문자열이 유효한 LaTex 규칙인지 확인하는 방법은 무엇입니까?

문자열이 유효한 LaTex 규칙인지 확인하는 방법은 무엇입니까?

나는 MathQuill 라이브러리를 사용하고 있습니다.수식 입력그리고 여러 가지 작업을 제한하려고 합니다. 내가 할 수 있는 방법이 없을까?문자열과 LaTex 규칙을 구별합니까?

예를 들어:

def check('\sum') => True  #LaTex rule
def check('\myCustomVar') => False  #NOT a LaTex rule

어떤 도움이라도 주시면 감사하겠습니다!

답변1

적어도 Linux에는(Windows에 대해서는 모릅니다) latexdef명령줄에서 LaTeX 정의를 찾는 Martin Scharrer의 스크립트가 있습니다.

latexdef section 

인쇄할 것이다

\section
\long macro:->\@startsection {section}{1}{\z@ }{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus .2ex}{\normalfont \Large \bfseries }

반면

latexdef sausage 

인쇄할 것이다

\sausage
undefined

latexdef다음과 같이 Python에서 호출할 수 있습니다 .

import subprocess, re

def latexdef(command_list, *args):
    '''
    call latexdef on a list of commands to be looked up
    *args can be used to pass options to latexdef
    '''
    p = subprocess.Popen(['latexdef'] + list(args) + command_list, \
                        stdout=subprocess.PIPE, \
                        stderr=subprocess.STDOUT)
    return p.communicate()[0].strip()

def are_commands(command_list, *args):
    '''
    look up multiple commands and return results in a dict
    '''
    result = latexdef(command_list, *args)
    frags = [ f.splitlines() for f in re.split(r'\n{2,}', result, re.MULTILINE) ]
    return { command[1:] : defn != 'undefined' for command, defn in frags }

def is_command(command, *args):
    '''
    look up a single command
    '''
    return are_commands([command],*args).values()[0]

if __name__ == '__main__':
    commands = "chapter section sausage".split()

    for command in commands:
        print command, is_command(command)

    print "\nwith book class loaded"

    for command in commands:
        print command, is_command(command, '-c', 'book')

    print "\nall at once, with class book"
    print are_commands(commands, '-c', 'book')

이 인쇄

chapter False
section True
sausage False

with book class loaded
chapter True
section True
sausage False

all at once, with class book
{'sausage:': False, 'section:': True, 'chapter:': True}

각 단일 호출은 latexdef다소 느리지만 단일 호출에서 여러 명령을 검색하면 시간을 절약할 수 있습니다. 이것이 are_commandsdict의 각 명령에 대한 조회 결과를 반환하는 의 목적입니다 .

또한 이는 latexdefPerl 스크립트이므로 이것이 얼마나 중요한지에 따라 전체 내용을 Python으로 번역하여 중개자를 제거하는 것이 합리적일 수 있습니다. 하지만 그것은 긴 스크립트이고, Perl은 눈에 좀 힘들죠...

답변2

이것은 실제 답변이 아니라 더 긴 설명입니다. Michael Palmer가 제공한 답변은 해당 매크로가 핵심 패키지/클래스에 의해 정의된 경우 대부분의 경우 작동합니다.

그러나 고려해야 할 몇 가지 경우가 있습니다. LaTeX 규칙을 공식화하는 방법은 아마도 명령 순서를 의미할 것입니다. 일반적인 LaTeX 명령 시퀀스(다음 예에서는 "cmd"라고 함)는 다음 ABNF로 생성될 수 있습니다.

cmd = "\" 1*ALPHA

그러나 그것만으로는 충분하지 않습니다. 별도로 포함/제외하려는 내부 매크로가 있다는 점에 유의해야 합니다. 이는 다음과 같은 것을 확인해야 함을 의미합니다.

cmd = "\" 1*(ALPHA | "@")

내부 매크로용. 그러한 명령 시퀀스가 ​​사용되는 시점에서 유효한 경우 상황에 따라 다릅니다. 이 규칙은 명령 자체의 유효성을 확인하지만 \makeatletter ... \makeatother유효성을 확인하려면 대부분 환경 내에서 사용해야 합니다 (검사에 컨텍스트가 포함되어야 하는 경우).

그리고 검사에 컨텍스트가 포함되어야 한다는 사실은 \frac수학 모드에서 사용될 때 "유효한 LaTeX 규칙"인 것과 같은 명령으로 간단하게 표시될 수 있습니다. 또는 의 명령 \meter내에서만 유효한 것과 유사한 것입니다.siunitx

또 다른 경우는 expl3입니다. l3 명령은 \ExplSyntaxOn및 로 묶인 경우 LaTeX에서도 유효합니다 \ExplSyntaxOff. 그들은 다음과 같이 구축될 것입니다:

cmd = "\" 1*(ALPHA | "_") ":" 0*ALPHA

콜론 뒤의 문자가 제한되어 있기 때문에 실제로는 사실이 아니지만 충분합니다.

\csname ...\endcsname그리고 여기에는 사용자에게 더 많은 옵션이 있으므로 사용자 정의 매크로의 유효성을 확인하려는 경우 상황은 더욱 악화됩니다 .

업데이트:결국 가장 흥미로운 부분은 호출이 유효한지 확인하는 것입니다. 이는 함수의 서명도 확인한 다음 명령 호출을 확인해야 함을 의미합니다. 이는 \frac수학 모드 내에서 호출되고 두 개의 필수 인수가 있는 경우에만 유효하다는 것을 의미합니다 . 좋아해요 $\frac{1}{2}$. 여기에서 실제 파서는 매우 복잡하기 때문에 샘플 문서를 컴파일하고 싶을 수도 있습니다.

이러한 모든 방법에는 한 가지 주의 사항이 있습니다. LaTeX 명령 시퀀스뿐만 아니라 TeX 명령 시퀀스도 얻을 수 있다는 것입니다. 특별히 LaTeX 항목을 얻으려고 하지만 TeX 항목을 제외하려는 경우 문제가 발생합니다.

업데이트 2:테스트 구현에 관심이 있으셨다면 일치하는 데 사용할 수 있는 몇 가지 정규식은 다음과 같습니다. 전체 일치에서만 실제로 유효한 시퀀스가 ​​앞에 표시됩니다. 상황에 맞는 부분의 경우 미리보기 및 뒤돌아보기를 사용하여 작업할 수 있습니다.

  • 표준 LaTeX:\\[A-Za-z]*
  • 내부 LaTeX:\\[A-Za-z@]*
  • expl 구문:\\[A-za-z@_]*:[DNncVvoOxfTFpw]*
  • \csname명령: 다음과 같은 것\\.*$

관련 정보