1

I have to write a properly (as in JSON or Javascript) escaped string to a file.

My minimal example is

\documentclass{standalone}

\begingroup
\catcode`<=1 \catcode`>=2
\catcode`{=12 \catcode`}=12
\gdef\wbgroup<{>
\gdef\wegroup<}>
\endgroup

\def\mytitle{This is a "title" for me}

\begin{document}
\newwrite\jsonwrite
\immediate\openout\jsonwrite=file.json
\immediate\write\jsonwrite{\wbgroup}
\immediate\write\jsonwrite{  title: "\mytitle"}
\immediate\write\jsonwrite{\wegroup}
\end{document}

What I get is a file.json with

{
 title: "This is a "title" for me"
}

whereas what I need is the internal quotes escaped as in

{
 title: "This is a \"title\" for me"
}

I have the suggestion Escaping quotes when writing to a file but if I do this

\documentclass{standalone}

\begingroup
\catcode`<=1 \catcode`>=2
\catcode`{=12 \catcode`}=12
\gdef\wbgroup<{>
\gdef\wegroup<}>
\endgroup

\usepackage[T1]{fontenc}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand{\myescapestring}[1]{
  \tl_set:Nn \l_tmpa_tl {#1}
  \regex_replace_all:nnN {"} {\u{c_backslash_str}"} \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\def\mytitle{This is a "title" for me}

\begin{document}
\newwrite\jsonwrite
\immediate\openout\jsonwrite=file.json
\immediate\write\jsonwrite{\wbgroup}
\immediate\write\jsonwrite{  title: "\myescapestring\mytitle"}
\immediate\write\jsonwrite{\wegroup}
\end{document}

I get an even much worse result, namely

{
 title: "\tl_set:Nn {This is a "title" for me}\regex_replace_all:nnN {"}{\unhbox \voidb@x \bgroup \let \unhbox \voidb@x \setbox \@tempboxa \hbox {c_backslash_str\global \mathchardef \accent@spacefactor \spacefactor }\let \begingroup \endgroup \relax \let \ignorespaces \relax \accent 8 c_backslash_str\egroup \spacefactor \accent@spacefactor "}"
}

I am stuck with PDFLaTeX and cannot use LUATex, since I am using many features of PDFLaTeX in other parts of my original document.

So essentially I am looking for a stringEscape function for Javascript in PDFTeX.

1

You need to do the escaping prior to writing, because it is not an expandable operation.

Without knowing more details on what you want to write out, a possible solution

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\jsonwrite}{mmmm}
 {% #1 = file name,
  % #2 = initial part
  % #3 = middle part
  % #4 = final part
  \nkiad_jsonwrite:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\iow_new:N \g__nkiad_jsonwrite_iow
\tl_new:N \l__nkiad_jsonwrite_item_tl

\cs_generate_variant:Nn \iow_now:Nn { NV }

\cs_new_protected:Nn \nkiad_jsonwrite:nnnn
 {
  \iow_open:Nn \g__nkiad_jsonwrite_iow { #1 }
  \iow_now:Nx \g__nkiad_jsonwrite_iow { \c_left_brace_str }
  \tl_set:Nx \l__nkiad_jsonwrite_item_tl { #3 }
  \regex_replace_all:nnN { \" } { \cO\\ \" } \l__nkiad_jsonwrite_item_tl
  \iow_now:Nx \g__nkiad_jsonwrite_iow
   {
    #2 % initial part
    \l__nkiad_jsonwrite_item_tl % middle part
    #4 % final part
   }
  \iow_now:Nx \g__nkiad_jsonwrite_iow { \c_right_brace_str }
  \iow_close:N \g__nkiad_jsonwrite_iow
 }
\ExplSyntaxOff

\def\mytitle{This is a "title" for me}

\begin{document}

\jsonwrite{\jobname.json}{  title: "}{\mytitle}{"}

\end{document}

We need to distinguish between quotes to be escaped (those contained in \mytitle) and those that shouldn't be.

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.