Exemple #1
0
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"])
Exemple #2
0
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))