\ThisStyle \SavedStyle 고통스러울 정도로 느립니다... 대안이 있나요?

\ThisStyle \SavedStyle 고통스러울 정도로 느립니다... 대안이 있나요?

첫 번째 버전을 사용하여 사용자 정의된 모자 글리프를 작업하는 동안이 솔루션, pdflatex문서를 컴파일하는 데 오랜 시간이 걸리기 시작했습니다. 연결된 답변은 더 느린 솔루션이지만 처음에는 딸꾹질 속도가 느려서 중요하지 않다고 지적합니다. 그러다가 두 개의 모자를 쌓은 후에는 견딜 수 있을 정도로 느려졌습니다. 그리고 조사하러 가서 모자 세 개를 쌓은 후에는 무한히 느려졌습니다.

간략한 이유는 다음과 같습니다.

  \documentclass[12pt, a4paper]{article}
  \usepackage{scalerel}

  \begin{document}
  \ensuremath{
  \ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
          \SavedStyle . }}}}}}}
  }}
  \end{document}

pdflatex또는 를 사용하면 15초가 걸립니다 latex. 한 수준의 중첩을 해제하면 2초로 줄어들고, 예제보다 한 수준을 더 추가하면 269초가 됩니다.

확실히 뭔가 기하급수적인 일이 벌어지고 있습니다. 조사하다scalerel.sty\SavedStyle, 및 의 코드 는 \ThisStyle다음과 같습니다.

\def\SavedStyle{\csname @mstyle\m@switch\endcsname}


\newcommand\ThisStyle[1]{%
  \ifmmode%
    \def\@mmode{T}\mathchoice%
      {\edef\m@switch{D}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{S}\LMex=\scriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptstyleScaleFactor pt\relax#1}%
      {\edef\m@switch{s}\LMex=\scriptscriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptscriptstyleScaleFactor pt\relax#1}%
  \else%
    \def\@mmode{F}%
    \edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1%
  \fi%
}

내 생각에는 논증이 \ThisStyle모든 수준에서 4배로 확장되는 것 같습니다. 즉, \mathchoice게으르지 않습니다.

#1이러한 \mathchoice주장을 벗어나면서도 동일한 동작을 유지하는 방법이 있습니까 ? 해당 항목 \m@switch\LMex정의는 다음 " }" 이후에도 계속 유지되나요?

\ThisStyle그렇지 않은 경우 해당 작업 을 수행하는 다른 접근 방식이 있습니까 \SavedStyle? 중첩 깊이와 관련하여 선형 시간에 작동하고 재진입이 있는 경우에도 여전히 올바르게 작동하는 것은 생각할 수 없습니다.

답변1

짧은 대답: 아니요. 모든 상황에서 또는 하나의 LaTeX 패스에서 이를 올바르게 수행할 수 있는 방법은 없습니다.


많은 학습과 실험 끝에 이 문제를 해결할 수 있는 유일한 방법은 다음과 같습니다.마누엘의 답변과 의견은 여기에 있습니다.. 그런 것은 없습니다\whatIsTheMathStyleHere (LuaTeX를 사용하지 않는 이상). 그만큼\mathchoice명령은 TeX 기본 요소입니다..네 가지 옵션 중 선택이 이루어집니다.늦은. "늦다"가 무엇을 의미하는지 이해하려면 TeX이몇 가지 소화 단계: 눈, 입,식도, 위, 각각은 의미상 의미 있는 토큰의 하위 집합을 통해 작업하여 논리적 문서를 최종 시각적 문서에 더 가까운 형식으로 변환합니다.때로는 이전 단계로 돌아가는 경우도 있습니다.(그러나 우리가 기대하는 사실이라기엔 너무 좋은 조판 지능이 어느 정도의 복잡성을 정당화하지 않습니까?)\mathchoice 그리고인수 내부는 \mathchoice자체가 적용되기 전에 매크로 확장됩니다. 사실, 내가 알 수 있는 한 확장뿐만 아니라 다른 TeX 명령(예: )이 \ifx이전에 처리되므로 \mathchoice각 처리 단계 내에 여러 계층화된 하위 단계가 있을 수 있습니까?

Manuel의 대안인 는 \mathcase수학 스타일에 따라 크기가 달라지는 나노 크기의 공간이 삽입되는 영리한 트릭을 사용합니다. 그리고 공간의 크기를 확인하고 스타일을 결정합니다. 모든 곳에서 최종 수학 스타일이 문서가 완전히 해결된 구조가 된 후에만 결정되어야 한다면 어떻게 작동할 수 있습니까? 패키지 를 사용하여 그렇게 합니다 zref-savepos. 에 대한 문서를 읽으면 zref다음과 같은 참고 사항이 있습니다.

페이지 위치는 즉시 알 수 없습니다. 먼저 페이지는 TEX의 비동기 출력 루틴으로 구성되어야 합니다. 따라서 위치가 알려진 시간이 페이지 출고 시간입니다. 따라서 정보가 첫 번째 실행에서 기록되고 두 번째 실행에서 사용할 수 있도록 제공되는 참조 시스템이 유용합니다.

즉, 올바른 수학 스타일은 다음에서 결정됩니다.배송\if, 이 시점에서는 다른 의사 결정 구조 에서 사용할 수 없지만 AUX 파일에 저장되고(아래 예의 AUX 파일을 검사하여 볼 수 있듯이) 두 번째 패스에서 사용할 수 있게 됩니다. .

불행하게도 이로 인해 계단식 수학 스타일이 중첩된 일련의 s로 전파되면서 다음과 같은 종류의 문제가 발생합니다 \mathcase. 중첩이 N 수준 깊이이면 문서가 N번 이상 컴파일될 때까지 문서의 안정성이 보장되지 않습니다. 예를 들어:

(이것은마누엘의 답변, 방금 문서 본문을 변경했습니다.)

\documentclass{scrartcl}

\usepackage{mathtools}


\usepackage{zref-savepos}
\newcount\mmstynum
\newcount\tmpnum
\protected\def\getmsty
 {\global\advance\mmstynum1 %
  \expandafter\getstyA\expandafter{\number\mmstynum}}
\protected\def\getstyA#1%
 {\zsaveposx{mmsty-#1-a}%
  \mathchoice{\kern4sp}{\kern3sp}{\kern2sp}{\kern1sp}%
  \zsaveposx{mmsty-#1-b}
  \tmpnum=\numexpr
            \zposx{mmsty-#1-b} - \zposx{mmsty-#1-a}
          \relax
   \ifcase\tmpnum\or\kern-1sp \or\kern-2sp \or\kern-3sp \or\kern-4sp \fi}
\protected\def\mstycase
 {\ifcase\tmpnum\expandafter\gobblefour\or\expandafter\usefourth\or
   \expandafter\usethird\or\expandafter\usesecond\or
   \expandafter\usefirst\else\expandafter\gobblefour\fi}
\protected\def\mathcase{\getmsty\mstycase}

\long\def\gobblefour#1#2#3#4{}
\long\def\usefourth#1#2#3#4{#4}
\long\def\usethird#1#2#3#4{#3}
\long\def\usesecond#1#2#3#4{#2}
\long\def\usefirst#1#2#3#4{#1}


\def\tmpa{If this prints it means it doesn't work}
\newcommand*\foo
 {\mathcase % compare with \mathchoice
   {\def\tmpa{displaystyle}}
   {\def\tmpa{textstyle}}
   {\def\tmpa{scriptstyle}}
   {\def\tmpa{scriptscriptstyle}}
  \text\tmpa}

\let\savedstyle\displaystyle

\def\thisstyle#1{\begingroup\mathcase{\let\savedstyle\displaystyle}{\let\savedstyle\textstyle}{\let\savedstyle\scriptstyle}{\let\savedstyle\scriptscriptstyle}#1\endgroup}

\begin{document}

\[
\sum \scriptstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \)}%
    }\)}%
    }\)}%
}
\]

