pylatexenc/latex2text.py
def node_to_text(self, node, prev_node_hint=None):
        """
        Return the textual representation of the given `node`.

        If `prev_node_hint` is specified, then the current node is formatted
        suitably as following the node given in `prev_node_hint`.  This might
        affect how much space we keep/discard, etc.
        """
        if node is None:
            return ""
        
        if node.isNodeType(latexwalker.LatexCharsNode):
            # Unless in strict latex spaces mode, ignore nodes consisting only
            # of empty chars, as this tends to produce too much space...  These
            # have been inserted by LatexWalker() in some occasions to keep
            # track of all relevant pre_space of tokens, such as between two
            # braced groups ("{one} {two}") or other such situations.
            if not self.strict_latex_spaces['between-latex-constructs'] and len(node.chars.strip()) == 0:
                return ""
            return node.chars
        
        if node.isNodeType(latexwalker.LatexCommentNode):
            if self.keep_comments:
                if self.strict_latex_spaces['after-comment']:
                    return '%' + node.comment + '\n'
                else:
                    # default spaces, i.e., keep what spaces were already there after the comment
                    return '%' + node.comment + node.comment_post_space
            else:
                if self.strict_latex_spaces['after-comment']:
                    return ""
                else:
                    # default spaces, i.e., keep what spaces were already there after the comment
                    # This can be useful to preserve e.g. indentation of the next line
                    return node.comment_post_space
        
        if node.isNodeType(latexwalker.LatexGroupNode):
            contents = self._groupnodecontents_to_text(node)
            if self.keep_braced_groups and len(contents) >= self.keep_braced_groups_minlen:
                return "{" + contents + "}"
            return contents

        def apply_simplify_repl(node, simplify_repl, nodelistargs, what):
            if callable(simplify_repl):
                if 'l2tobj' in getfullargspec(simplify_repl)[0]:
                    # callable accepts an argument named 'l2tobj', provide pointer to self
                    return simplify_repl(node, l2tobj=self)
                return simplify_repl(node)
            if '%' in simplify_repl:
                try:
                    return simplify_repl % tuple([self._groupnodecontents_to_text(nn)
                                                  for nn in nodelistargs])
                except (TypeError, ValueError):
                    logger.warning(
                        "WARNING: Error in configuration: {} failed its substitution!".format(what)
                    )
                    return simplify_repl # too bad, keep the percent signs as they are...
            return simplify_repl
            
        
        if node.isNodeType(latexwalker.LatexMacroNode):
            # get macro behavior definition.
            macroname = node.macroname.rstrip('*')
            if macroname in self.macro_dict:
                mac = self.macro_dict[macroname]
            else:
                # no predefined behavior, use default:
                mac = self.macro_dict['']

            def get_macro_str_repl(node, macroname, mac):
                if mac.simplify_repl:
                    return apply_simplify_repl(node, mac.simplify_repl, node.nodeargs,
                                               what="macro '%s'"%(macroname))
                if mac.discard:
                    return ""
                a = node.nodeargs
                if (node.nodeoptarg):
                    a.prepend(node.nodeoptarg)
                return "".join([self._groupnodecontents_to_text(n) for n in a])

            macrostr = get_macro_str_repl(node, macroname, mac)
            return macrostr

        if node.isNodeType(latexwalker.LatexEnvironmentNode):
            # get environment behavior definition.
            envname = node.envname.rstrip('*')
            if (envname in self.env_dict):
                envdef = self.env_dict[envname]
            else:
                # no predefined behavior, use default:
                envdef = self.env_dict['']

            if envdef.simplify_repl:
                return apply_simplify_repl(node, envdef.simplify_repl, node.nodelist,
                                           what="environment '%s'"%(envname))
            if envdef.discard:
                return ""
            return self._nodelistcontents_to_text(node.nodelist)

        if node.isNodeType(latexwalker.LatexMathNode):
            if self.keep_inline_math:
                # we care about math modes and we should keep this verbatim
                return latexwalker.math_node_to_latex(node)
            else:
                # note, this here only happens if the latexwalker had keep_inline_math=True
                with _PushEquationContext(self):
                    return self._nodelistcontents_to_text(node.nodelist)

        logger.warning("LatexNodes2Text.node_to_text(): Unknown node: %r", node)

        # discard anything else.
        return ""
