def convert(source, styles): """ Convert `source`, a unicode string formatted as describe in the module docstring, to a engine_two.model-tree that can be rendered to PostScript using the engine. """ return elements.richtext(boxes(source, styles), style=styles["document"])
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))