[parsing/mfm] Optimize restOfLineContains case for single char, remove unnecessary pushLine/assertLine calls
This commit is contained in:
parent
92c6e01988
commit
bd56788542
1 changed files with 23 additions and 17 deletions
|
@ -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 =
|
||||||
|
|
Loading…
Add table
Reference in a new issue