def node_to_text(self, node, prev_node_hint=None):
        """
        Return the textual representation of the given `node`.

        If `prev_node_hint` is specified, then the current node is formatted
        suitably as following the node given in `prev_node_hint`.  This might
        affect how much space we keep/discard, etc.
        """
        if node is None:
            return ""
        
        if node.isNodeType(latexwalker.LatexCharsNode):
            # Unless in strict latex spaces mode, ignore nodes consisting only
            # of empty chars, as this tends to produce too much space...  These
            # have been inserted by LatexWalker() in some occasions to keep
            # track of all relevant pre_space of tokens, such as between two
            # braced groups ("{one} {two}") or other such situations.
            if not self.strict_latex_spaces['between-latex-constructs'] and len(node.chars.strip()) == 0:
                return ""
            return node.chars
        
        if node.isNodeType(latexwalker.LatexCommentNode):
            if self.keep_comments:
                if self.strict_latex_spaces['after-comment']:
                    return '%' + node.comment + '\n'
                else:
                    # default spaces, i.e., keep what spaces were already there after the comment
                    return '%' + node.comment + node.comment_post_space
            else:
                if self.strict_latex_spaces['after-comment']:
                    return ""
                else:
                    # default spaces, i.e., keep what spaces were already there after the comment
                    # This can be useful to preserve e.g. indentation of the next line
                    return node.comment_post_space
        
        if node.isNodeType(latexwalker.LatexGroupNode):
            contents = self._groupnodecontents_to_text(node)
            if self.keep_braced_groups and len(contents) >= self.keep_braced_groups_minlen:
                return "{" + contents + "}"
            return contents

        def apply_simplify_repl(node, simplify_repl, nodelistargs, what):
            if callable(simplify_repl):
                if 'l2tobj' in getfullargspec(simplify_repl)[0]:
                    # callable accepts an argument named 'l2tobj', provide pointer to self
                    return simplify_repl(node, l2tobj=self)
                return simplify_repl(node)
            if '%' in simplify_repl:
                try:
                    return simplify_repl % tuple([self._groupnodecontents_to_text(nn)
                                                  for nn in nodelistargs])
                except (TypeError, ValueError):
                    logger.warning(
                        "WARNING: Error in configuration: {} failed its substitution!".format(what)
                    )
                    return simplify_repl # too bad, keep the percent signs as they are...
            return simplify_repl
            
        
        if node.isNodeType(latexwalker.LatexMacroNode):
            # get macro behavior definition.
            macroname = node.macroname.rstrip('*')
            if macroname in self.macro_dict:
                mac = self.macro_dict[macroname]
            else:
                # no predefined behavior, use default:
                mac = self.macro_dict['']

            def get_macro_str_repl(node, macroname, mac):
                if mac.simplify_repl:
                    return apply_simplify_repl(node, mac.simplify_repl, node.nodeargs,
                                               what="macro '%s'"%(macroname))
                if mac.discard:
                    return ""
                a = node.nodeargs
                if (node.nodeoptarg):
                    a.prepend(node.nodeoptarg)
                return "".join([self._groupnodecontents_to_text(n) for n in a])

            macrostr = get_macro_str_repl(node, macroname, mac)
            return macrostr

        if node.isNodeType(latexwalker.LatexEnvironmentNode):
            # get environment behavior definition.
            envname = node.envname.rstrip('*')
            if (envname in self.env_dict):
                envdef = self.env_dict[envname]
            else:
                # no predefined behavior, use default:
                envdef = self.env_dict['']

            if envdef.simplify_repl:
                return apply_simplify_repl(node, envdef.simplify_repl, node.nodelist,
                                           what="environment '%s'"%(envname))
            if envdef.discard:
                return ""
            return self._nodelistcontents_to_text(node.nodelist)

        if node.isNodeType(latexwalker.LatexMathNode):
            if self.keep_inline_math:
                # we care about math modes and we should keep this verbatim
                return latexwalker.math_node_to_latex(node)
            else:
                # note, this here only happens if the latexwalker had keep_inline_math=True
                with _PushEquationContext(self):
                    return self._nodelistcontents_to_text(node.nodelist)

        logger.warning("LatexNodes2Text.node_to_text(): Unknown node: %r", node)

        # discard anything else.
        return ""
Return the textual representation of the given `node`.

        If `prev_node_hint` is specified, then the current node is formatted
        suitably as following the node given in `prev_node_hint`.  This might
        affect how much space we keep/discard, etc.