?? latex2esis.py
字號:
#! /usr/bin/env python"""Generate ESIS events based on a LaTeX source document andconfiguration data.The conversion is not strong enough to work with arbitrary LaTeXdocuments; it has only been designed to work with the highly stylizedmarkup used in the standard Python documentation. A lot ofinformation about specific markup is encoded in the control tablepassed to the convert() function; changing this table can allow thistool to support additional LaTeX markups.The format of the table is largely undocumented; see the commentedheaders where the table is specified in main(). There is no provision to load an alternate table from an external file."""__version__ = '$Revision: 1.1.1.1 $'import copyimport errnoimport getoptimport osimport reimport stringimport StringIOimport sysimport UserListfrom esistools import encodefrom types import ListType, StringType, TupleTypetry: from xml.parsers.xmllib import XMLParserexcept ImportError: from xmllib import XMLParserDEBUG = 0class LaTeXFormatError(Exception): passclass LaTeXStackError(LaTeXFormatError): def __init__(self, found, stack): msg = "environment close for %s doesn't match;\n stack = %s" \ % (found, stack) self.found = found self.stack = stack[:] LaTeXFormatError.__init__(self, msg)_begin_env_rx = re.compile(r"[\\]begin{([^}]*)}")_end_env_rx = re.compile(r"[\\]end{([^}]*)}")_begin_macro_rx = re.compile(r"[\\]([a-zA-Z]+[*]?) ?({|\s*\n?)")_comment_rx = re.compile("%+ ?(.*)\n[ \t]*")_text_rx = re.compile(r"[^]%\\{}]+")_optional_rx = re.compile(r"\s*[[]([^]]*)[]]")# _parameter_rx is this complicated to allow {...} inside a parameter;# this is useful to match tabular layout specifications like {c|p{24pt}}_parameter_rx = re.compile("[ \n]*{(([^{}}]|{[^}]*})*)}")_token_rx = re.compile(r"[a-zA-Z][a-zA-Z0-9.-]*$")_start_group_rx = re.compile("[ \n]*{")_start_optional_rx = re.compile("[ \n]*[[]")ESCAPED_CHARS = "$%#^ {}&~"def dbgmsg(msg): if DEBUG: sys.stderr.write(msg + "\n")def pushing(name, point, depth): dbgmsg("pushing <%s> at %s" % (name, point))def popping(name, point, depth): dbgmsg("popping </%s> at %s" % (name, point))class _Stack(UserList.UserList): def append(self, entry): if type(entry) is not StringType: raise LaTeXFormatError("cannot push non-string on stack: " + `entry`) sys.stderr.write("%s<%s>\n" % (" "*len(self.data), entry)) self.data.append(entry) def pop(self, index=-1): entry = self.data[index] del self.data[index] sys.stderr.write("%s</%s>\n" % (" "*len(self.data), entry)) def __delitem__(self, index): entry = self.data[index] del self.data[index] sys.stderr.write("%s</%s>\n" % (" "*len(self.data), entry))def new_stack(): if DEBUG: return _Stack() return []class Conversion: def __init__(self, ifp, ofp, table): self.write = ofp.write self.ofp = ofp self.table = table self.line = string.join(map(string.rstrip, ifp.readlines()), "\n") self.preamble = 1 def err_write(self, msg): if DEBUG: sys.stderr.write(str(msg) + "\n") def convert(self): self.subconvert() def subconvert(self, endchar=None, depth=0): # # Parses content, including sub-structures, until the character # 'endchar' is found (with no open structures), or until the end # of the input data is endchar is None. # stack = new_stack() line = self.line while line: if line[0] == endchar and not stack: self.line = line return line m = _comment_rx.match(line) if m: text = m.group(1) if text: self.write("(COMMENT\n- %s \n)COMMENT\n-\\n\n" % encode(text)) line = line[m.end():] continue m = _begin_env_rx.match(line) if m: name = m.group(1) entry = self.get_env_entry(name) # re-write to use the macro handler line = r"\%s %s" % (name, line[m.end():]) continue m = _end_env_rx.match(line) if m: # end of environment envname = m.group(1) entry = self.get_entry(envname) while stack and envname != stack[-1] \ and stack[-1] in entry.endcloses: self.write(")%s\n" % stack.pop()) if stack and envname == stack[-1]: self.write(")%s\n" % entry.outputname) del stack[-1] else: raise LaTeXStackError(envname, stack) line = line[m.end():] continue m = _begin_macro_rx.match(line) if m: # start of macro macroname = m.group(1) entry = self.get_entry(macroname) if entry.verbatim: # magic case! pos = string.find(line, "\\end{%s}" % macroname) text = line[m.end(1):pos] stack.append(entry.name) self.write("(%s\n" % entry.outputname) self.write("-%s\n" % encode(text)) self.write(")%s\n" % entry.outputname) stack.pop() line = line[pos + len("\\end{%s}" % macroname):] continue while stack and stack[-1] in entry.closes: top = stack.pop() topentry = self.get_entry(top) if topentry.outputname: self.write(")%s\n-\\n\n" % topentry.outputname) # if entry.outputname: if entry.empty: self.write("e\n") # params, optional, empty, environ = self.start_macro(macroname) # rip off the macroname if params: line = line[m.end(1):] elif empty: line = line[m.end(1):] else: line = line[m.end():] opened = 0 implied_content = 0 # handle attribute mappings here: for pentry in params: if pentry.type == "attribute": if pentry.optional: m = _optional_rx.match(line) if m and entry.outputname: line = line[m.end():] self.dump_attr(pentry, m.group(1)) elif pentry.text and entry.outputname: # value supplied by conversion spec: self.dump_attr(pentry, pentry.text) else: m = _parameter_rx.match(line) if not m: raise LaTeXFormatError( "could not extract parameter %s for %s: %s" % (pentry.name, macroname, `line[:100]`)) if entry.outputname: self.dump_attr(pentry, m.group(1)) line = line[m.end():] elif pentry.type == "child": if pentry.optional: m = _optional_rx.match(line) if m: line = line[m.end():] if entry.outputname and not opened: opened = 1 self.write("(%s\n" % entry.outputname) stack.append(macroname) stack.append(pentry.name) self.write("(%s\n" % pentry.name) self.write("-%s\n" % encode(m.group(1))) self.write(")%s\n" % pentry.name) stack.pop() else: if entry.outputname and not opened: opened = 1 self.write("(%s\n" % entry.outputname) stack.append(entry.name) self.write("(%s\n" % pentry.name) stack.append(pentry.name) self.line = skip_white(line)[1:] line = self.subconvert( "}", len(stack) + depth + 1)[1:] self.write(")%s\n" % stack.pop()) elif pentry.type == "content": if pentry.implied: implied_content = 1 else: if entry.outputname and not opened: opened = 1 self.write("(%s\n" % entry.outputname) stack.append(entry.name) line = skip_white(line) if line[0] != "{": raise LaTeXFormatError( "missing content for " + macroname) self.line = line[1:] line = self.subconvert("}", len(stack) + depth + 1) if line and line[0] == "}": line = line[1:] elif pentry.type == "text" and pentry.text: if entry.outputname and not opened: opened = 1 stack.append(entry.name)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -