def syllables(element, span_style=None): if isinstance(element, xsc.Text): u = element.__unicode__() match = starts_word_re.search(u) starts_word = (match is not None) for letters, whitespace in word_re.findall(u): ends_word = ( whitespace != u"" ) if ends_word: whitespace_style = span_style else: whitespace_style = None yield ( elements.syllable(letters, span_style, whitespace_style), starts_word, ends_word, ) starts_word = False else: mystyle = style(element) assert mystyle.display == "inline", ValueError( "Inline elements may not contain block elements.") for child in element: for syllable in syllables(child, mystyle): yield syllable
def words(text_elements): word = elements.word() for element in text_elements: if isinstance(element, xsc.Text): mystyle = None element = [ element, ] else: mystyle = style(element) for child in element: for (syllable, starts_word, ends_word,) in syllables( child, mystyle): if starts_word and len(word) > 0: word[-1]._whitespace_style = syllable._style yield word word = elements.word() word.append(syllable) if ends_word: yield word word = elements.word() if len(word) > 0: yield word
def boxes(element): current_text_elements = [] for child in element: if isinstance(child, xsc.Text) or style(child).display == "inline": current_text_elements.append(child) else: # It’s a block element if len(current_text_elements) > 0: yield paragraph(current_text_elements) current_text_elements = [] yield elements.box(boxes(child), style=style(child)) if len(current_text_elements) > 0: yield paragraph(current_text_elements)
serif_ff = font_family({"regular": serif_roman, "italic": serif_roman, "bold": serif_bold, "bold-italic": serif_bold}) verasans_text = text_style( { "font-family": sans_serif_ff, "font-size": 10, "font-weight": "normal", "text-style": "normal", "line-height": 14, "kerning": True, "char-spacing": 0, "color": colors.black, "hyphenator": None, }, name="verasans text", ) veraserif_text = verasans_text + {"font-family": serif_ff} veraserif_text.set_name("veraserif text") box = style({"margin": (0, 0, 0, 0), "padding": (0, 0, 0, 0), "background": backgrounds.none()}, name="null box") paragraph = style({"list-style": lists.none(), "text-align": "left"}, name="left") verasans = verasans_text + box + paragraph verasans.set_name("verasans") veraserif = veraserif_text + box + paragraph veraserif.set_name("veraserif")
sans_serif_ff = font_family({ "regular": sansserif, "italic": sansserif_oblique, "bold": sansserif_bold, "bold-italic": sansserif_boldoblique }) serif_ff = font_family({ "regular": serif_roman, "italic": serif_italic, "bold": serif_bold, "bold-italic": serif_bolditalic }) sans_serif_text = style({ "font-family": sans_serif_ff, "font-size": 10, "font-weight": "normal", "text-style": "normal", "line-height": 12.5, "kerning": True, "char-spacing": 0, "color": colors.black, "hyphenator": None, }, name="cmuss") serif_text = sans_serif_text + {"font-family": serif_ff} box = style({ "margin": (0, 0, 0, 0), "padding": (0, 0, 0, 0), "background": backgrounds.none() }, name="null box") paragraph = style({"list-style": lists.none(), "text-align": "left",}, name="left")
def convert(element, styles={}): """ Convert the XIST DOM tree referenced by `frag` to a engine_two.model-tree that can be rendered to PostScript using the engine. The style provided for `element`s tag in `styles` must be complete. It will be passed to the returned elements.richtext object. """ # Fill in the gaps in the styles dict. styles = copy.copy(styles) for tag, style in default_styles.iteritems(): if styles.has_key(tag): styles[tag] = default_styles[tag] + styles[tag] styles[tag].set_name("usr" + tag.upper()) else: styles[tag] = default_styles[tag] def style(element): """ Return the style from the `styles` parameter keyd to `element` by its class name, i.e. its HTML tag. """ return styles[element.__class__.__name__] def boxes(element): current_text_elements = [] for child in element: if isinstance(child, xsc.Text) or style(child).display == "inline": current_text_elements.append(child) else: # It’s a block element if len(current_text_elements) > 0: yield paragraph(current_text_elements) current_text_elements = [] yield elements.box(boxes(child), style=style(child)) if len(current_text_elements) > 0: yield paragraph(current_text_elements) def paragraph(text_elements): return elements.paragraph(words(text_elements)) def words(text_elements): word = elements.word() for element in text_elements: if isinstance(element, xsc.Text): mystyle = None element = [ element, ] else: mystyle = style(element) for child in element: for (syllable, starts_word, ends_word,) in syllables( child, mystyle): if starts_word and len(word) > 0: word[-1]._whitespace_style = syllable._style yield word word = elements.word() word.append(syllable) if ends_word: yield word word = elements.word() if len(word) > 0: yield word word_re = re.compile(r"(\S+)(\s*)") starts_word_re = re.compile(r"^\s+") def syllables(element, span_style=None): if isinstance(element, xsc.Text): u = element.__unicode__() match = starts_word_re.search(u) starts_word = (match is not None) for letters, whitespace in word_re.findall(u): ends_word = ( whitespace != u"" ) if ends_word: whitespace_style = span_style else: whitespace_style = None yield ( elements.syllable(letters, span_style, whitespace_style), starts_word, ends_word, ) starts_word = False else: mystyle = style(element) assert mystyle.display == "inline", ValueError( "Inline elements may not contain block elements.") for child in element: for syllable in syllables(child, mystyle): yield syllable return elements.richtext(boxes(element), style=style(element))
if __name__ == "__main__": import sys, os, os.path as op from t4.psg.document.dsc import dsc_document from t4.psg.util import * import t4.psg.drawing.box from t4.psg.drawing.engine_two.styles import lists from t4.psg.drawing.engine_two.styles.bitstream_vera import verasans as sans #from t4.psg.drawing.engine_two.styles.computer_modern import cmu_sans_serif as sans from t4.psg.util.colors import red from t4.psg.drawing.engine_two.styles import style from t4.psg.drawing.engine_two.processors import render_to_filename base = sans + style({"hyphenator": hyphenator.hyphenator("en_US"), "text-align": "justified", "margin": (0, 0, 4, 0)}, name="base") styles = { "document": base, "h1": style({"font-size": 18, "line-height": 22, "font-weight": "bold", "text-align": "left", "margin": (0, 0, 5, 0)}, name="h1"), "h2": style({"font-size": 14, "line-height": 18, "font-weight": "bold", "text-align": "left", "margin": (9, 0, 4, 0)}, name="h2"),