0

I would like to replace each new line of an argument with + but I can't achieve this. Maybe a bad format for the argument...

What I am missing?

\documentclass{article}

\ExplSyntaxOn
    \str_new:N \l__crypto_code_str
    
    \NewDocumentCommand\cryptocode{m}{
        \str_set:Nn \l__crypto_code_str {#1}
        \regex_replace_all:nnN {\n} { + } \l__crypto_code_str
        \regex_replace_all:nnN {\s} { , } \l__crypto_code_str
        
        Result:
        \par
        \str_use:N \l__crypto_code_str
    }
\ExplSyntaxOff


\begin{document}

\cryptocode{X H C M O N O Y J F O C D L D
T Z L O B O T O Q L O T H Y F
O M W M C L F V S R V L R G I
V Y C Y P O D Y R D X M I E Z
E K O D V J D E C A B R A E O
J B N X L V P R I L V A C A A
A A E V V G J C I R A Q U Y D
W L J S P B B G L L Y B A N I
G L O F C P Z V S K O G E L F
A E C L E A T O V P U D J J K
T N H M R T B R R T I C Z A A
O A G V A F W A R R O F R P B
R I J S N B F O L E O Z G E J
T Q R W A U T E O L N I D R W
G B J L E Y C G E C O P M X J}

\end{document}
3
  • 1
    The issue is that the newline characters get converted to spaces before \str_set:Nn sees them (by TeX's tokenisation rules). You'll have to use a multi-line verbatim argument (+v in xparse).
    – Skillmon
    May 2 '21 at 12:10
  • 1
    I'd use something like \\ to mark the breaks, because text editors might get into the way and ruin your careful line breaking.
    – egreg
    May 2 '21 at 12:16
  • @egreg You are right but I'm playing with LaTeX" to learn a little more about it.
    – projetmbc
    May 2 '21 at 12:20
4

The following does what you want by using the +v argument type of \NewDocumentCommand (multi-line verbatim). This also uses \str_replace_all:Nnn instead of \regex_replace_all:nnN, since the former is much faster, and in this case you don't need a regular expression at all.

\documentclass{article}

\ExplSyntaxOn
    \str_new:N \l__crypto_code_str
    
    \cs_new_protected:Npx \__cryptocode_process_string:
      {
        \str_replace_all:Nnn \exp_not:N \l__crypto_code_str { ~ } { , }
        \str_replace_all:Nnn \exp_not:N \l__crypto_code_str
          { \char_generate:nn { 13 } { 12 } } { + }
      }
    \NewDocumentCommand\cryptocode{+v}{
        \str_set:Nn \l__crypto_code_str {#1}
        \__cryptocode_process_string:
        \par
        Result:
        \par
        \str_use:N \l__crypto_code_str
    }
\ExplSyntaxOff


\begin{document}

\cryptocode{X H C M O N O Y J F O C D L D
T Z L O B O T O Q L O T H Y F
O M W M C L F V S R V L R G I
V Y C Y P O D Y R D X M I E Z
E K O D V J D E C A B R A E O
J B N X L V P R I L V A C A A
A A E V V G J C I R A Q U Y D
W L J S P B B G L L Y B A N I
G L O F C P Z V S K O G E L F
A E C L E A T O V P U D J J K
T N H M R T B R R T I C Z A A
O A G V A F W A R R O F R P B
R I J S N B F O L E O Z G E J
T Q R W A U T E O L N I D R W
G B J L E Y C G E C O P M X J}

\end{document}
5
  • This works well and it is easy to follow but even with +v "my regex" does not work. Why?
    – projetmbc
    May 2 '21 at 12:21
  • 2
    @projetmbc Because TeX translates newlines into character 13 (carriage return) on input, and doesn't use character 10 (newline) in the tokenisation, so you'd have to use \r in your regular expression instead.
    – Skillmon
    May 2 '21 at 12:24
  • If it is done whatever the encoding of the file is, that's good news. Thanks for all.
    – projetmbc
    May 2 '21 at 13:16
  • 1
    @projetmbc one can change which character TeX inserts at the end of each line (through \endlinechar), but with the usual settings this is set to 13 (and +v should normalise those, iirc).
    – Skillmon
    May 2 '21 at 13:23
  • Ok. I was thinking of normal use cases.
    – projetmbc
    May 2 '21 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.