Recursively typeset the etree *node*, using a reference to element *e* or the cascading *style*. If *e* is None, then the tag style is merged on top of the doc.rootStyle. If *e* is defined, then rootstyle of the stack starts with an empty dictionary, leaving root searching
(self, node, e=None)
| 603 | return bs |
| 604 | |
| 605 | def typesetNode(self, node, e=None): |
| 606 | """Recursively typeset the etree *node*, using a reference to element |
| 607 | *e* or the cascading *style*. If *e* is None, then the tag style is |
| 608 | merged on top of the doc.rootStyle. If *e* is defined, then rootstyle |
| 609 | of the stack starts with an empty dictionary, leaving root searching |
| 610 | for the e.parent path.""" |
| 611 | |
| 612 | # Ignore <pre> tag output, as it is part of a ~~~Pyhton ... ~~~ code block |
| 613 | if self.writeTags and not node.tag in self.skipTags: |
| 614 | # Open the node in HTML export for this node |
| 615 | self.htmlNode(node) |
| 616 | |
| 617 | # Add this tag to the tag-history line. It is used to connect to the |
| 618 | # right style in case we are rendering towards a FormattedString or |
| 619 | # another context-equivalent. |
| 620 | self.addHistory(node.tag) |
| 621 | |
| 622 | # If e is undefined, then we make sure that the stack contains the doc.rootStyle on top. |
| 623 | # If e is defined then root queries for style should follow the e.parent path. |
| 624 | if self.peekStyle() is None and e is not None: |
| 625 | # Root of stack is empty style, to force searching on the e.parent line. |
| 626 | self.pushStyle({}) # Define top level for styles. |
| 627 | nodeStyle = self.getNodeStyle(node.tag) # Merge found tag style with current top of stack |
| 628 | self.pushStyle(nodeStyle) # Push this merged style on the stack |
| 629 | |
| 630 | # XML-nodes are organized as: node - node.text - node.children - |
| 631 | # node.tail If no text exists or if the node does not have tail text, |
| 632 | # these are None. Still we want to be able to add the prefix to the |
| 633 | # node.text, so then the text is changed to an empty string. |
| 634 | |
| 635 | nodeText = self._strip(node.text) |
| 636 | |
| 637 | if nodeText: # Not None and still has content after stripping? |
| 638 | # Don't cache the context from self.galley as variable, as it may |
| 639 | # become dynamically updated by code blocks. The galley context |
| 640 | # will define the type of BabelStrings generated by the Typesetter. |
| 641 | firstTagIndent = nodeStyle.get('firstTagIndent') |
| 642 | if firstTagIndent is not None and len(self.tagHistory) > 2 and self.tagHistory[-2] != '_'+node.tag: |
| 643 | nodeStyle['firstLineIndent'] = firstTagIndent |
| 644 | bs = self.context.newString(nodeText, nodeStyle) |
| 645 | self.append(bs) |
| 646 | |
| 647 | self.tagStack.append(node.tag) # Add current node to the stack |
| 648 | |
| 649 | # Type set all child node in the current node, by recursive call. |
| 650 | for child in node: |
| 651 | hook = 'node_'+child.tag |
| 652 | # Method will handle the styled body of the element, but not the |
| 653 | # tail. |
| 654 | if hasattr(self, hook): |
| 655 | # There is a hook for this node, let this method do the work. |
| 656 | getattr(self, hook)(child, e) # Hook must be able to derive styles from e. |
| 657 | # We are in tail mode now, but we don't know what happened in the child block. |
| 658 | else: |
| 659 | # If no method hook defined, then just solve recursively. Child node will get the style. |
| 660 | self.typesetNode(child, e) |
| 661 | |
| 662 | # XML-nodes are organized as: node - node.text - node.children - |
no test coverage detected