## Base Formatting classes # Thomas Michon # import ReportLab libraries from reportlab.pdfgen import canvas from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter # Used to open the PDF at the end in Acrobat import subprocess # Provides a way to abstract alignment of text by line. class Alignment(object): def left_align(box_width, item_width): return 0 def right_align(box_width, item_width): return box_width - item_width def center_align(box_width, item_width): return (box_width - item_width) / 2.0 left = staticmethod(left_align) center = staticmethod(center_align) right = staticmethod(right_align) # Handles font styling, combining bold and italic versions of fonts class Font(object): def __init__(self, name, regular, italic, bold, bold_italic): self.___name = name self.___regular = regular self.___italic = italic self.___bold = bold self.___bold_italic = bold_italic def get_name(self): return self.___name name = property(get_name) def get_regular(self): return self.___regular regular = property(get_regular) def get_italic(self): return self.___italic italic = property(get_italic) def get_bold(self): return self.___bold bold = property(get_bold) def get_bold_italic(self): return self.___bold_italic bold_italic = property(get_bold_italic) def get_by_style(self, bold=False, italic=False): if bold and italic: return self.bold_italic if bold: return self.bold if italic: return self.italic return self.regular times = Font("Times", "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic") courier = Font("Courier", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique") helvetica = Font("Helvetica", "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique") # Base class for all text formatters. This one does nothing. class Formatter(object): def __init__(self, box): self.___box = box def get_box(self): return self.___box box = property(get_box) def format(self, canvas): pass # Performs line-wrapping. Handles line-breaks, page-breaks, and text alignment. class WrapFormatter(Formatter): def __init__(self, box, pagination=False): Formatter.__init__(self, box) self.___rows = [] def get_rows(self): return self.___rows rows = property(get_rows) def clear_rows(self): self.___rows = [] def build_rows(self, rows): current_row = None row_index = -1 for item in self.box.children: if (current_row == None or current_row[1] + item.width > self.box.inner_width \ or item.implicit_linebreak) and not item.whitespace: rows.append([[], 0, 0]) row_index += 1 current_row = rows[row_index] current_row[0].append(item) current_row[1] += item.width if row_index == 0: current_row[1] += self.box.indent_first current_row[2] = max(current_row[2], item.height) def position_rows(self, rows, x, y): for row in rows: self.position_items(row, x, y) y += row[2] def position_items(self, row, x, y): for item in row[0]: item.position = x + self.box.halign(self.box.inner_width, row[1]), y + (row[2] - item.height) / 2.0 x += item.width """Fits as many objects across the given Box and extends the Box downwards""" def format(self, canvas): width_min = max([item.width for item in self.box.children]) + self.box.margin_left + self.box.margin_right self.box.width = max(self.box.width, width_min) self.clear_rows() self.build_rows(self.rows) height_min = sum([row[2] for row in self.rows]) + self.box.margin_top + self.box.margin_bottom self.box.height = max(self.box.height, height_min) self.position_rows(self.rows, self.box.margin_left, self.box.margin_top) # Puts everything on one line and ignores wrapping. Good for things which should stay together, # such as Fractions class StretchFormatter(Formatter): """Puts all the objects on a single line and stretches the width of the Box to compensate""" def format(self, canvas): self.box.width = sum([item.width for item in self.box.children]) + self.box.margin_left + self.box.margin_right self.box.height = max([item.height for item in self.box.children]) + self.box.margin_top + self.box.margin_bottom x, y = self.box.margin_left, self.box.margin_top for item in self.box.children: item.position = x, y + (self.box.inner_height - item.height) / 2.0 x += item.width # Implements pagination for the top-level Document class. Unfortunately, this one breaks the # Formatter interface, since the Document accesses Formatter.pages class PageFormatter(WrapFormatter): def __init__(self, box): WrapFormatter.__init__(self, box) self.___pages = [] def get_pages(self): return self.___pages pages = property(get_pages) def clear_pages(self): self.___pages = [] def build_pages(self, pages): current_page = None page_index = -1 for row in self.rows: if current_page == None or current_page[2] + row[2] > self.box.inner_height \ or row[0][0].implicit_pagebreak: pages.append([[], 0, 0]) page_index += 1 current_page = pages[page_index] current_page[0].append(row) current_page[2] += row[2] current_page[1] = max(current_page[1], row[1]) def format(self, canvas): self.clear_rows() self.clear_pages() self.build_rows(self.rows) self.build_pages(self.pages) for page in self.pages: self.position_rows(page[0], self.box.margin_left, self.box.margin_top) # Allows Boxes to format themselves by providing their own methods. Good for weird things. class CustomFormatter(Formatter): """Calls a custom format method for specialized packing""" def __init__(self, box, pack_method): Formatter.__init__(self, box) self.___pack_method = pack_method def get_pack_method(self): return self.___pack_method pack_method = property(get_pack_method) def format(self, canvas): self.pack_method(canvas) ### ITEM ### # The primary formatting class. Everything is an Item in a Box. # Items inherit most styling elements, such as font-size and bold text, # from their parents. class Item(object): def __init__(self): self.___parent = None self.___width, self.___height = 0, 0 self.___x, self.___y = 0, 0 self.___imp_pbr = False self.___imp_cbr = False self.___imp_lbr = False self.___whitespace = False self.___font_size = -1 self.___font_family = None self.___font_scale = 1 self.___line_offset = 0.3 self.___bold = None self.___italic = None self.___border_thickness = 0 """Sets the parent of the Item to the given Box. Guarantees that any Item only has one parent, and only one Box has a given Item as its child.""" def set_parent(self, box): if self.___parent == box: return if self.___parent != None: self.___parent.remove(self) self.___parent = box if self.___parent != None: self.___parent.add(self) def get_parent(self): return self.___parent parent = property(get_parent, set_parent) """Determines whether this item must start on its own line.""" def set_implicit_linebreak(self, imp_lbr): self.___imp_lbr = imp_lbr def get_implicit_linebreak(self): return self.___imp_lbr implicit_linebreak = property(get_implicit_linebreak, set_implicit_linebreak) """Determines whether this item must start on its own page.""" def set_implicit_pagebreak(self, imp_pbr): self.___imp_pbr = imp_pbr def get_implicit_pagebreak(self): return self.___imp_pbr implicit_pagebreak = property(get_implicit_pagebreak, set_implicit_pagebreak) """Determines whether this item is just whitespace, and is immune to some formatting conventions.""" def set_whitespace(self, whitespace): self.___whitespace = whitespace def get_whitespace(self): return self.___whitespace whitespace = property(get_whitespace, set_whitespace) """Determines how large the text (if any) in this item will be. If not set, inherits from its parent.""" def set_font_size(self, font_size): self.___font_size = font_size def get_font_size(self): if self.___font_size <= 0: if self.parent == None: return 11 return self.parent.font_size return self.___font_size font_size = property(get_font_size, set_font_size) """Determines how much this item will scale the fonts of everything inside it, in order to allow for things to get smaller.""" def set_font_scale(self, font_scale): self.___font_scale = font_scale def get_font_scale(self): return self.___font_scale font_scale = property(get_font_scale, set_font_scale) """Gets the absolute font scale of this item relative to the top-level document.""" def get_font_disp_scale(self): if self.parent == None: return self.font_scale return self.parent.font_disp_scale * self.font_scale font_disp_scale = property(get_font_disp_scale) """Gets the absolute font size of this item once scaled by the font scale factor.""" def get_font_disp_size(self): return self.font_size * self.font_disp_scale font_disp_size = property(get_font_disp_size) def set_font_family(self, font_family): self.___font_family = font_family def get_font_family(self): if self.___font_family == None: if self.parent == None: return times return self.parent.font_family return self.___font_family font_family = property(get_font_family, set_font_family) def set_font(self, font): self.font_family, self._font_size = font def get_font(self): return self.font_family, self.font_size font = property(get_font, set_font) def set_bold(self, bold): self.___bold = bold def get_bold(self): if self.___bold == None: if self.parent == None: return False return self.parent.bold return self.___bold bold = property(get_bold, set_bold) def set_italic(self, italic): self.___italic = italic def get_italic(self): if self.___italic == None: if self.parent == None: return False return self.parent.italic return self.___italic italic = property(get_italic, set_italic) def set_line_offset(self, line_offset): self.___line_offset = line_offset def get_line_offset(self): return self.___line_offset line_offset = property(get_line_offset, set_line_offset) def set_border_thickness(self, border_thickness): self.___border_thickness = border_thickness def get_border_thickness(self): return self.___border_thickness border_thickness = property(get_border_thickness, set_border_thickness) def set_width(self, width): self.___width = width def get_width(self): return self.___width width = property(get_width, set_width) def set_height(self, height): self.___height = height def get_height(self): return self.___height height = property(get_height, set_height) def set_dimensions(self, dimensions): self.width, self.height = dimensions def get_dimensions(self): return self.width, self.height dimensions = property(get_dimensions, set_dimensions, doc="The Item's dimensions. This is meant for internal use only.") def set_x(self, x): self.___x = x def get_x(self): return self.___x x = property(get_x, set_x) def set_y(self, y): self.___y = y def get_y(self): return self.___y y = property(get_y, set_y) def set_position(self, position): self.x, self.y = position def get_position(self): return self.x, self.y position = property(get_position, set_position, doc="The Item's position within its parent. This is meant for internal use only.") def get_doc_depth(self): if self.parent == None: return -1 depth = self.parent.get_doc_depth() if depth == -1: return -1 return depth + 1 def get_document(self): if self.parent == None: return None return self.parent.get_document() def pack(self, canvas): pass def draw(self, canvas): canvas.saveState() self.draw_border(canvas) canvas.restoreState() canvas.saveState() self.draw_self(canvas) canvas.restoreState() def draw_border(self, canvas): canvas.setLineWidth(self.border_thickness) if self.border_thickness > 0: canvas.rect(0, 0, self.width, self.height) def draw_self(self, canvas): pass ### BOX ### # The general container class. Boxes are Items, but with content. Boxes have Formatters # which do all the dirty work. class Box(Item): def __init__(self): Item.__init__(self) self.___children = [] self.___margin_left, self.margin_right, self.___margin_top, self.margin_bottom = 0, 0, 0, 0 self.___pref_width, self.___pref_height = 0, 0 self.___formatter = WrapFormatter(self) self.___halign = Alignment.left self.___indent_first = 0 def set_formatter(self, formatter): if formatter == None: return self.___formatter = formatter def get_formatter(self): return self.___formatter formatter = property(get_formatter, set_formatter) def set_halign(self, halign): self.___halign = halign def get_halign(self): return self.___halign halign = property(get_halign, set_halign) def set_valign(self, valign): self.___halign = valign def get_valign(self): return self.___valign valign = property(get_valign, set_valign) def set_pref_width(self, width): self.___pref_width = width def get_pref_width(self): return self.___pref_width pref_width = property(get_pref_width, set_pref_width) def set_pref_height(self, height): self.___pref_height = height def get_pref_height(self): return self.___pref_height pref_height = property(get_pref_height, set_pref_height) def set_pref_dimensions(self, dimensions): self.pref_width, self.pref_height = dimensions def get_pref_dimensions(self): return self.pref_width, self.pref_height pref_dimensions = property(get_pref_dimensions, set_pref_dimensions) def set_margin_left(self, margin_left): self.___margin_left = margin_left def get_margin_left(self): return self.___margin_left margin_left = property(get_margin_left, set_margin_left) def set_margin_right(self, margin_right): self.___margin_right = margin_right def get_margin_right(self): return self.___margin_right margin_right = property(get_margin_right, set_margin_right) def set_margin_top(self, margin_top): self.___margin_top = margin_top def get_margin_top(self): return self.___margin_top margin_top = property(get_margin_top, set_margin_top) def set_margin_bottom(self, margin_bottom): self.___margin_bottom = margin_bottom def get_margin_bottom(self): return self.___margin_bottom margin_bottom = property(get_margin_bottom, set_margin_bottom) def set_margin(self, margin): self.margin_left, self.margin_right, self.margin_top, self.margin_bottom = margin def get_margin(self): return self.margin_left, self.margin_right, self.margin_top, self.margin_bottom margin = property(get_margin, set_margin) def get_inner_width(self): return self.width - self.margin_left - self.margin_right inner_width = property(get_inner_width) def get_inner_height(self): return self.height - self.margin_top - self.margin_bottom inner_height = property(get_inner_height) def get_inner_dimensions(self): return self.inner_width, self.inner_height inner_dimensions = property(get_pref_dimensions) def set_indent_first(self, indent_first): self.___indent_first = indent_first def get_indent_first(self): return self.___indent_first indent_first = property(get_indent_first, set_indent_first) def get_children(self): return self.___children children = property(get_children) def get_num_children(self): return len(self.children) num_children = property(get_num_children) def add(self, item, index=-1): if item in self.children: return self.children.append(item) item.parent = self def remove(self, item): if item not in self.children: return self.children.remove(item) item.parent = None def pack(self, canvas): self.dimensions = self.pref_dimensions if self.parent is not None: if self.pref_width < 0: self.width = - (self.parent.width - self.parent.margin_left - self.parent.margin_right) * self.pref_width if self.pref_height < 0: self.height = - (self.parent.height - self.parent.margin_top - self.parent.margin_bottom) * self.pref_height for item in self.children: item.pack(canvas) self.formatter.format(canvas) def draw_self(self, canvas): Item.draw_self(self, canvas) self.draw_children(canvas, self.children) def draw_children(self, canvas, children): for item in children: canvas.saveState() canvas.translate(item.x, self.height - item.y - item.height) item.draw(canvas) canvas.restoreState() def add_text(self, text, font_size=-1, bold=None, italic=None): words = text.split(" ") first = True for word in words: if first: first = False else: self.add(Space(font_size=font_size, bold=bold, italic=italic)) self.add(TextLiteral(word, font_size=font_size, bold=bold, italic=italic)) def add_math(self, math, font_size=-1, bold=None, italic=None): words = math.split(" ") first = True for word in words: if first: first = False else: self.add(Space(font_size=font_size, bold=bold, italic=italic)) self.add(MathLiteral(word, font_size=font_size, bold=bold, italic=italic)) def add_formatted(self, formatted, font_size=-1, bold=None, italic=None): self.add(TextLiteral(formatted, font_size=font_size, bold=bold, italic=italic)) def add_linebreak(self): self.add(LineBreak()) ## Document Components class Document(Box): def __init__(self): Box.__init__(self) self.___name = "" self.pref_dimensions = letter self.margin = inch, inch, inch, inch self.font_size = 11 self.font_family = times self.formatter = PageFormatter(self) def set_name(self, name): self.___name = name def get_name(self): return self.___name name = property(get_name, set_name) def get_doc_depth(self): return 0 def get_document(self): return self def pack(self, canvas): Box.pack(self, canvas) canvas.setPageSize(self.dimensions) def draw(self, canvas): for page in self.formatter.pages: children = [] for row in page[0]: children.extend(row[0]) Box.draw_children(self, canvas, children) canvas.showPage() ## Boxes class Paragraph(Box): def __init__(self): Box.__init__(self) self.pref_dimensions = -1, 0 self.implicit_linebreak = True class Figure(Box): pass class Fraction(Box): def __init__(self, numerator=None, denominator=None): Box.__init__(self) self.add(Box()) self.add(Box()) self.formatter = CustomFormatter(self, self.format) self.numerator.formatter = StretchFormatter(self.numerator) self.denominator.formatter = StretchFormatter(self.denominator) self.halign = Alignment.center self.font_scale = 0.9 def get_numerator(self): return self.children[0] numerator = property(get_numerator) def get_denominator(self): return self.children[1] denominator = property(get_denominator) def format(self, canvas): width_limit = max([item.width for item in self.children]) self.width = width_limit + self.margin_left + self.margin_right self.height = sum([item.height for item in self.children]) + self.margin_top + self.margin_bottom x, y = self.margin_left, self.margin_top first = True for item in self.children: item.position = x + self.halign(width_limit, item.width), y y += item.height def draw_self(self, canvas): Box.draw_self(self, canvas) first = True for item in self.children: canvas.setStrokeColorRGB(0, 0, 0) canvas.setLineWidth(0.2) if first: first = False else: y = self.height - item.y canvas.line(self.margin_left, y, self.width - self.margin_right, y) ## Items class Literal(Item): def __init__(self, text='', font_size=-1, bold=None, italic=None): Item.__init__(self) self.___text = text self.font_size = font_size self.italic = italic self.bold = bold def set_text(self, text): self.___text = text def get_text(self): return self.___text text = property(get_text, set_text) def pack(self, canvas): self.width = canvas.stringWidth(self.text, self.font_family.get_by_style(self.bold, self.italic), self.font_disp_size) self.height = self.font_disp_size * 1.3 def draw_self(self, canvas): canvas.setFont(self.font_family.get_by_style(self.bold, self.italic), self.font_disp_size) canvas.drawString(0, self.font_disp_size * self.line_offset, self.text) class Space(Literal): def __init__(self, font_size=-1, bold=None, italic=None): Literal.__init__(self, text=' ', font_size=font_size, bold=bold, italic=italic) self.whitespace = True class TextLiteral(Literal): pass class MathLiteral(Literal): def __init__(self, text='', font_size=-1, bold=None, italic=None): Literal.__init__(self, text, font_size, bold=bold, italic=italic) def pack(self, canvas): self.width = 0 self.height = self.font_disp_size * 1.3 for char in self.text: font = self.font_family.get_by_style(self.bold, self.italic) if char.isalpha(): font = self.font_family.get_by_style(self.bold, not self.italic) self.width += canvas.stringWidth(char, font, self.font_disp_size) def draw_self(self, canvas): x = 0 for char in self.text: font = self.font_family.get_by_style(self.bold, False) if char.isalpha(): font = self.font_family.get_by_style(self.bold, True) canvas.setFont(font, self.font_disp_size) canvas.drawString(x, self.font_disp_size * self.line_offset, char) x += canvas.stringWidth(char, font, self.font_disp_size) class Break(Item): def __init__(self): Item.__init__(self) self.implicit_linebreak = True class LineBreak(Break): pass class PageBreak(Break): def __init__(self): Break.__init__(self) self.implicit_pagebreak = True import string import time ###defines the commands and templates for use inside functions OBJECTS = { LineBreak:["linebreak","lnbr"], PageBreak:["pagebreak","pgbr"], Paragraph:["paragraph","par"], Fraction:["fraction","frac"] } FUNCTIONS = { "denominator":["denominator", "den"], "endobject":["end","|"], "title":["title"], "math":["math"], "endmath":["endmath"], "tabsize":["tabsize", "tab"], "whack":["whack", "w"], "triplesinglequotes":["triplesinglequotes","tsq"], "sub":["sub0","sub1","sub2", "sub3","sub4", "sub5"], "bold":["bold", "b"], "italics":["italics", "italic", "i"], "plain":["plain"] } TABSIZE = 4 COMMANDS_TEMPLATE = "\COMMANDS\n" for obj in OBJECTS: objstr = string.split(str(obj), ".")[1][:-2] COMMANDS_TEMPLATE+=objstr+"="+OBJECTS[obj][0]+"\n" for func in FUNCTIONS: COMMANDS_TEMPLATE+=func+"="+FUNCTIONS[func][0]+"\n" COMMANDS_TEMPLATE+="\\\n" COMMENT_TEMPLATE = "'''COMMENT HERE'''" PARAGRAPH_TEMPLATE = "\par[halign=Alignment.left font_size=11] \n\n\end\n" FRACTION_TEMPLATE = "\\fraction NUMERATOR \denominator DENOMINATOR \end " DATE_TEMPLATE = time.strftime("%m/%d/%y") HEADER_TEMPLATE = "\par[halign=Alignment.center font_size=25] \end" APPENDIX_TEMPLATE = "\par[halign=Alignment.center font_size=25] Appendix I \end" STARTS_WITH_CARRIAGE_RETURN = ["HEADER", "APPENDIX", "PARAGRAPH", "COMMANDS"] def jontex(action, *a, **kw): '''function jontex is what is called by Flauxtext - it calls either parse or insert depending on which item in the menu the user selected''' if action=="parse": parse(self.current_text()) elif action[:6]=="insert": buf = self.current_buffer() ins_type = string.upper(action[6:]) ins=eval(ins_type+"_TEMPLATE") if buf.get_iter_at_mark(buf.get_insert()).get_line_offset()!=0 and ins_type in STARTS_WITH_CARRIAGE_RETURN: ins="\n"+ins buf.insert_at_cursor(ins) def parse(text, title="untitled"): '''parse is what creates a PDF out of the given text''' global TABSIZE TABSIZE = 4 #Weird import calls because of the plugin flauxtext.imp0rt("reportlab.pdfgen.canvas") flauxtext.imp0rt("reportlab.pdfbase.pdfmetrics") flauxtext.imp0rt("subprocess") doc = Document() doc.name = title while "'''" in text: #deal with commented out areas begin_comment = text.index("'''")+3 try: size_commented = text[begin_comment:].index("'''") except ValueError: break text = text[:begin_comment-3]+text[begin_comment+size_commented+3:] sections = string.split(text, "\\") add_to_box(sections, doc) #call the function that adds all the proper objects to the PDF canv = flauxtext.reportlab.pdfgen.canvas.Canvas(doc.name + ".pdf") doc.pack(canv) doc.draw(canv) canv.save() flauxtext.subprocess.Popen(doc.name + ".pdf", shell=True) ##open the PDF return doc def add_to_commands(commands): '''function to append to the commands dictionary so that the user can customize commands''' global OBJECTS global FUNCTIONS for comm in commands: spl = string.split(comm, "=") for obj in OBJECTS: obj_name = string.split(str(obj),".")[1][:-2] if spl[0] == obj_name: OBJECTS[obj].append(spl[1]) for func in FUNCTIONS: if spl[0] == func: FUNCTIONS[func].append(spl[1]) def get_argstags(options): '''gets the args and/or tags out of the initiation of a box''' options = options[:-1].split() tags=[] args=[] for opt in options: opt = opt.split("=") if len(opt)==1: tags.append(opt) elif len(opt)==2: args.append(opt) return args, tags def deal_with_next(sections, curobject): '''adds the next chunk of text to the current object''' next_chunk = sections.pop(0).strip("\n") if not next_chunk: return if next_chunk[0]==" ": next_chunk = next_chunk[1:] par_check = string.split(next_chunk, "\n") if len(par_check)==1: if math: curobject.add_math(next_chunk, bold=bold, italic=italics) else: curobject.add_text(next_chunk, bold=bold, italic=italics) else: for chunk in par_check: if math: curobject.add_math(chunk, bold=bold, italic=italics) else: curobject.add_text(chunk, bold=bold, italic=italics) curobject.add(LineBreak()) def make_comm(sections): '''takes an object initiation and returns the object as well as the options''' comm = string.lower(sections[0].split()[0]) options="" if "[" in comm: comm = sections[0][:sections[0].index("]")+1] options = comm[comm.index("[")+1:] comm = string.lower(comm[:comm.index("[")]) if options[-1]!="]": comm = comm+"["+options return comm, options math = False italics = False bold = False def add_to_box(sections, curobject): '''add_to_box takes a string that was split on \ and then calls itself for every new command that it needs to implement''' global math global TABSIZE global bold global italics while "\t" in sections[0]: sections[0] = sections[0].replace("\t", " "*TABSIZE) deal_with_next(sections, curobject) if len(sections)==0: return else: found_comm = False comm, options = make_comm(sections) for obj in OBJECTS: #Check to see if the given command is a new object if comm in OBJECTS[obj]: found_comm = True sections[0] = sections[0][len(comm)+1+len(options):] args, tags = get_argstags(options) new_child = obj() for arg in args: setattr(new_child, arg[0], eval(arg[1])) for tag in tags: setattr(new_child, tag, True) curobject.add(new_child) if isinstance(new_child, Box): if isinstance(new_child, Fraction): math = True add_to_box(sections, new_child.numerator) else: add_to_box(sections, new_child) else: add_to_box(sections,curobject) for func in FUNCTIONS: #Check to see if the given command is a function if comm in FUNCTIONS[func]: found_comm = True sections[0] = sections[0][len(comm)+1:] if func == "denominator": add_to_box(sections, curobject.parent.denominator) elif func == "endobject": if isinstance(curobject.parent, Fraction): math = False add_to_box(sections, curobject.parent.parent) else: add_to_box(sections, curobject.parent) elif func == "title": curobject.get_document().name = sections[0].split()[0] sections[0] = sections[0][len(sections[0].split()[0])+1:] add_to_box(sections, curobject) elif func=="math": math=True add_to_box(sections, curobject) elif func=="endmath": math=False add_to_box(sections, curobject) elif func=="tabsize": newsize = sections[0].split()[0] try: TABSIZE = int(newsize) sections[0] = sections[0][len(newsize)+1:] add_to_box(sections, curobject) except: add_to_box(sections, curobject) elif func=="whack": sections[0] = "\\"+sections[0] add_to_box(sections, curobject) elif func=="triplesinglequotes": sections[0] = "'''"+sections[0] add_to_box(sections, curobject) elif func=="sub": headertype = int(comm[3:]) size = 22-headertype*4 sections.insert(1,"par[font_size="+str(size)+"] "+sections[0]) if headertype==0 or headertype==1: sections.insert(1,"linebreak ") sections[0] = "" add_to_box(sections, curobject) elif func=="italics": italics=True add_to_box(sections, curobject) elif func=="bold": bold=True add_to_box(sections, curobject) elif func=="plain": bold=False italics=False add_to_box(sections, curobject) if comm == "commands": #if the command was "commands" then do a command customization found_comm = True add_to_commands(sections[0].split()[1:]) add_to_box(sections[1:],curobject) if not found_comm: #if the command wasn't found in the dictionaries then add it as text add_to_box(sections, curobject)