\end{document}

PDF를 컴파일하는 동안 TeXworks 뷰어에서 보면 다음과 같습니다.

첫 번째 패스 후:

1위

두 번째 패스 후:

2위

세 번째 패스 후:

3번째

네 번째 패스 후:

4번째

따라서 솔루션은 패스 수를 절충하여 각 패스의 속도를 향상시킵니다. (문서가 아직 안정적이지 않을 때 경고도 표시하면 좋겠지만.) 완벽한 해결책은 아니지만 TeX(및 TeX)의 특성을 고려할 때 이것이 가능한 최선의 대안이라고 확신합니다. 가까운 미래에 이 측면이 바뀔 가능성은 거의 없습니다.)

패키지 도 있습니다 mathstyle(여기에서 토론을 참조하세요\mathchoice), 모든 수학 모드 구분 기호를 탭하면 문제가 해결됩니다 (그러나\(분명히 그렇지 않다!) 그리고 TeX를 사용하여 현재 수학 스타일이 어떻게 될지 추적하기 위해 몇 가지 논리를 주입합니다. 그러나 에서 지적한 바와 같이Aditya의 의견은 여기에 있습니다., TeX의 동작을 예측하지 못하는 경우가 있습니다. 예를 들어 TeX 프리미티브 \over를 사용하는 경우입니다 \atop. (댓글은 5년차인데 그 사이 좀 나아졌지 않을까요?)

따라서 가장 좋은 대답은 가능한 경우 \mathchoice중첩 수준 수를 줄이는 것입니다(a는 , , 등에 \mathchoice포함되어 있음 ).\ThisStyle\text\mathpalette\TextStyle선행 질문에서 중복되는 몇 가지를 제거했습니다.) 또는 상식적인 추론을 사용하여 수학 스타일을 추론할 수 있다면로컬에서 재정 \mathchoice의하여 단락시키세요..

어찌보면 정말 놀라운 결과입니다. LaTeX로 뭔가를 하고 싶었던 것은 이번이 처음이었는데, 그게 비실용적이라는 것이 밝혀졌습니다. 또한 해킹을 시도하는 동안 \mathchoice매크로 언어의 모든 공포를 만났습니다. 여기서는 무엇이 어떤 순서로 확장될지 전혀 알 수 없습니다. ("고전적인" 방식을 살펴보세요 \expandafter\expandafter\expandafter\expandafter\expandafter....이 솔루션, 그리고 뭔가 잘못되었다는 것을 알 수 있습니다.) 마지막으로, 70년대 소프트웨어의 경우 \mathchoice의도된 목적이 단지 단일 사용자 정의 기호를 조판하는 것일지라도 의 의미 체계는 다소 비효율적으로 보입니다.

관련 정보