이상한 'ProvidesPackage' 대 'newenvironment' 매크로 확장

이상한 'ProvidesPackage' 대 'newenvironment' 매크로 확장

현재 svg(ditaa-0.11.0-standalone.jar에서 구현됨)에 대한 지원을 추가하기 위해 기존 패키지(ditaa0_9.jar 기반 'ditaa')를 개선하고 있지만 이상한 매크로 정의/확장에 직면하고 있습니다.

기본적으로 나는 명령줄 인수에 대한 지원을 그런 식으로 추가하여 'ditaa' 바이너리의 동작을 제어하고 싶습니다(요약).

\ProvidesPackage{ditaa}
\RequirePackage[patch]{kvoptions}

% Support for https://github.com/stathissideris/ditaa
\DeclareBoolOption{A}               % Turns anti-aliasing off (-A or --no-antialias)
\DeclareBoolOption{noantialias}

\ProcessKeyvalOptions*

\newenvironment{ditaa}[3][\columnwidth]{
        % OPTION A <-----
        \def\ditaaoptA{\ifthenelse{\boolean{ditaa@A}}{-A }{\ifthenelse{\boolean{ditaa@noantialias}}{--no-antialias }{}}}

        % OPTION B <-----
        \ifthenelse{\boolean{ditaa@A}}{\def\ditaaoptA{-A }}{\ifthenelse{\boolean{ditaa@noantialias}}{\def\ditaaoptA{--no-antialias }}{\def\ditaaoptA{}}}

        \VerbatimOut{\ditaafile}}
    {\endVerbatimOut
        \immediate\write18{ditaa.jar \ditaaoptA "\ditaafile" "\ditaadir/\ditaastem.png"}    % <----- TITI
        \begin{figure}[H]
            \vdots      % because I'm lazy
        \end{figure}
        \ditaaoptA      % <----- TOTO
    }

나중에...

\usepackage[A]{ditaa}

좋아, 말했듯이 OPTION A가 사용될 때 TOTO는 올바른 인수(-A)를 표시하지만 실행되는 내용이 다음과 같기 때문에 TITI는 실패합니다.

