나는 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_commands
dict의 각 명령에 대한 조회 결과를 반환하는 의 목적입니다 .
또한 이는 latexdef
Perl 스크립트이므로 이것이 얼마나 중요한지에 따라 전체 내용을 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
명령: 다음과 같은 것\\.*$