2

Given a piece of text, I would like to replace lines start with a date string yyyy-mm-dd with a command. For this, my idea is first to split the text by \par with \regex_split, save the result in a sequence, then do the regex replacement in each sequence item, and finally put all these items in a token list. However, I'm getting TeX capacity exceeded, sorry [input stack size=5000] error.

Below is a MWE (it should color the date in red and title in blue):

\documentclass{article}

\usepackage{xcolor}

\ExplSyntaxOn

\NewDocumentCommand \JournalEntry { m m }
  {
    \textcolor { red } { #1 }
    \textcolor { blue } { #2 }
  }

\tl_new:N \g_myjournal_contents_tl
\NewDocumentEnvironment { myjournal } { +b }
  {
    \tl_gset:Nn \g_myjournal_contents_tl { #1 }
    \myjournal_parse_contents:N \g_myjournal_contents_tl
    \tl_use:N \g_myjournal_contents_tl
  }
  {}

\seq_new:N \l_myjournal_tmp_seq
\cs_generate_variant:Nn \regex_split:nnN { nVN }
\cs_new:Nn \myjournal_parse_contents:N
  {
    \regex_split:nVN { \c{par} } #1 \l_myjournal_tmp_seq
    \tl_set:Nn \g_myjournal_contents_tl {}
    \seq_map_inline:Nn \l_myjournal_tmp_seq
      {
        \tl_set:Nn \l_tmpa_tl { #1 }
        \regex_replace_all:nnN
          { (\ *)? (\d{4}-\d{1,2}-\d{1,2}) (\ *)? (.*) }
          { \c{JournalEntry} {\2} {\4} }
          \l_tmpa_tl
        \tl_gput_right:NV \g_myjournal_contents_tl \l_tmpa_tl
        \tl_gput_right:Nn \g_myjournal_contents_tl { \par }
      }
  }

\ExplSyntaxOff


\usepackage{blindtext}

\begin{document}

\begin{myjournal}

2022-02-01 Sunny - Some title

\blindtext

2022-02-01    Not sunny   titles

\blindtext

\end{myjournal}

-- Text in case of empty --

\end{document}
2
  • 2
    You are not using the mapping items at all: you are passing #1 (the name of a token list) to the regex every time. That won't help: you need ##1 due to the nesting.
    – Joseph Wright
    Feb 17, 2022 at 8:02
  • 1
    @JosephWright Thank you! I didn't realize that I was actually nesting things.
    – Jinwen
    Feb 17, 2022 at 8:04

1 Answer 1

0

There are two errors: first, you set the tl that should contain the final data and pass it to the next stage; second, you need ##1 in the loop of \seq_map_inline:Nn.

By the way, you can use \seq_set_split:Nnn rather than \regex_split:nnN

\documentclass{article}

\usepackage{xcolor}

\ExplSyntaxOn

\NewDocumentCommand \JournalEntry { m m }
  {
    \textcolor { red } { #1 }~
    \textcolor { blue } { #2 }
  }

\NewDocumentEnvironment { myjournal } { +b }
  {
    \myjournal_parse_contents:n { #1 }
    \tl_use:N \g_myjournal_contents_tl
  }
  {}

\tl_new:N \g_myjournal_contents_tl
\seq_new:N \l_myjournal_tmp_seq

\cs_new_protected:Nn \myjournal_parse_contents:n
  {
    \tl_gclear:N \g_myjournal_contents_tl
    \seq_set_split:Nnn \l_myjournal_tmp_seq { \par } { #1 }
    \seq_map_inline:Nn \l_myjournal_tmp_seq
      {
        \tl_set:Nn \l_tmpa_tl { ##1 }
        \regex_replace_all:nnN
          { \s* (\d{4}-\d{1,2}-\d{1,2}) \s* (.*) }
          { \c{JournalEntry} {\1} {\2} }
          \l_tmpa_tl
        \tl_gput_right:NV \g_myjournal_contents_tl \l_tmpa_tl
        \tl_gput_right:Nn \g_myjournal_contents_tl { \par }
      }
  }

\ExplSyntaxOff


\usepackage{blindtext}

\begin{document}

\begin{myjournal}

2022-02-01 Sunny - Some title

\blindtext

2022-02-01    Not sunny   titles

\blindtext

\end{myjournal}

-- Text in case of empty --

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .