def unclosed_env_handler(src, expr, end): """Handle unclosed environments. Currently raises an end-of-file error. In the future, this can be the hub for unclosed-environment fault tolerance. :param Buffer src: a buffer of tokens :param TexExpr expr: expression for the environment :param int tolerance: error tolerance level (only supports 0 or 1) :param end str: Actual end token (as opposed to expected) """ clo = CharToLineOffset(str(src)) explanation = 'Instead got %s' % end if end else 'Reached end of file.' line, offset = clo(src.position) raise EOFError('[Line: %d, Offset: %d] "%s" env expecting %s. %s' % (line, offset, expr.name, expr.end, explanation))
def __init__(self, expr, src=None): """Creates TexNode object. :param TexExpr expr: a LaTeX expression, either a singleton command or an environment containing other commands :param str src: LaTeX source string """ assert isinstance(expr, TexExpr), \ 'Expression given to node must be a valid TexExpr' super().__init__() self.expr = expr self.parent = None if src is not None: self.char_to_line = CharToLineOffset(src) else: self.char_to_line = None
def read_arg(src, c, tolerance=0, mode=MODE_NON_MATH): r"""Read the argument from buffer. Advances buffer until right before the end of the argument. :param Buffer src: a buffer of tokens :param str c: argument token (starting token) :param int tolerance: error tolerance level (only supports 0 or 1) :param str mode: math or not math mode :return: the parsed argument :rtype: TexGroup >>> from TexSoup.category import categorize >>> from TexSoup.tokens import tokenize >>> s = r'''{\item\abovedisplayskip=2pt\abovedisplayshortskip=0pt~\vspace*{-\baselineskip}}''' >>> buf = tokenize(categorize(s)) >>> read_arg(buf, next(buf)) BraceGroup(TexCmd('item')) >>> buf = tokenize(categorize(r'{\incomplete! [complete]')) >>> read_arg(buf, next(buf), tolerance=1) BraceGroup(TexCmd('incomplete'), '! ', '[', 'complete', ']') """ content = [c] arg = ARG_BEGIN_TO_ENV[c.category] while src.hasNext(): if src.peek().category == arg.token_end: src.forward() return arg(*content[1:], position=c.position) else: content.append(read_expr(src, tolerance=tolerance, mode=mode)) if tolerance == 0: clo = CharToLineOffset(str(src)) line, offset = clo(c.position) raise TypeError( '[Line: %d, Offset %d] Malformed argument. First and last elements ' 'must match a valid argument format. In this case, TexSoup' ' could not find matching punctuation for: %s.\n' 'Just finished parsing: %s' % (line, offset, c, content)) return arg(*content[1:], position=c.position)