Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
513ff1f9
Commit
513ff1f9
authored
Mar 13, 2008
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
The texcheck script is not needed with reST documentation.
parent
84492df4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
0 additions
and
233 deletions
+0
-233
Tools/scripts/texcheck.py
Tools/scripts/texcheck.py
+0
-233
No files found.
Tools/scripts/texcheck.py
deleted
100644 → 0
View file @
84492df4
""" TeXcheck.py -- rough syntax checking on Python style LaTeX documents.
Written by Raymond D. Hettinger <python at rcn.com>
Copyright (c) 2003 Python Software Foundation. All rights reserved.
Designed to catch common markup errors including:
* Unbalanced or mismatched parenthesis, brackets, and braces.
* Unbalanced or mismatched
\
\
begin and
\
\
end blocks.
* Misspelled or invalid LaTeX commands.
* Use of forward slashes instead of backslashes for commands.
* Table line size mismatches.
Sample command line usage:
python texcheck.py -k chapterheading -m lib/librandomtex *.tex
Options:
-m Munge parenthesis and brackets. [0,n) would normally mismatch.
-k keyword: Keyword is a valid LaTeX command. Do not include the backslash.
-d: Delimiter check only (useful for non-LaTeX files).
-h: Help
-s lineno: Start at lineno (useful for skipping complex sections).
-v: Verbose. Trace the matching of //begin and //end blocks.
"""
import
re
import
sys
import
getopt
from
itertools
import
izip
,
count
,
islice
import
glob
cmdstr
=
r"""
\
sec
tion \
module
\declaremodule \
modulesy
nopsis \
module
author
\
sec
tionauthor \versionadded \
code
\class \
me
thod \begin
\
op
tional \var \ref \
e
nd \
su
bsection \
li
neiii \
hli
ne \
l
abel
\
i
ndexii \textrm \
ldo
ts \
keywo
rd \
s
tindex \
i
ndex \
i
tem \note
\
wi
thsubitem \ttindex \footnote \
ci
tetitle \
s
amp \
opi
ndex
\noindent \
e
xception \
s
trong \
d
fn \
c
type \
o
bindex \
ch
aracter
\
i
ndexiii \function \bifuncindex \refmodule \refbimodindex
\
su
bsubsection \nodename \
mem
ber \
ch
apter \
emph
\ASCII \
UNIX
\regexp \
p
rogram \
p
roduction \token \
p
roductioncont \term
\
g
rammartoken \
li
neii \
seemodule
\file \
EOF
\documentclass
\
usep
ackage \title \
i
nput \
m
aketitle \
i
fhtml \fi \
u
rl \
Cpp
\tableofcontents \
k
bd \
p
rogramopt \
e
nvvar \refstmodindex
\
c
function \
co
nstant \
NULL
\moreargs \
c
funcline \
cd
ata
\textasciicircum \n \
ABC
\setindexsubitem \versionchanged
\
dep
recated \
see
text \newcommand \
POSIX
\pep \
w
arning \rfc
\verbatiminput \
me
thodline \textgreater \
see
title \
li
neiv
\funclineni \
uli
nk \
m
anpage \funcline \
d
ataline \
u
nspecified
\textbackslash \
mime
type \
m
ailheader \
seepep
\textunderscore
\
lo
ngprogramopt \
i
nfinity \
plusmi
nus \
sho
rtversion \version
\refmodindex \
see
rfc \
m
akeindex \
m
akemodindex \renewcommand
\
i
ndexname \appendix \
p
rotect \
i
ndexiv \
m
box \textasciitilde
\
pl
atform \
seeu
rl \
le
ftmargin \
l
abelwidth \
loc
almoduletable
\
L
aTeX \
copy
right \
mem
berline \backslash \
pi
\centerline
\
c
aption \vspace \textwidth \
me
nuselection \textless
\
m
akevar \
csimplem
acro \
me
nuselection \bfcode \
su
b \release
\
em
ail \
kwi
ndex \refexmodindex \filenq \
e
\menuselection
\
exi
ndex \
li
nev \newsgroup \verbatim \
se
tshortversion
\author \authoraddress \
p
aragraph \
su
bparagraph \
cmem
berline
\textbar \
C
\seelink
"""
def
matchclose
(
c_lineno
,
c_symbol
,
openers
,
pairmap
):
"Verify that closing delimiter matches most recent opening delimiter"
try
:
o_lineno
,
o_symbol
=
openers
.
pop
()
except
IndexError
:
print
(
"
\
n
Delimiter mismatch. On line %d, encountered closing '%s' without corresponding open"
%
(
c_lineno
,
c_symbol
))
return
if
o_symbol
in
pairmap
.
get
(
c_symbol
,
[
c_symbol
]):
return
print
(
"
\
n
Opener '%s' on line %d was not closed before encountering '%s' on line %d"
%
(
o_symbol
,
o_lineno
,
c_symbol
,
c_lineno
))
return
def
checkit
(
source
,
opts
,
morecmds
=
[]):
"""Check the LaTeX formatting in a sequence of lines.
Opts is a mapping of options to option values if any:
-m munge parenthesis and brackets
-d delimiters only checking
-v verbose trace of delimiter matching
-s lineno: linenumber to start scan (default is 1).
Morecmds is a sequence of LaTeX commands (without backslashes) that
are to be considered valid in the scan.
"""
texcmd
=
re
.
compile
(
r'\\[A-Za-z]+'
)
falsetexcmd
=
re
.
compile
(
r'\
/([A-Z
a-z]+)'
)
# Mismarked with forward slash
validcmds
=
set
(
cmdstr
.
split
())
for
cmd
in
morecmds
:
validcmds
.
add
(
'
\
\
'
+
cmd
)
if
'-m'
in
opts
:
pairmap
=
{
']'
:
'[('
,
')'
:
'(['
}
# Munged openers
else
:
pairmap
=
{
']'
:
'['
,
')'
:
'('
}
# Normal opener for a given closer
openpunct
=
set
(
'(['
)
# Set of valid openers
delimiters
=
re
.
compile
(
r'\\(begin|end){([_a-zA-Z]+)}|([()\
[
\]])'
)
braces
=
re
.
compile
(
r'({)|(})'
)
doubledwords
=
re
.
compile
(
r'(\b[A-za-z]+\b) \b\1\b'
)
spacingmarkup
=
re
.
compile
(
r'\\(ABC|ASCII|C|Cpp|EOF|infinity|NULL|plusminus|POSIX|UNIX)\
s
')
openers = [] # Stack of pending open delimiters
bracestack = [] # Stack of pending open braces
tablestart = re.compile(r'
\\
begin
{(
?
:
long
)
?
table
([
iv
]
+
)}
')
tableline = re.compile(r'
\\
line
([
iv
]
+
){
')
tableend = re.compile(r'
\\
end
{(
?
:
long
)
?
table
([
iv
]
+
)}
')
tablelevel = ''
tablestartline = 0
startline = int(opts.get('
-
s
', '
1
'))
lineno = 0
for lineno, line in izip(count(startline), islice(source, startline-1, None)):
line = line.rstrip()
# Check balancing of open/close parenthesis, brackets, and begin/end blocks
for begend, name, punct in delimiters.findall(line):
if '
-
v
' in opts:
print(lineno, '
|
', begend, name, punct, end='
')
if begend == '
begin
' and '
-
d
' not in opts:
openers.append((lineno, name))
elif punct in openpunct:
openers.append((lineno, punct))
elif begend == '
end
' and '
-
d
' not in opts:
matchclose(lineno, name, openers, pairmap)
elif punct in pairmap:
matchclose(lineno, punct, openers, pairmap)
if '
-
v
' in opts:
print('
-->
', openers)
# Balance opening and closing braces
for open, close in braces.findall(line):
if open == '
{
':
bracestack.append(lineno)
if close == '
}
':
try:
bracestack.pop()
except IndexError:
print(r'
Warning
,
unmatched
}
on
line
%
s
.
' % (lineno,))
# Optionally, skip LaTeX specific checks
if '
-
d
' in opts:
continue
# Warn whenever forward slashes encountered with a LaTeX command
for cmd in falsetexcmd.findall(line):
if '
822
' in line or '
.
html
' in line:
continue # Ignore false positives for urls and for /rfc822
if '
\\
' + cmd in validcmds:
print('
Warning
,
forward
slash
used
on
line
%
d
with
cmd
:
/%
s
' % (lineno, cmd))
# Check for markup requiring {} for correct spacing
for cmd in spacingmarkup.findall(line):
print(r'
Warning
,
\
%
s
should
be
written
as
\
%
s
{}
on
line
%
d
' % (cmd, cmd, lineno))
# Validate commands
nc = line.find(r'
\
newcommand
')
if nc != -1:
start = line.find('
{
', nc)
end = line.find('
}
', start)
validcmds.add(line[start+1:end])
for cmd in texcmd.findall(line):
if cmd not in validcmds:
print(r'
Warning
,
unknown
tex
cmd
on
line
%
d
:
\
%
s
' % (lineno, cmd))
# Check table levels (make sure lineii only inside tableii)
m = tablestart.search(line)
if m:
tablelevel = m.group(1)
tablestartline = lineno
m = tableline.search(line)
if m and m.group(1) != tablelevel:
print(r'
Warning
,
\
line
%
s
on
line
%
d
does
not
match
\
table
%
s
on
line
%
d
' % (m.group(1), lineno, tablelevel, tablestartline))
if tableend.search(line):
tablelevel = ''
# Style guide warnings
if '
e
.
g
.
' in line or '
i
.
e
.
' in line:
print(r'
Style
warning
,
avoid
use
of
i
.
e
or
e
.
g
.
on
line
%
d
' % (lineno,))
for dw in doubledwords.findall(line):
print(r'
Doubled
word
warning
.
"%s"
on
line
%
d
' % (dw, lineno))
lastline = lineno
for lineno, symbol in openers:
print("Unmatched open delimiter '
%
s
' on line %d" % (symbol, lineno))
for lineno in bracestack:
print("Unmatched { on line %d" % (lineno,))
print('
Done
checking
%
d
lines
.
' % (lastline,))
return 0
def main(args=None):
if args is None:
args = sys.argv[1:]
optitems, arglist = getopt.getopt(args, "k:mdhs:v")
opts = dict(optitems)
if '
-
h
' in opts or args==[]:
print(__doc__)
return 0
if len(arglist) < 1:
print('
Please
specify
a
file
to
be
checked
')
return 1
for i, filespec in enumerate(arglist):
if '
*
' in filespec or '
?
' in filespec:
arglist[i:i+1] = glob.glob(filespec)
morecmds = [v for k,v in optitems if k=='
-
k
']
err = []
for filename in arglist:
print('
=
' * 30)
print("Checking", filename)
try:
f = open(filename)
except IOError:
print('
Cannot
open
file
%
s
.
' % arglist[0])
return 2
try:
err.append(checkit(f, opts, morecmds))
finally:
f.close()
return max(err)
if __name__ == '
__main__
':
sys.exit(main())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment