I have the following lines in my awk program :

str = gensub(/`([^`]*)`/, "\\\\texttt{\\1}", "g", str);
str = gensub(/\*([^\*]*)\*/, "\\\\textbf{\\1}", "g", str);

These lines perform non-greedy substitution for `...` and *...* by resp. \texttt{...} and \textbf{...}.

I am looking for a way to avoid *...* substitution when it's "semi-nested" or nested in `...`, e.g. `...*...`...* or `...*...*...`.

Input and expected output :

  1. `.*` text `^.*$` ---> \texttt{.*} text \texttt{^.*$}
  2. `*abc*` ---> \texttt{*abc*}

You need to identify the two patterns A and B in a single pass, then change them later. The following merges the 2 patterns into one (A|B) and marks it with the prefix string XXX. It then looks for XXX and the pattern A for the real substitution. Similarly, for B. This does not handle your semi-nested `a*b`c* case.

awk '{ str = $0
 str = gensub(/(`[^`]*`|\*[^\*]*\*)/, "XXX\\1", "g", str);
 str = gensub(/XXX`([^`]*)`/, "\\\\texttt{\\1}", "g", str);
 str = gensub(/XXX\*([^\*]*)\*/, "\\\\textbf{\\1}", "g", str);
 print str
}' <<\!
 `abc` *abc*
 `.*` text `^.*$`


 \texttt{abc} \textbf{abc}
 \texttt{.*} text \texttt{^.*$}
  • Thanks for your answer. I just realize that the semi-nested case doesn't really happen. So, you solve my problems. – Firmin Martin May 13 '18 at 11:03

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.