[parsing/mfm] Optimize restOfLineContains case for single char, remove unnecessary pushLine/assertLine calls

This commit is contained in:
Laura Hausmann 2024-11-27 04:25:56 +01:00
parent 92c6e01988
commit bd56788542
No known key found for this signature in database
GPG key ID: D044E84C5BE01605

View file

@ -261,6 +261,20 @@ module private MfmParser =
| c when c.Contains(s) -> Reply(()) | c when c.Contains(s) -> Reply(())
| _ -> Reply(Error, error) | _ -> Reply(Error, error)
let restOfLineContainsChar (c: char) : Parser<unit, UserState> =
let error = messageError "No match found"
let func ch = ch <> c && isNotNewline ch
fun (stream: CharStream<_>) ->
let pos = stream.Position
let _ = stream.SkipCharsOrNewlinesWhile(func)
let ch = stream.Read()
do stream.Seek pos.Index
match ch with
| m when m = c -> Reply(())
| _ -> Reply(Error, error)
let restOfSegmentContains (s: string, segment: char -> bool) : Parser<unit, UserState> = let restOfSegmentContains (s: string, segment: char -> bool) : Parser<unit, UserState> =
let error = messageError "No match found" let error = messageError "No match found"
@ -329,19 +343,19 @@ module private MfmParser =
let italicAsteriskNode = let italicAsteriskNode =
previousCharSatisfiesNot isNotWhitespace previousCharSatisfiesNot isNotWhitespace
>>. italicPatternAsterisk >>. italicPatternAsterisk
>>. restOfLineContains "*" >>. restOfLineContainsChar '*' // TODO: this doesn't cover the case where a bold node ends before the italic one
>>. pushLine >>. pushLine // Remove when above TODO is resolved
>>. manyInlineNodesTill italicPatternAsterisk >>. manyInlineNodesTill italicPatternAsterisk
.>> assertLine .>> assertLine // Remove when above TODO is resolved
|>> fun c -> MfmItalicNode(aggregateTextInline c, Symbol) :> MfmNode |>> fun c -> MfmItalicNode(aggregateTextInline c, Symbol) :> MfmNode
let italicUnderscoreNode = let italicUnderscoreNode =
previousCharSatisfiesNot isNotWhitespace previousCharSatisfiesNot isNotWhitespace
>>. italicPatternUnderscore >>. italicPatternUnderscore
>>. restOfLineContains "_" >>. restOfLineContainsChar '_' // TODO: this doesn't cover the case where a bold node ends before the italic one
>>. pushLine >>. pushLine // Remove when above TODO is resolved
>>. manyInlineNodesTill italicPatternUnderscore >>. manyInlineNodesTill italicPatternUnderscore
.>> assertLine .>> assertLine // Remove when above TODO is resolved
|>> fun c -> MfmItalicNode(aggregateTextInline c, Symbol) :> MfmNode |>> fun c -> MfmItalicNode(aggregateTextInline c, Symbol) :> MfmNode
let italicTagNode = let italicTagNode =
@ -354,18 +368,14 @@ module private MfmParser =
previousCharSatisfiesNot isNotWhitespace previousCharSatisfiesNot isNotWhitespace
>>. skipString "**" >>. skipString "**"
>>. restOfLineContains "**" >>. restOfLineContains "**"
>>. pushLine
>>. manyInlineNodesTill (skipString "**") >>. manyInlineNodesTill (skipString "**")
.>> assertLine
|>> fun c -> MfmBoldNode(aggregateTextInline c, Symbol) :> MfmNode |>> fun c -> MfmBoldNode(aggregateTextInline c, Symbol) :> MfmNode
let boldUnderscoreNode = let boldUnderscoreNode =
previousCharSatisfiesNot isNotWhitespace previousCharSatisfiesNot isNotWhitespace
>>. skipString "__" >>. skipString "__"
>>. restOfLineContains "__" >>. restOfLineContains "__"
>>. pushLine
>>. manyInlineNodesTill (skipString "__") >>. manyInlineNodesTill (skipString "__")
.>> assertLine
|>> fun c -> MfmBoldNode(aggregateTextInline c, Symbol) :> MfmNode |>> fun c -> MfmBoldNode(aggregateTextInline c, Symbol) :> MfmNode
let boldTagNode = let boldTagNode =
@ -377,9 +387,7 @@ module private MfmParser =
let strikeNode = let strikeNode =
skipString "~~" skipString "~~"
>>. restOfLineContains "~~" >>. restOfLineContains "~~"
>>. pushLine
>>. manyInlineNodesTill (skipString "~~") >>. manyInlineNodesTill (skipString "~~")
.>> assertLine
|>> fun c -> MfmStrikeNode(aggregateTextInline c, Symbol) :> MfmNode |>> fun c -> MfmStrikeNode(aggregateTextInline c, Symbol) :> MfmNode
let strikeTagNode = let strikeTagNode =
@ -390,10 +398,10 @@ module private MfmParser =
let codeNode = let codeNode =
codePattern codePattern
>>. restOfLineContains "`" >>. restOfLineContainsChar '`' // TODO: this doesn't cover the case where a code block node ends before the inline one
>>. pushLine >>. pushLine // Remove when above TODO is resolved
>>. manyCharsTill anyChar codePattern >>. manyCharsTill anyChar codePattern
.>> assertLine .>> assertLine // Remove when above TODO is resolved
|>> fun v -> MfmInlineCodeNode(v) :> MfmNode |>> fun v -> MfmInlineCodeNode(v) :> MfmNode
let codeBlockNode = let codeBlockNode =
@ -413,9 +421,7 @@ module private MfmParser =
let mathNode = let mathNode =
skipString "\(" skipString "\("
>>. restOfLineContains "\)" >>. restOfLineContains "\)"
>>. pushLine
>>. manyCharsTill anyChar (skipString "\)") >>. manyCharsTill anyChar (skipString "\)")
.>> assertLine
|>> fun f -> MfmMathInlineNode(f) :> MfmNode |>> fun f -> MfmMathInlineNode(f) :> MfmNode
let mathBlockNode = let mathBlockNode =