2

I am trying to define an environment that calls an external command to draw pdfs based on the contents of the environment, and include the output.

Now I also want to be able to pass on the width and scale options to the \includegraphics macro inside the environment end function, but I cannot get it to pass the arguments in such a way that \includegraphics it still understands.

The small example below ends with the following error:

Package keyval Error: scale=1 undefined.

Similarly, if I try to pass width=0.5\textwidth to the environment, it breaks with:

! Missing \endcsname inserted.
<to be read again> 
                   \textwidth 
l.32 \end{haslpicture}

Small example (in this case cupsfilter is the external command)

\documentclass{minimal}
\usepackage{environ}
\usepackage{graphicx}

\newwrite\myOutput
\makeatletter

\def\hasl@writeToFile#1{
  \immediate\openout\myOutput=\hasl@filename.txt%
  \immediate\write\myOutput{#1}%
  \immediate\closeout\myOutput%
}

\newenvironment{haslpicture}[2][scale=1]{%
  \def\hasl@filename{#2}%
  \def\hasl@arguments{#1}%
  \newlinechar`\^^M%
  \obeylines%
  \message{Optional argument: #1}
  \Collect@Body\hasl@writeToFile% %macro from the environ package
}{%
  \immediate\write18{cupsfilter \hasl@filename.txt > \hasl@filename.pdf}%
  \includegraphics[\hasl@arguments]{\hasl@filename.pdf}
}
\makeatother

\begin{document}
\begin{haslpicture}[scale=1]{xoutput}
one
two
three
\end{haslpicture}
\end{document}
3

The syntax characters = and , must not be hidden in key value lists. Fix by expanding \hasl@arguments:

\expandafter\includegraphics\expandafter[\hasl@arguments]{\hasl@filename.pdf}
1

With xparse you can use the arguments also in the “end part”.

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}
\usepackage{graphicx}

\ExplSyntaxOn

\iow_new:N \g_jelmervdl_haslpicture_stream

\cs_new_protected:Nn \jelmervdl_haslpicture_write:n
 {
  \iow_open:NV \g_jelmervdl_haslpicture_stream \l__jelmervdl_haslpicture_name_tl
  \iow_now:Nf \g_jelmervdl_haslpicture_stream { \tl_trim_spaces:n { #1 } }
  \iow_close:N \g_jelmervdl_haslpicture_stream
 }
\cs_generate_variant:Nn \iow_open:Nn { NV }
\cs_generate_variant:Nn \iow_now:Nn { Nf }

\NewDocumentEnvironment{haslpicture}{O{}m}
 {
  \tl_set:Nn \l__jelmervdl_haslpicture_name_tl { #2.txt }
  \endlinechar=`\^^J \scan_stop:
  \use:c { Collect@Body } \jelmervdl_haslpicture_write:n
 }
 {
  \message{Optional~argument:~#1}
  \sys_shell_now:n { cupsfilter ~ #2.txt ~ > ~ #2.pdf }
  \includegraphics[#1]{#2.pdf}
 }
\ExplSyntaxOff

\begin{document}

\begin{haslpicture}[scale=1]{xoutput}
one
two
three
\end{haslpicture}

\end{document}

Instead of playing with \obeylines, it's better to set \endlinechar to ^^J, which is the default newlinechar in LaTeX.

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.