runsystem(ditaa.jar \let \begingroup \let \begingroup \NROrg@begingroup \begingroup \def \protect \let \reserved@d = *\def \catcode `\ =5 \par )...executed.

그러나 OPTION B를 사용하면 두 경우 모두 작동합니다.아직동일한 매크로를 (빈 변형으로) 3번 정의해야 하는데 이는 유지 관리가 번거롭고 오류가 발생하기 쉽습니다.

어떤 일이 있어도 OPTION A(더 우아한)가 작동하도록 하는 방법이 있습니까?

감사해요.

답변1

Ulrike가 주석에서 말했듯 \ifthenelse이 확장 가능하지 않으므로 내부에서는 작동하지 않습니다 \write. 즉, 먼저 평가하고 \ditaaoptA그에 따라 설정한 다음 에 전달 해야 합니다 \write.

expl3대신 bool 변수를 사용하고 l3keys2e키를 구문 분석하는 재구현은 다음과 같습니다 .

no-antialias열쇠를 열쇠로 만들었습니다 .bool_set:N. no-antialias및 의 효과 no-antialias=true는 동일하며 를 사용할 수도 있습니다 no-antialias=false. 나는 로 리디렉션되는 키를 A만들었 으므로(그러나 나는 그것을 사용하지 않고 단지 제공할 것입니다 ), 두 개를 확인하는 대신 하나의 부울만 갖게 됩니다(초기에 정리하면 코드가 훨씬 더 간단해집니다). 또한 다른 변수에 대한 키도 정의했습니다..metano-antialiasno-antialias

그런 다음 전화하려면 ditaa.jar다음이 필요합니다.

\sys_shell_now:x
  {
    ditaa.jar~ % executable
    \bool_if:NT \l__ditaa_no_antialias_bool { --no-antialias ~ } % --no-antialias if the bool is true
    "\l__ditaa_outfile_tl" ~ % whatever these other two are :)
    "\l__ditaa_path_tl/\l__ditaa_path_tl.png"
  }

또한 환경에 대한 선택적 인수를 로드 시간 옵션으로 수정하는 대신 환경별로 전달할 수 있는 키 목록으로 만들었습니다.

\begin{filecontents}[overwrite]{ditaa.sty}

\RequirePackage{l3keys2e}
\RequirePackage{fancyvrb}

\ProvidesExplPackage{ditaa}{2020-11-04}
  {v1.0}{Interface to ditaa}

\keys_define:nn { ditaa }
  {
    , no-antialias .bool_set:N = \l__ditaa_no_antialias_bool
    , no-antialias .default:n = true
    , no-antialias .initial:n = false
    , A .meta:n = { no-antialias }
    %
    , output-file .tl_set:N = \l__ditaa_outfile_tl
    , output-file .initial:n = { \c_sys_jobname_str-ditaa }
    %
    , path .tl_set:N = \l__ditaa_path_tl
    , path .initial:n = { \c_sys_jobname_str-path } % <- insert reasonable defaults
    , stem .tl_set:N = \l__ditaa_stem_tl
    , stem .initial:n = { \c_sys_jobname_str-stem } % <- insert reasonable defaults
    %
  }

\ProcessKeysOptions { ditaa }

\NewDocumentEnvironment { ditaa } { o m m }
  {
    \group_begin:
      \IfValueT{#1} { \keys_set:nn { ditaa } {#1} }
      \VerbatimOut { \l__ditaa_outfile_tl }
  }
  {
      \endVerbatimOut
      % \exp_args:Nx \tl_show:n
      \sys_shell_now:x
        {
          ditaa.jar~
          \bool_if:NT \l__ditaa_no_antialias_bool { --no-antialias ~ }
          "\l__ditaa_outfile_tl" ~
          "\l__ditaa_path_tl/\l__ditaa_path_tl.png"
        }
    \group_end:
  }

\end{filecontents}

\documentclass{article}

\usepackage[A]{ditaa}

\begin{document}

\begin{ditaa}{a}{b}
\end{ditaa}

\begin{ditaa}[no-antialias=false]{a}{b}
\end{ditaa}

\end{document}

답변2

기능/테스트가 아니기 때문에 주석 처리된 전체 버전은 다음과 같습니다.

% 'ditaa' package
%
% (c) Hiroshi Ukai
%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ditaa}
[2020/11/04 v0.11.0 LaTeX package for embedding ditaa style ascii art]

\RequirePackage{fancyvrb}
\RequirePackage{graphicx}
\RequirePackage{svg}
\RequirePackage{etoolbox}
\RequirePackage{xifthen}
\RequirePackage[debugshow,patch]{kvoptions}
%\RequirePackage[patch]{kvoptions}
%\RequirePackage{kvoptions-patch}

%\newcommand*{\ditaasetup}[1]{\setkeys{ditaa}{#1}}
\newcommand*{\ditaasetup}{\kvsetkeys{ditaa}}
\SetupKeyvalOptions{setkeys=\kvsetkeys}
%\SetupKeyvalOptions{family=ditaa, prefix=ditaa@, setkeys=\kvsetkeys}
%\SetupKeyvalOptions{}

% These options are defined at \usepackage[options]{ditaa} location, *not* at \begin[options]{ditaa}
% These options can be changed at "runtime" using the \ditaasetup{options} macro, though
\DeclareStringOption{imagepath}             % Path of the image
\DeclareStringOption[\columnwidth]{width}[\columnwidth]

% Support for https://github.com/stathissideris/ditaa
\DeclareBoolOption{A}                       % Turns anti-aliasing off
\DeclareBoolOption{noantialias}
\DeclareStringOption{b}[FFFFFF]             % The background colour of the image
\DeclareStringOption{background}[FFFFFF]
\DeclareBoolOption{d}                       % Renders the debug grid
\DeclareBoolOption{debug}
\DeclareBoolOption[true]{E}                 % Prevents the separation of common edges
\DeclareBoolOption{noseparation}
\DeclareStringOption{e}[utf-8]              % The encoding of the input file
\DeclareStringOption{encoding}[utf-8]
\DeclareBoolOption{h}                       % The input is an HTML file
\DeclareBoolOption{html}
\DeclareBoolOption{help}                    % Prints usage help
\DeclareBoolOption{o}                       % Image file is overwriten
\DeclareBoolOption{overwrite}
\DeclareBoolOption{r}                       % All corners to be rendered as round corners
\DeclareBoolOption{roundcorners}
\DeclareBoolOption{S}                       % Turns off the drop-shadow effect
\DeclareBoolOption{noshadows}
\DeclareStringOption{s}[1.0]                % Size of the rendered image
\DeclareStringOption{scale}[1.0]
\DeclareBoolOption{svg}                     % SVG image as destination file
\DeclareStringOption{svgfonturl}[]          % SVG font URL
\DeclareBoolOption{T}                       % Diagram rendered on a transparent background
\DeclareBoolOption{transparent}
\DeclareStringOption{t}[4]                  % Tabs interpreted as x spaces
\DeclareStringOption{tabs}[4]
\DeclareBoolOption{v}                       % Makes ditaa more verbose
\DeclareBoolOption{verbose}
\DeclareBoolOption{W}                       % Sides of parallelograms as fixed slope
\DeclareBoolOption{fixedslop}

\ProcessKeyvalOptions*
%\ProcessLocalKeyvalOptions*
%\ProcessKeyvalOptions{ditaa}

%@formatter:off (This line indicates IntelliJ that formatter should be off before this)
\newenvironment{ditaa}[3][\ditaa@width]
    {
        \def\ditaacaption{#2}
        \def\ditaastem{#3}
        \def\ditaadir{\ditaa@imagepath/ditaa}
        \def\ditaafile{\ditaadir/\ditaastem.ditaa}
        \def\ditaafigwidth{#1}
        % usepackage->program options ('-\/-' is de-ligaturing '--')

%       \def\ditaaoptA{\ifthenelse{\boolean{ditaa@A}}{-A}{\ifthenelse{\boolean{ditaa@noantialias}}{-\/-no-antialias}{}}}
%       \def\ditaaoptb{\ifdefstring{\ditaa@b}{}{\ifdefstring{\ditaa@background}{}{}{-\/-background \ditaa@background}}{-b \ditaa@b}}
%       \def\ditaaoptd{\ifthenelse{\boolean{ditaa@d}}{-d}{\ifthenelse{\boolean{ditaa@debug}}{-\/-debug}{}}}
%       \def\ditaaoptE{\ifthenelse{\boolean{ditaa@E}}{-E}{\ifthenelse{\boolean{ditaa@noseparation}}{-\/-no-separation}{}}}
%       \def\ditaaopte{\ifdefstring{\ditaa@e}{}{\ifdefstring{\ditaa@encoding}{}{}{-\/-encoding \ditaa@encoding}}{-b \ditaa@e}}
%       \def\ditaaopth{\ifthenelse{\boolean{ditaa@h}}{-h}{\ifthenelse{\boolean{ditaa@html}}{-\/-html}{}}}
%       \def\ditaaopthelp{\ifthenelse{\boolean{ditaa@help}}{-\/-help}{}}
%       \def\ditaaopto{\ifthenelse{\boolean{ditaa@o}}{-o}{\ifthenelse{\boolean{ditaa@overwrite}}{-\/-overwrite}{}}}
%       \def\ditaaoptr{\ifthenelse{\boolean{ditaa@r}}{-r}{\ifthenelse{\boolean{ditaa@roundcorners}}{-\/-round-corners}{}}}
%       \def\ditaaoptS{\ifthenelse{\boolean{ditaa@S}}{-S}{\ifthenelse{\boolean{ditaa@noshadows}}{-\/-no-shadows}{}}}
%       \def\ditaaopts{\ifdefstring{\ditaa@s}{}{\ifdefstring{\ditaa@scale}{}{}{-\/-scale \ditaa@scale}}{-s \ditaa@s}}
%       \def\ditaaoptsvg{\ifthenelse{\boolean{ditaa@svg}}{-\/-svg}{}}
%       \def\ditaaoptsvgext{\ifthenelse{\boolean{ditaa@svg}}{svg}{png}}
%       \def\ditaaoptsvgfonturl{\ifdefstring{\ditaa@svg-font-url}{}{}{-\/-svg-font-url \ditaa@svg-font-url}}
%       \def\ditaaoptT{\ifthenelse{\boolean{ditaa@T}}{-T}{\ifthenelse{\boolean{ditaa@transparent}}{-\/-transparent}{}}}
%       \def\ditaaoptt{\ifdefstring{\ditaa@t}{}{\ifdefstring{\ditaa@tabs}{}{}{-\/-tabs \ditaa@tabs}}{-t \ditaa@t}}
%       \def\ditaaoptv{\ifthenelse{\boolean{ditaa@v}}{-v}{\ifthenelse{\boolean{ditaa@verbose}}{-\/-verbose}{}}}
%       \def\ditaaoptW{\ifthenelse{\boolean{ditaa@W}}{-W}{\ifthenelse{\boolean{ditaa@fixedslop}}{-\/-fixed-slop}{}}}

        % \\def\\(ditaaopt[-\w]+)\{\\ifthenelse\{\\boolean\{(ditaa\@[-\w]+)\}\}\{([-\w]+)\}\{\\ifthenelse\{\\boolean\{(ditaa\@[-\w]+)\}\}\{-\\/-([-\w]+)\}\{\}\}\}
        % \\ifthenelse\{\\boolean\{\2\}\}\{\\def\\\1\{\3 \}\}\{\\ifthenelse\{\\boolean\{\4\}\}\{\\def\\\1\{-\\/-\5 \}\}\{\\\1\{\}\}\}

        % \\def\\(ditaaopt[-\w]+)\{\\ifdefstring\{\\(ditaa\@[-\w]+)\}\{\}\{\\ifdefstring\{\\(ditaa\@[-\w]+)\}\{\}\{\}\{-\\/-([-\w]+) \\\3\}\}\{-([-\w]+) \\\2\}\}
        % \\ifdefstring\{\\\2\}\{\}\{\\ifdefstring\{\\\3\}\{\}\{\\\1\{\}\}\{\\def\\\1\{-\\/-\4 \\\3 \}\}\}\{\\def\\\1\{-\5 \\\2 \}\}
        
        % \\def\\(ditaaopt[-\w]+)\{\\ifthenelse\{\\boolean\{(ditaa\@[-\w]+)\}\}\{-\\/-([-\w]+)\}\{\}\}
        % \\ifthenelse\{\\boolean\{\2\}\}\{\\def\\\1\{-\\/-\3 \}\}\{\\\1\{\}\}
        
        \ifthenelse{\boolean{ditaa@A}}{\def\ditaaoptA{-A }}{\ifthenelse{\boolean{ditaa@noantialias}}{\def\ditaaoptA{--no-antialias }}{\def\ditaaoptA{}}}
        \ifdefstring{\ditaa@b}{}{\ifdefstring{\ditaa@background}{}{\def\ditaaoptb{}}{\def\ditaaoptb{--background \ditaa@background }}}{\def\ditaaoptb{-b \ditaa@b }}
        \ifthenelse{\boolean{ditaa@d}}{\def\ditaaoptd{-d }}{\ifthenelse{\boolean{ditaa@debug}}{\def\ditaaoptd{--debug }}{\def\ditaaoptd{}}}
        \ifthenelse{\boolean{ditaa@E}}{\def\ditaaoptE{-E }}{\ifthenelse{\boolean{ditaa@noseparation}}{\def\ditaaoptE{--no-separation }}{\def\ditaaoptE{}}}
        \ifdefstring{\ditaa@e}{}{\ifdefstring{\ditaa@encoding}{}{\def\ditaaopte{}}{\def\ditaaopte{--encoding \ditaa@encoding }}}{\def\ditaaopte{-e \ditaa@e }}
        \ifthenelse{\boolean{ditaa@h}}{\def\ditaaopth{-h }}{\ifthenelse{\boolean{ditaa@html}}{\def\ditaaopth{--html }}{\def\ditaaopth{}}}
        \ifthenelse{\boolean{ditaa@help}}{\def\ditaaopthelp{--help }}{\def\ditaaopthelp{}}
        \ifthenelse{\boolean{ditaa@o}}{\def\ditaaopto{-o }}{\ifthenelse{\boolean{ditaa@overwrite}}{\def\ditaaopto{--overwrite }}{\def\ditaaopto{}}}
        \ifthenelse{\boolean{ditaa@r}}{\def\ditaaoptr{-r }}{\ifthenelse{\boolean{ditaa@roundcorners}}{\def\ditaaoptr{--round-corners }}{\def\ditaaoptr{}}}
        \ifthenelse{\boolean{ditaa@S}}{\def\ditaaoptS{-S }}{\ifthenelse{\boolean{ditaa@noshadows}}{\def\ditaaoptS{--no-shadows }}{\def\ditaaoptS{}}}
        \ifdefstring{\ditaa@s}{}{\ifdefstring{\ditaa@scale}{}{\def\ditaaopts{}}{\def\ditaaopts{--scale \ditaa@scale }}}{\def\ditaaopts{-s \ditaa@s }}
        \ifthenelse{\boolean{ditaa@svg}}{\def\ditaaoptsvg{--svg }}{\def\ditaaoptsvg{}}
        \ifthenelse{\boolean{ditaa@svg}}{\def\ditaaoptsvgext{svg}}{\def\ditaaoptsvgext{png}}
        \ifdefstring{\ditaa@svgfonturl}{}{\def\ditaaoptsvgfonturl{}}{\def\ditaaoptsvgfonturl{--svg-font-url "\ditaa@svgfonturl" }}
        \ifthenelse{\boolean{ditaa@T}}{\def\ditaaoptT{-T }}{\ifthenelse{\boolean{ditaa@transparent}}{\def\ditaaoptT{--transparent }}{\def\ditaaoptT{}}}
        \ifdefstring{\ditaa@t}{}{\ifdefstring{\ditaa@tabs}{}{\def\ditaaoptt{}}{\def\ditaaoptt{--tabs \ditaa@tabs }}}{\def\ditaaoptt{-t \ditaa@t }}
        \ifthenelse{\boolean{ditaa@v}}{\def\ditaaoptv{-v }}{\ifthenelse{\boolean{ditaa@verbose}}{\def\ditaaoptv{--verbose }}{\def\ditaaoptv{}}}
        \ifthenelse{\boolean{ditaa@W}}{\def\ditaaoptW{-W }}{\ifthenelse{\boolean{ditaa@fixedslop}}{\def\ditaaoptW{--fixed-slop }}{\def\ditaaoptW{}}}

        \VerbatimOut{\ditaafile}}
    {\endVerbatimOut
        \immediate\write18{ditaa.jar \ditaaoptA \ditaaoptb \ditaaoptd \ditaaoptE \ditaaopte \ditaaopth \ditaaopthelp \ditaaopto \ditaaoptr \ditaaoptS \ditaaopts \ditaaoptsvg \ditaaoptsvgfonturl \ditaaoptT \ditaaoptt \ditaaoptv \ditaaoptW "\ditaafile" "\ditaadir/\ditaastem.\ditaaoptsvgext"}
        \begin{figure}[H]
            \begin{center}
                \vspace{-1em}
                \ifditaa@svg
                    \includesvg[inkscapelatex=false, width=\ditaafigwidth]{\ditaadir/\ditaastem.svg}
                \else
                    \includegraphics[width=\ditaafigwidth]{\ditaadir/\ditaastem.png}
                \fi
                \vspace{-2em}
                \caption{\ditaacaption}
                \label{fig:\ditaastem}
                \vspace{-1.5em}
            \end{center}
        \end{figure}
    }
%@formatter:on (This line indicates IntelliJ that formatter should be off before this)
%--------------------------------------------------

\endinput
%%
%% End of file `ditaa.sty'.

예, 또한 이중 하이픈이 '먹혔다'는 것을 알아차렸기 때문에 '--'를 '-\/-'로 '이스케이프'해야 한다는 다른 주제를 읽었습니다. 하지만 OPTION A에서는 작동하지만 그렇지 않습니다. 옵션 B의 경우. 이동해 보세요...

관련 정보