Skip to content

Instantly share code, notes, and snippets.

@wtsnjp
Created October 18, 2017 08:06
Show Gist options
  • Save wtsnjp/c5eac5ce080716818f00238443024362 to your computer and use it in GitHub Desktop.
Save wtsnjp/c5eac5ce080716818f00238443024362 to your computer and use it in GitHub Desktop.
#
# usage: python chk_syntax.py {file path} ...
#
import sys
import re
from fabric.colors import red, yellow
def get_syntax(fns):
sl, env_syntax = [], False
begin = re.compile(r'%\s*\\begin\{syntax\}')
end = re.compile(r'%\s*\\end\{syntax\}')
ignore = re.compile(r'(%|~|\n|\\\\)')
spaces = re.compile(r'\s+')
for fn in fns:
for l in open(fn):
if not env_syntax:
if begin.match(l):
env_syntax = True
s = ''
else:
if end.match(l):
env_syntax = False
sl.append(spaces.sub(' ', s).strip())
else:
s += ignore.sub('', l) + ' '
return sl
def split_to_function(sl):
fl, tl = [], []
cs = re.compile(r'(\\cs\{|"\\)(?P<cs>.+)(\}|")')
for l in sl:
s = ''
for t in l.split(' '):
m = cs.match(t)
if m:
if len(tl) > 0:
fl.append(tl)
tl = ['\\' + m.group('cs')]
else:
if s == '':
s = t
else:
s += '~' + t
if s.count('{') == s.count('}') and s.count('<') == s.count('>'):
tl.append(s)
s = ''
return fl
def chk_syntax(fl):
arg_spec = re.compile(r':(.*)')
arg = re.compile(r'(\\Arg\{.*\}|\\\{.*\\\})|\|\{.*\}\|')
meta = re.compile(r'(\\meta\{.*\}|<.*>|\\cs.*)')
for f in fl:
m = arg_spec.search(f[0])
ok = True
# no arg-spec
if not m or len(m.group(1)) < 1:
continue
a = m.group(1)
# arg-spec = w
if 'w' in a:
continue
# mismatch number
if len(a) != len(f[1:]):
# ignore
if 'if_' in f[0]:
continue
if '...' in ''.join(f[1:]) or '\\ldots' in ''.join(f[1:]):
continue
# print
print(yellow(' '.join(f)))
continue
# inappropriate arg
for i in range(len(a)):
c = a[i]
if c == 'N' or c == 'V' or c == 'p':
if not meta.match(f[i + 1]):
ok = False
else:
if not arg.match(f[i + 1]):
ok = False
if not ok:
print(red(' '.join(f)))
if __name__ == '__main__':
fns = sys.argv[1:]
sl = get_syntax(fns)
# print syntax lines
#for l in sl:
# print(l)
fl = split_to_function(sl)
# print function list
#for f in fl:
# print(' '.join(f))
chk_syntax(fl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment