@@ -117,6 +117,8 @@ function lexnext(state::LexerState, bytes::DenseVector{UInt8}, start::UInt32)::T
117117 lex_comment(state, bytes, pos)
118118 elseif chr == UInt8(' -' ) && ischarat(bytes, pos + 0x1 , ' -' )
119119 lex_hrule(state, bytes, pos)
120+ elseif chr == UInt8(' \\ ' ) && hasprefix(bytes, pos + 0x1 , " begin{" )
121+ lex_latexenv(state, bytes, pos)
120122 elseif K" heading" ∈ state. lastelement
121123 lex_planning(state, bytes, pos)
122124 else
@@ -458,7 +460,33 @@ function lex_hrule(::LexerState, bytes::DenseVector{UInt8}, pos::UInt32)
458460 Token(K" hrule" , pos, rend - 0x1 ), lend
459461end
460462
461- # TODO : LaTeX environments
463+ function lex_latexenv(:: LexerState , bytes:: DenseVector{UInt8} , start:: UInt32 )
464+ hasprefix(bytes, start, " \\ begin{" ) || return NONE_TOKEN
465+ namestart = start + ncodeunits(" \\ begin{" ) % UInt32
466+ nameend = skipcharsets(bytes, namestart, (' a' :' z' , ' A' :' Z' , ' 0' :' 9' , ' *' ))
467+ nameend < length(bytes) && bytes[nameend] == UInt8(' }' ) || return NONE_TOKEN
468+ namelen = nameend - namestart
469+ pos = start
470+ while pos <= length(bytes)
471+ pos = lineend(bytes, pos) + 0x1
472+ pos = skipspaces(bytes, pos). stop
473+ hasprefix(bytes, pos, " \\ end{" ) || continue
474+ pos += ncodeunits(" \\ end{" ) % UInt32
475+ pos + namelen < length(bytes) || return NONE_TOKEN
476+ namematch = true
477+ for offset in 0 : namelen- 0x1
478+ if bytes[namestart + offset] != bytes[pos + offset]
479+ namematch = false
480+ break
481+ end
482+ end
483+ namematch && bytes[pos + namelen] == UInt8(' }' ) || continue
484+ islineend(bytes, skipspaces(bytes, pos + namelen + 0x1 ). stop) ||
485+ return NONE_TOKEN
486+ return Token(K" latex_environment" , start, pos + namelen), lineend(bytes, pos)
487+ end
488+ NONE_TOKEN
489+ end
462490
463491# TODO : Paragraphs
464492
0 commit comments