3

I'm trying to write a funny style writing targeting a young audience. At some point, I would like some words to have "wave" effect on each character according to their position.

I've already found this article that use pgf/TikZ to simulate WordArt, but I would like to be able to do it without pgf.

So the idea should be to be able to write something like this

I can write a \bubbletext{bubble-like} wavy text.

So far, based on this example, I was able to at least get a randomized effect. My problem comes from the fact that I would like something more consistant.

\ExplSyntaxOn

\NewDocumentCommand{\bubblechar}{ O{0.25} m } { \group_begin: \tl_set:Nn \l_tmpa_tl { #2 } \tl_replace_all:Nnn \l_tmpa_tl { ~ } { \c_space_tl } \tl_map_inline:Nn \l_tmpa_tl { \int_case:nnF { \int_mod:nn {\int_rand:nn{0}{400}} {4} } { {1} {\raisebox { #1 ex} { ##1 } } {3} {\raisebox {-#1 ex} { ##1 } } } {##1} } \group_end: }

\ExplSyntaxOff

To achieve that, I have to replace the \int_rand:nn{0}{400} with the actual position I currently am in the list, but I don't find how to reach that value. So basically, the effect I want will have a similar effect that if I had writen this line

I can write a b\raisebox{-0.25ex}ub\raisebox{0.25ex}bl\raisebox{-.25ex}e-\raisebox{0.25ex}li\raisebox{-0.25ex}ke wavy text.

With the 400, I'm sometime lucky, but it's not always the case (far from it). (In the following example, it was pretty close / almost perfect, but most of the time, the effect is barely visible.)

Expected result vs reality based on luck

Thanks in advance.

Miraino Hikari
  • 335
  • 1
  • 9

1 Answers1

3

Instead of randomizing the shift the following uses an integer to track the offset that should be applied to each element in the token list. I also added a step between base line and top/bottom aligned with 0.707 times the displacement (roughly cos(pi/4), might change it to your liking).

\documentclass{article}

\ExplSyntaxOn \keys_define:nn { wavychars } { displace .tl_set:N = \l__wavychars_displace_tl ,displace .initial:n = 0.25ex ,halfstep .fp_set:N = \l__wavychars_halfstep_fp ,halfstep .initial:n = 0.707 ,no-halfstep .bool_set:N = \l__wavychars_no_halfstep_bool ,unknown .code:n = \tl_set:Nx \l__wavychars_displace_tl { \l_keys_key_str } } \tl_new:N \l__wavychars_input_tl \int_new:N \l__wavychars_state_int \cs_new:Npn __wavychars_halfstep: { \fp_eval:n { \l__wavychars_displace_tl * \l__wavychars_halfstep_fp } pt } \cs_new_protected:Npn __wavychars_with_halfstep:n #1 { \tl_if_eq:nnTF { \c_space_tl } {#1} { \c_space_tl } { \int_incr:N \l__wavychars_state_int \int_case:nn \l__wavychars_state_int { 1 {#1} 2 { \raisebox { __wavychars_halfstep: } {#1} } 3 { \raisebox { \l__wavychars_displace_tl } {#1} } 4 { \raisebox { __wavychars_halfstep: } {#1} } 5 {#1} 6 { \raisebox { -__wavychars_halfstep: } {#1} } 7 { \raisebox { -\l__wavychars_displace_tl } {#1} } 8 { \raisebox { -__wavychars_halfstep: } {#1} \int_zero:N \l__wavychars_state_int } } } } \cs_new_protected:Npn __wavychars_no_halfstep:n #1 { \tl_if_eq:nnTF { \c_space_tl } {#1} { \c_space_tl } { \int_incr:N \l__wavychars_state_int \int_case:nn \l__wavychars_state_int { 1 {#1} 2 { \raisebox { \l__wavychars_displace_tl } {#1} } 3 {#1} 4 { \raisebox { -\l__wavychars_displace_tl } {#1} \int_zero:N \l__wavychars_state_int } } } } \cs_new_protected:Npn \wavychars:nn #1#2 { \group_begin: \keys_set:nn { wavychars } {#1} % though \text_expand:n should be preferred for user input, the following % loop wouldn't work anyway with input containing argument grabbing macros \tl_set:Nx \l__wavychars_input_tl { #2 } \tl_replace_all:Nnn \l__wavychars_input_tl { ~ } { \c_space_tl } \int_zero:N \l__wavychars_state_int \bool_if:NTF \l__wavychars_no_halfstep_bool { \tl_map_function:NN \l__wavychars_input_tl __wavychars_no_halfstep:n } { \tl_map_function:NN \l__wavychars_input_tl __wavychars_with_halfstep:n } \group_end: } \NewDocumentCommand \wavychars { O{} m } { \wavychars:nn {#1} {#2} } \ExplSyntaxOff

\begin{document} \wavychars{This is in wavy style} and this is normal style.

\wavychars[halfstep=0.5]{This is in wavy style} and this is normal style.

% short syntax for displacement \wavychars[1ex]{This is in wavy style} and this is normal style.

% short syntax doesn't work if displacement contains a macro \newcommand*\mydisplacement{1ex} \wavychars[displace=\mydisplacement]{This is in wavy style} and this is normal style.

\wavychars[no-halfstep]{This is in wavy style} and this is normal style. \end{document}

enter image description here

Skillmon
  • 60,462
  • I don't know why I didn't think to create my own position counter, but that's perfect. I also kept the idea for the keys, it may come handy. And your answer is even more complete than what I really needed, but it may help other in the future. Thanks a lot. – Miraino Hikari Aug 23 '22 at 12:44