Adjustments to allow elements with subelements as parameters. This is
used to deal with the table headings and entries. An additional flag in the element table is used to indicate elements which have no "general" content, but which do have subelement content. These must be flagged distinctly from empty elements. Currently used for \lineii, \lineiii, and \lineiv.
This commit is contained in:
parent
79cbadc194
commit
d7acf02290
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
"""Generate ESIS events based on a LaTeX source document and configuration
|
"""Generate ESIS events based on a LaTeX source document and configuration
|
||||||
data.
|
data.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__version__ = '$Revision$'
|
__version__ = '$Revision$'
|
||||||
|
|
||||||
@ -16,6 +14,9 @@ import sys
|
|||||||
from esistools import encode
|
from esistools import encode
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = 0
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -40,19 +41,30 @@ _start_optional_rx = re.compile("[ \n]*[[]")
|
|||||||
ESCAPED_CHARS = "$%#^ {}&~"
|
ESCAPED_CHARS = "$%#^ {}&~"
|
||||||
|
|
||||||
|
|
||||||
def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
def pushing(name, point, depth):
|
||||||
|
if DEBUG:
|
||||||
|
sys.stderr.write("%s<%s> at %s\n" % (" "*depth, name, point))
|
||||||
|
|
||||||
|
def popping(name, point, depth):
|
||||||
|
if DEBUG:
|
||||||
|
sys.stderr.write("%s</%s> at %s\n" % (" "*depth, name, point))
|
||||||
|
|
||||||
|
|
||||||
|
def subconvert(line, ofp, table, discards, autoclosing, endchar=None, depth=0):
|
||||||
|
if DEBUG and endchar:
|
||||||
|
sys.stderr.write("subconvert(%s, ..., endchar=%s)\n"
|
||||||
|
% (`line[:20]`, `endchar`))
|
||||||
stack = []
|
stack = []
|
||||||
while line:
|
while line:
|
||||||
if line[0] == endchar and not stack:
|
if line[0] == endchar and not stack:
|
||||||
|
if DEBUG:
|
||||||
|
sys.stderr.write("subconvert() --> %s\n" % `line[1:21]`)
|
||||||
return line[1:]
|
return line[1:]
|
||||||
m = _comment_rx.match(line)
|
m = _comment_rx.match(line)
|
||||||
if m:
|
if m:
|
||||||
text = m.group(1)
|
text = m.group(1)
|
||||||
if text:
|
if text:
|
||||||
ofp.write("(COMMENT\n")
|
ofp.write("(COMMENT\n- %s \n)COMMENT\n-\\n\n" % encode(text))
|
||||||
ofp.write("- %s \n" % encode(text))
|
|
||||||
ofp.write(")COMMENT\n")
|
|
||||||
ofp.write("-\\n\n")
|
|
||||||
line = line[m.end():]
|
line = line[m.end():]
|
||||||
continue
|
continue
|
||||||
m = _begin_env_rx.match(line)
|
m = _begin_env_rx.match(line)
|
||||||
@ -75,8 +87,9 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
elif envname == stack[-1]:
|
elif envname == stack[-1]:
|
||||||
ofp.write(")%s\n" % envname)
|
ofp.write(")%s\n" % envname)
|
||||||
del stack[-1]
|
del stack[-1]
|
||||||
|
popping(envname, "a", len(stack) + depth)
|
||||||
else:
|
else:
|
||||||
print stack
|
sys.stderr.write("stack: %s\n" % `stack`)
|
||||||
raise LaTeXFormatError(
|
raise LaTeXFormatError(
|
||||||
"environment close for %s doesn't match" % envname)
|
"environment close for %s doesn't match" % envname)
|
||||||
line = line[m.end():]
|
line = line[m.end():]
|
||||||
@ -102,20 +115,25 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
while stack[-1] != macroname:
|
while stack[-1] != macroname:
|
||||||
if stack[-1] and stack[-1] not in discards:
|
if stack[-1] and stack[-1] not in discards:
|
||||||
ofp.write(")%s\n-\\n\n" % stack[-1])
|
ofp.write(")%s\n-\\n\n" % stack[-1])
|
||||||
|
popping(stack[-1], "b", len(stack) + depth - 1)
|
||||||
del stack[-1]
|
del stack[-1]
|
||||||
if macroname not in discards:
|
if macroname not in discards:
|
||||||
ofp.write("-\\n\n)%s\n-\\n\n" % macroname)
|
ofp.write("-\\n\n)%s\n-\\n\n" % macroname)
|
||||||
|
popping(macroname, "c", len(stack) + depth - 1)
|
||||||
del stack[-1]
|
del stack[-1]
|
||||||
real_ofp = ofp
|
real_ofp = ofp
|
||||||
if macroname in discards:
|
if macroname in discards:
|
||||||
ofp = StringIO.StringIO()
|
ofp = StringIO.StringIO()
|
||||||
#
|
#
|
||||||
conversion = table.get(macroname, ([], 0, 0, 0))
|
conversion = table.get(macroname, ([], 0, 0, 0, 0))
|
||||||
params, optional, empty, environ = conversion
|
params, optional, empty, environ, nocontent = conversion
|
||||||
if empty:
|
if empty:
|
||||||
ofp.write("e\n")
|
ofp.write("e\n")
|
||||||
|
elif nocontent:
|
||||||
|
empty = 1
|
||||||
if not numbered:
|
if not numbered:
|
||||||
ofp.write("Anumbered TOKEN no\n")
|
ofp.write("Anumbered TOKEN no\n")
|
||||||
|
opened = 0
|
||||||
# rip off the macroname
|
# rip off the macroname
|
||||||
if params:
|
if params:
|
||||||
if optional and len(params) == 1:
|
if optional and len(params) == 1:
|
||||||
@ -133,13 +151,15 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
#
|
#
|
||||||
if optional and type(params[0]) is type(()):
|
if optional and type(params[0]) is type(()):
|
||||||
# the attribute name isn't used in this special case
|
# the attribute name isn't used in this special case
|
||||||
|
pushing(macroname, "a", depth + len(stack))
|
||||||
stack.append(macroname)
|
stack.append(macroname)
|
||||||
ofp.write("(%s\n" % macroname)
|
ofp.write("(%s\n" % macroname)
|
||||||
m = _start_optional_rx.match(line)
|
m = _start_optional_rx.match(line)
|
||||||
if m:
|
if m:
|
||||||
line = line[m.end():]
|
line = line[m.end():]
|
||||||
line = subconvert(line, ofp, table, discards,
|
line = subconvert(line, ofp, table, discards,
|
||||||
autoclosing, endchar="]")
|
autoclosing, endchar="]",
|
||||||
|
depth=depth + len(stack))
|
||||||
line = "}" + line
|
line = "}" + line
|
||||||
continue
|
continue
|
||||||
# handle attribute mappings here:
|
# handle attribute mappings here:
|
||||||
@ -155,6 +175,7 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
elif type(attrname) is type(()):
|
elif type(attrname) is type(()):
|
||||||
# This is a sub-element; but don't place the
|
# This is a sub-element; but don't place the
|
||||||
# element we found on the stack (\section-like)
|
# element we found on the stack (\section-like)
|
||||||
|
pushing(macroname, "b", len(stack) + depth)
|
||||||
stack.append(macroname)
|
stack.append(macroname)
|
||||||
ofp.write("(%s\n" % macroname)
|
ofp.write("(%s\n" % macroname)
|
||||||
macroname = attrname[0]
|
macroname = attrname[0]
|
||||||
@ -164,10 +185,17 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
elif type(attrname) is type([]):
|
elif type(attrname) is type([]):
|
||||||
# A normal subelement.
|
# A normal subelement.
|
||||||
attrname = attrname[0]
|
attrname = attrname[0]
|
||||||
stack.append(macroname)
|
if not opened:
|
||||||
stack.append(attrname)
|
opened = 1
|
||||||
ofp.write("(%s\n" % macroname)
|
ofp.write("(%s\n" % macroname)
|
||||||
macroname = attrname
|
pushing(macroname, "c", len(stack) + depth)
|
||||||
|
ofp.write("(%s\n" % attrname)
|
||||||
|
pushing(attrname, "sub-elem", len(stack) + depth + 1)
|
||||||
|
line = subconvert(skip_white(line)[1:], ofp, table,
|
||||||
|
discards, autoclosing, endchar="}",
|
||||||
|
depth=depth + len(stack) + 2)
|
||||||
|
popping(attrname, "sub-elem", len(stack) + depth + 1)
|
||||||
|
ofp.write(")%s\n" % attrname)
|
||||||
else:
|
else:
|
||||||
m = _parameter_rx.match(line)
|
m = _parameter_rx.match(line)
|
||||||
if not m:
|
if not m:
|
||||||
@ -191,12 +219,18 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
"non-empty element '%s' has no content: %s"
|
"non-empty element '%s' has no content: %s"
|
||||||
% (macroname, line[:12]))
|
% (macroname, line[:12]))
|
||||||
line = line[m.end():]
|
line = line[m.end():]
|
||||||
stack.append(macroname)
|
if not opened:
|
||||||
ofp.write("(%s\n" % macroname)
|
ofp.write("(%s\n" % macroname)
|
||||||
|
pushing(macroname, "d", len(stack) + depth)
|
||||||
if empty:
|
if empty:
|
||||||
line = "}" + line
|
line = "}" + line
|
||||||
|
stack.append(macroname)
|
||||||
ofp = real_ofp
|
ofp = real_ofp
|
||||||
continue
|
continue
|
||||||
|
if line[0] == endchar and not stack:
|
||||||
|
if DEBUG:
|
||||||
|
sys.stderr.write("subconvert() --> %s\n" % `line[1:21]`)
|
||||||
|
return line[1:]
|
||||||
if line[0] == "}":
|
if line[0] == "}":
|
||||||
# end of macro
|
# end of macro
|
||||||
macroname = stack[-1]
|
macroname = stack[-1]
|
||||||
@ -206,10 +240,12 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
and type(conversion) is not type(""):
|
and type(conversion) is not type(""):
|
||||||
# otherwise, it was just a bare group
|
# otherwise, it was just a bare group
|
||||||
ofp.write(")%s\n" % stack[-1])
|
ofp.write(")%s\n" % stack[-1])
|
||||||
|
popping(macroname, "d", len(stack) + depth - 1)
|
||||||
del stack[-1]
|
del stack[-1]
|
||||||
line = line[1:]
|
line = line[1:]
|
||||||
continue
|
continue
|
||||||
if line[0] == "{":
|
if line[0] == "{":
|
||||||
|
pushing("", "e", len(stack) + depth)
|
||||||
stack.append("")
|
stack.append("")
|
||||||
line = line[1:]
|
line = line[1:]
|
||||||
continue
|
continue
|
||||||
@ -241,10 +277,12 @@ def subconvert(line, ofp, table, discards, autoclosing, endchar=None):
|
|||||||
while stack and stack[-1] in autoclosing:
|
while stack and stack[-1] in autoclosing:
|
||||||
ofp.write("-\\n\n")
|
ofp.write("-\\n\n")
|
||||||
ofp.write(")%s\n" % stack[-1])
|
ofp.write(")%s\n" % stack[-1])
|
||||||
|
popping(stack[-1], "e", len(stack) + depth - 1)
|
||||||
del stack[-1]
|
del stack[-1]
|
||||||
if stack:
|
if stack:
|
||||||
raise LaTeXFormatError("elements remain on stack: "
|
raise LaTeXFormatError("elements remain on stack: "
|
||||||
+ string.join(stack))
|
+ string.join(stack))
|
||||||
|
# otherwise we just ran out of input here...
|
||||||
|
|
||||||
|
|
||||||
def convert(ifp, ofp, table={}, discards=(), autoclosing=()):
|
def convert(ifp, ofp, table={}, discards=(), autoclosing=()):
|
||||||
@ -259,6 +297,12 @@ def convert(ifp, ofp, table={}, discards=(), autoclosing=()):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def skip_white(line):
|
||||||
|
while line and line[0] in " %\n\t":
|
||||||
|
line = string.lstrip(line[1:])
|
||||||
|
return line
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
ifp = open(sys.argv[1])
|
ifp = open(sys.argv[1])
|
||||||
@ -271,87 +315,93 @@ def main():
|
|||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
convert(ifp, ofp, {
|
convert(ifp, ofp, {
|
||||||
# entries have the form:
|
# entries have the form:
|
||||||
# name: ([attribute names], first_is_optional, empty, isenv)
|
# name: ([attribute names], first_is_optional, empty, isenv, nocontent)
|
||||||
"appendix": ([], 0, 1, 0),
|
"appendix": ([], 0, 1, 0, 0),
|
||||||
"bifuncindex": (["name"], 0, 1, 0),
|
"bifuncindex": (["name"], 0, 1, 0, 0),
|
||||||
"catcode": ([], 0, 1, 0),
|
"catcode": ([], 0, 1, 0, 0),
|
||||||
"cfuncdesc": (["type", "name", ("args",)], 0, 0, 1),
|
"cfuncdesc": (["type", "name", ("args",)], 0, 0, 1, 0),
|
||||||
"chapter": ([("title",)], 0, 0, 0),
|
"chapter": ([("title",)], 0, 0, 0, 0),
|
||||||
"chapter*": ([("title",)], 0, 0, 0),
|
"chapter*": ([("title",)], 0, 0, 0, 0),
|
||||||
"classdesc": (["name", ("constructor-args",)], 0, 0, 1),
|
"classdesc": (["name", ("constructor-args",)], 0, 0, 1, 0),
|
||||||
"ctypedesc": (["name"], 0, 0, 1),
|
"ctypedesc": (["name"], 0, 0, 1, 0),
|
||||||
"cvardesc": (["type", "name"], 0, 0, 1),
|
"cvardesc": (["type", "name"], 0, 0, 1, 0),
|
||||||
"datadesc": (["name"], 0, 0, 1),
|
"datadesc": (["name"], 0, 0, 1, 0),
|
||||||
"declaremodule": (["id", "type", "name"], 1, 1, 0),
|
"declaremodule": (["id", "type", "name"], 1, 1, 0, 0),
|
||||||
"deprecated": (["release"], 0, 0, 0),
|
"deprecated": (["release"], 0, 0, 0, 0),
|
||||||
"documentclass": (["classname"], 0, 1, 0),
|
"documentclass": (["classname"], 0, 1, 0, 0),
|
||||||
"excdesc": (["name"], 0, 0, 1),
|
"excdesc": (["name"], 0, 0, 1, 0),
|
||||||
"funcdesc": (["name", ("args",)], 0, 0, 1),
|
"funcdesc": (["name", ("args",)], 0, 0, 1, 0),
|
||||||
"funcdescni": (["name", ("args",)], 0, 0, 1),
|
"funcdescni": (["name", ("args",)], 0, 0, 1, 0),
|
||||||
"geq": ([], 0, 1, 0),
|
"geq": ([], 0, 1, 0, 0),
|
||||||
"hline": ([], 0, 1, 0),
|
"hline": ([], 0, 1, 0, 0),
|
||||||
"indexii": (["ie1", "ie2"], 0, 1, 0),
|
"indexii": (["ie1", "ie2"], 0, 1, 0, 0),
|
||||||
"indexiii": (["ie1", "ie2", "ie3"], 0, 1, 0),
|
"indexiii": (["ie1", "ie2", "ie3"], 0, 1, 0, 0),
|
||||||
"indexiv": (["ie1", "ie2", "ie3", "ie4"], 0, 1, 0),
|
"indexiv": (["ie1", "ie2", "ie3", "ie4"], 0, 1, 0, 0),
|
||||||
"indexname": ([], 0, 0, 0),
|
"indexname": ([], 0, 0, 0, 0),
|
||||||
"input": (["source"], 0, 1, 0),
|
"input": (["source"], 0, 1, 0, 0),
|
||||||
"item": ([("leader",)], 1, 0, 0),
|
"item": ([("leader",)], 1, 0, 0, 0),
|
||||||
"label": (["id"], 0, 1, 0),
|
"label": (["id"], 0, 1, 0, 0),
|
||||||
"labelwidth": ([], 0, 1, 0),
|
"labelwidth": ([], 0, 1, 0, 0),
|
||||||
"LaTeX": ([], 0, 1, 0),
|
"LaTeX": ([], 0, 1, 0, 0),
|
||||||
"leftmargin": ([], 0, 1, 0),
|
"leftmargin": ([], 0, 1, 0, 0),
|
||||||
"leq": ([], 0, 1, 0),
|
"leq": ([], 0, 1, 0, 0),
|
||||||
"localmoduletable": ([], 0, 1, 0),
|
"lineii": ([["entry"], ["entry"]], 0, 0, 0, 1),
|
||||||
"makeindex": ([], 0, 1, 0),
|
"lineiii": ([["entry"], ["entry"], ["entry"]], 0, 0, 0, 1),
|
||||||
"makemodindex": ([], 0, 1, 0),
|
"lineiv": ([["entry"], ["entry"], ["entry"], ["entry"]], 0, 0, 0, 1),
|
||||||
"maketitle": ([], 0, 1, 0),
|
"localmoduletable": ([], 0, 1, 0, 0),
|
||||||
"manpage": (["name", "section"], 0, 1, 0),
|
"makeindex": ([], 0, 1, 0, 0),
|
||||||
"memberdesc": (["class", "name"], 1, 0, 1),
|
"makemodindex": ([], 0, 1, 0, 0),
|
||||||
"methoddesc": (["class", "name", ("args",)], 1, 0, 1),
|
"maketitle": ([], 0, 1, 0, 0),
|
||||||
"methoddescni": (["class", "name", ("args",)], 1, 0, 1),
|
"manpage": (["name", "section"], 0, 1, 0, 0),
|
||||||
"moduleauthor": (["name", "email"], 0, 1, 0),
|
"memberdesc": (["class", "name"], 1, 0, 1, 0),
|
||||||
"opcodedesc": (["name", "var"], 0, 0, 1),
|
"methoddesc": (["class", "name", ("args",)], 1, 0, 1, 0),
|
||||||
"par": ([], 0, 1, 0),
|
"methoddescni": (["class", "name", ("args",)], 1, 0, 1, 0),
|
||||||
"paragraph": ([("title",)], 0, 0, 0),
|
"moduleauthor": (["name", "email"], 0, 1, 0, 0),
|
||||||
"renewcommand": (["macro"], 0, 0, 0),
|
"opcodedesc": (["name", "var"], 0, 0, 1, 0),
|
||||||
"rfc": (["number"], 0, 1, 0),
|
"par": ([], 0, 1, 0, 0),
|
||||||
"section": ([("title",)], 0, 0, 0),
|
"paragraph": ([("title",)], 0, 0, 0, 0),
|
||||||
"sectionauthor": (["name", "email"], 0, 1, 0),
|
"renewcommand": (["macro"], 0, 0, 0, 0),
|
||||||
"seemodule": (["ref", "name"], 1, 0, 0),
|
"rfc": (["number"], 0, 1, 0, 0),
|
||||||
"stindex": (["type"], 0, 1, 0),
|
"section": ([("title",)], 0, 0, 0, 0),
|
||||||
"subparagraph": ([("title",)], 0, 0, 0),
|
"sectionauthor": (["name", "email"], 0, 1, 0, 0),
|
||||||
"subsection": ([("title",)], 0, 0, 0),
|
"seemodule": (["ref", "name"], 1, 0, 0, 0),
|
||||||
"subsubsection": ([("title",)], 0, 0, 0),
|
"stindex": (["type"], 0, 1, 0, 0),
|
||||||
"list": (["bullet", "init"], 0, 0, 1),
|
"subparagraph": ([("title",)], 0, 0, 0, 0),
|
||||||
"tableii": (["colspec", "style", "head1", "head2"], 0, 0, 1),
|
"subsection": ([("title",)], 0, 0, 0, 0),
|
||||||
"tableiii": (["colspec", "style", "head1", "head2", "head3"], 0, 0, 1),
|
"subsubsection": ([("title",)], 0, 0, 0, 0),
|
||||||
"tableiv": (["colspec", "style", "head1", "head2", "head3", "head4"],
|
"list": (["bullet", "init"], 0, 0, 1, 0),
|
||||||
0, 0, 1),
|
"tableii": (["colspec", "style",
|
||||||
"version": ([], 0, 1, 0),
|
["entry"], ["entry"]], 0, 0, 1, 0),
|
||||||
"versionadded": (["version"], 0, 1, 0),
|
"tableiii": (["colspec", "style",
|
||||||
"versionchanged": (["version"], 0, 1, 0),
|
["entry"], ["entry"], ["entry"]], 0, 0, 1, 0),
|
||||||
"withsubitem": (["text"], 0, 0, 0),
|
"tableiv": (["colspec", "style",
|
||||||
|
["entry"], ["entry"], ["entry"], ["entry"]], 0, 0, 1, 0),
|
||||||
|
"version": ([], 0, 1, 0, 0),
|
||||||
|
"versionadded": (["version"], 0, 1, 0, 0),
|
||||||
|
"versionchanged": (["version"], 0, 1, 0, 0),
|
||||||
|
"withsubitem": (["text"], 0, 0, 0, 0),
|
||||||
#
|
#
|
||||||
"ABC": ([], 0, 1, 0),
|
"ABC": ([], 0, 1, 0, 0),
|
||||||
"ASCII": ([], 0, 1, 0),
|
"ASCII": ([], 0, 1, 0, 0),
|
||||||
"C": ([], 0, 1, 0),
|
"C": ([], 0, 1, 0, 0),
|
||||||
"Cpp": ([], 0, 1, 0),
|
"Cpp": ([], 0, 1, 0, 0),
|
||||||
"EOF": ([], 0, 1, 0),
|
"EOF": ([], 0, 1, 0, 0),
|
||||||
"e": ([], 0, 1, 0),
|
"e": ([], 0, 1, 0, 0),
|
||||||
"ldots": ([], 0, 1, 0),
|
"ldots": ([], 0, 1, 0, 0),
|
||||||
"NULL": ([], 0, 1, 0),
|
"NULL": ([], 0, 1, 0, 0),
|
||||||
"POSIX": ([], 0, 1, 0),
|
"POSIX": ([], 0, 1, 0, 0),
|
||||||
"UNIX": ([], 0, 1, 0),
|
"UNIX": ([], 0, 1, 0, 0),
|
||||||
#
|
#
|
||||||
# Things that will actually be going away!
|
# Things that will actually be going away!
|
||||||
#
|
#
|
||||||
"fi": ([], 0, 1, 0),
|
"fi": ([], 0, 1, 0, 0),
|
||||||
"ifhtml": ([], 0, 1, 0),
|
"ifhtml": ([], 0, 1, 0, 0),
|
||||||
"makeindex": ([], 0, 1, 0),
|
"makeindex": ([], 0, 1, 0, 0),
|
||||||
"makemodindex": ([], 0, 1, 0),
|
"makemodindex": ([], 0, 1, 0, 0),
|
||||||
"maketitle": ([], 0, 1, 0),
|
"maketitle": ([], 0, 1, 0, 0),
|
||||||
"noindent": ([], 0, 1, 0),
|
"noindent": ([], 0, 1, 0, 0),
|
||||||
"tableofcontents": ([], 0, 1, 0),
|
"protect": ([], 0, 1, 0, 0),
|
||||||
|
"tableofcontents": ([], 0, 1, 0, 0),
|
||||||
},
|
},
|
||||||
discards=["fi", "ifhtml", "makeindex", "makemodindex", "maketitle",
|
discards=["fi", "ifhtml", "makeindex", "makemodindex", "maketitle",
|
||||||
"noindent", "tableofcontents"],
|
"noindent", "tableofcontents"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user