현재 카운터 값을 스택 데이터 구조에 전달

현재 카운터 값을 스택 데이터 구조에 전달

\newcounter{}나는 텍스트 전체에 흩어져 있는 포인트 모음을 자동으로 쌍으로 연결할 수 있도록 스택 데이터 구조를 정의와 결합하려고 합니다 .

각 포인트는 \openbracket또는 a 로 표시되며 쌍 을 \closebracket형성하기 위해 반대로 정의된 포인트와 자동으로 쌍을 이룹니다 . 닫힌 쌍은 다른 닫힌 괄호 쌍 안에 중첩될 수 있으며, 열린/닫힌 점의 각 쌍은 각각 tikz 노드로 표시됩니다 ( 여기서 X는 외부 카운터에 의해 정의된 정수임).\openbracket\closebracket\node(openX) {};\node(closeX) {};

예를 들어:

\openbraket First tier
    \openbraket Second tier A
        \openbraket Third tier
        \closebracket 
    \closebracket 
    \openbracket Second tier B
    \closebracket 
\closebracket 

위의 \openbracket \closebracket점을 4개의 닫힌 브래킷 쌍으로 자동으로 쌍을 이루어야 합니다. 두 개의 두 번째 계층 브래킷을 포함하는 첫 번째 계층 브래킷 1개, 첫 번째(A)에는 단일 세 번째 계층 브래킷이 포함됩니다. 내 MWE는 또한 위 예의 tikz 노드가 다음과 같이 정의되도록 스택 구조에서 데이터를 팝해야 합니다.

(open0) First tier (open1) Second tier A (open2) Third tier 
(close2) (close1) (open3)  Second tier B (close3) (close0)

의 도움을 이용하여길이/치수를 푸시/팝하거나 저장하시겠습니까?,카운터의 현재 값을 명령에 저장, 그리고tikz 노드 이름에 스택 데이터 전달, 나는 작동하는 스택 데이터 구조를 정의하고 스택 데이터를 내 \tikzmark매크로에 올바르게 전달하는 방법을 알아냈습니다.

그러나 아래 MWE는 의 현재 값을 명시적으로 푸시하지 않고 bracketpairingcounter필요한 bracketpairingstack정수 대신 축어적 명령 문자열을 푸시합니다. 따라서 각 \node(closeX) {};tikz 표시가 데이터 스택에서 팝될 때 각 노드 번호는 bracketpairingcounter스택에 순차적으로 푸시되는 다른 정수 대신 의 마지막 값에서 평가됩니다.

LaTeX 코드에서 아래 값을 즉시 평가하도록 강제하여 번호 매기기 문제를 해결할 수 있기를 바라고 있지만 \openbracketname평생 동안 이 경우에는 작업을 수행 \expandafter할 수 없습니다.\edef{}

MWE

\documentclass[openany]{article}
\usepackage{tikz}

%Define stack data structure commands (\push, \pop, \splitstack)
\newtoks\braketpairingstack
\braketpairingstack={\empty}

    \def\push#1#2{%
        \def\tmp{{#1}}% 
        \expandafter\expandafter\expandafter%
        #2\expandafter\expandafter\expandafter{\expandafter\tmp\the#2}%
    \ignorespaces}

    \def\pop#1#2{%
        \expandafter\splitstack\the#1\stop{#1}{#2}%
    }

    \def\splitstack#1#2\stop#3#4{% 
        \def\tmp{#1}
        \ifx\tmp\empty 
        \else
            \def#4{#1}\global#3={#2}%
        \fi
    } 

%Define \tikzmark command
\def\tikzmark#1{%
    \tikz[remember picture, overlay]\node[red](#1) {#1};%
}

%Define bracket pair counting commands (\openbracket, \closebracket)
\newcounter{bracketpairingcounter}

    \newcommand{\openbraket}{%
        \expandafter\edef\csname openbracketname\endcsname{\thebracketpairingcounter}%
        \push{\openbracketname}{\braketpairingstack}%
        \tikzmark{open\openbracketname}%
        \stepcounter{bracketpairingcounter}%
    }

    \newcommand{\closebraket}{%
        \pop{\braketpairingstack}{\closebracketname}%
        \tikzmark{close\closebracketname}%
    }

%Begin MWE document
\begin{document}
    \openbraket Open first bracket.\\ %Correctly marked as open0
    \openbraket Open second bracket.\\ %Correctly marked as open1

    Close second bracket. \closebraket\\ %Correctly marked as close1 
    Close first bracket. \closebraket\\ %Incorrectly marked as close1
\end{document}

답변1

하고 싶지만 코드의 \edef\temp{{#1}}정의와 다른 부분도 단순화할 수 있습니다 .\push

\documentclass[openany]{article}
\usepackage{tikz}

%Define stack data structure commands (\push, \pop, \splitstack)
\newtoks\braketpairingstack
\braketpairingstack={\empty}

\def\push#1#2{%
  \edef\tmp{{#1}\the#2}%
  #2=\expandafter{\tmp}%
}

\def\pop#1#2{%
  \expandafter\splitstack\the#1\stop{#1}{#2}%
}

\def\splitstack#1#2\stop#3#4{% 
  \def\tmp{#1}%
  \ifx\tmp\empty
  \else
    \def#4{#1}\global#3={#2}%
  \fi
} 

%Define \tikzmark command
\def\tikzmark#1{%
  \tikz[remember picture, overlay]\node[red](#1) {#1};%
}

%Define bracket pair counting commands (\openbracket, \closebracket)
\newcounter{bracketpairingcounter}

\newcommand{\openbraket}{%
   \edef\openbracketname{\thebracketpairingcounter}%
   \push{\openbracketname}{\braketpairingstack}%
   \tikzmark{open\openbracketname}%
   \stepcounter{bracketpairingcounter}%
}

\newcommand{\closebraket}{%
  \pop{\braketpairingstack}{\closebracketname}%
  \tikzmark{close\closebracketname}%
}

%Begin MWE document
\begin{document}

\openbraket Open first bracket. %Correctly marked as open0

\openbraket Open second bracket. %Correctly marked as open1

Close second bracket. \closebraket %Correctly marked as close1 

Close first bracket. \closebraket %Correctly marked as close0
\end{document}

여기에 이미지 설명을 입력하세요

우리는 토큰 레지스터 #2의 확장되지 않은 콘텐츠를 \edef\tmp{{#1}\the#2}완전히 확장 하고 추가합니다. 왜냐하면 레지스터의 콘텐츠를 전달한 후에는 확장이 진행되지 않기 때문입니다. 그런 다음 .#1\the\tokenregister\the#2\tmp

\ignorespaces호출 \push하면 \tikzmark; 실제로는 시기적절하지 않은 확장이 발생할 수 있습니다(이 경우는 아님).

관련 정보