Paragraph Support
This commit is contained in:
parent
98ed90a9bc
commit
f60e209073
2 changed files with 136 additions and 60 deletions
|
@ -31,6 +31,9 @@ data Inline : Type where
|
||||||
|
|
||||||
public export
|
public export
|
||||||
data Block : Type where
|
data Block : Type where
|
||||||
|
Paragraph : (contents : List1 Inline) -> Block
|
||||||
|
|
||||||
|
%runElab derive "Block" [Show, Eq]
|
||||||
|
|
||||||
--*****************************************
|
--*****************************************
|
||||||
--* Character Classes and String Escaping *
|
--* Character Classes and String Escaping *
|
||||||
|
@ -83,9 +86,12 @@ escapedChar = do
|
||||||
-- Line Qualifying And Whitespace --
|
-- Line Qualifying And Whitespace --
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
space : PS Char
|
||||||
|
space = theseChars horizontalWhitespaceChars
|
||||||
|
|
||||||
spaces : PS Nat
|
spaces : PS Nat
|
||||||
spaces = do
|
spaces = do
|
||||||
xs <- many $ theseChars horizontalWhitespaceChars
|
xs <- many space
|
||||||
pure $ length xs
|
pure $ length xs
|
||||||
|
|
||||||
nonTerminal : PS Char
|
nonTerminal : PS Char
|
||||||
|
@ -106,7 +112,7 @@ terminal = do
|
||||||
line : PS (List Char)
|
line : PS (List Char)
|
||||||
line = do
|
line = do
|
||||||
cs <- many nonTerminal
|
cs <- many nonTerminal
|
||||||
terminal
|
_ <- lineEnding
|
||||||
pure cs
|
pure cs
|
||||||
|
|
||||||
isHorizontalWhitespace : Char -> Bool
|
isHorizontalWhitespace : Char -> Bool
|
||||||
|
@ -119,12 +125,26 @@ blankLine = do
|
||||||
False => throw "nonblank line"
|
False => throw "nonblank line"
|
||||||
True => pure cs
|
True => pure cs
|
||||||
|
|
||||||
|
blankLineOrEnd : PS ()
|
||||||
|
blankLineOrEnd = do
|
||||||
|
Nothing <- tryMaybe blankLine
|
||||||
|
| Just _ => pure ()
|
||||||
|
eof <- parseEoF
|
||||||
|
case eof of
|
||||||
|
False => throw "Expected newline or end of document"
|
||||||
|
True => pure ()
|
||||||
|
|
||||||
|
blankLines : PS ()
|
||||||
|
blankLines = do
|
||||||
|
xs <- many blankLine
|
||||||
|
if length xs > 0
|
||||||
|
then pure ()
|
||||||
|
else blankLineOrEnd
|
||||||
|
|
||||||
--*****************************************
|
--*****************************************
|
||||||
--* Inline syntax *
|
--* Inline syntax *
|
||||||
--*****************************************
|
--*****************************************
|
||||||
|
|
||||||
inlineElement : PS Inline
|
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
-- Escaped Whitespace --
|
-- Escaped Whitespace --
|
||||||
------------------------
|
------------------------
|
||||||
|
@ -176,34 +196,52 @@ text = do
|
||||||
-- Overall Inline Parser --
|
-- Overall Inline Parser --
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
inlineElement = oneOfE "" [
|
inlineElementsNoNewlines : PS Inline
|
||||||
hardLineBreak
|
inlineElementsNoNewlines = oneOfE "" [
|
||||||
, nbsp
|
nbsp
|
||||||
, escapedText
|
, escapedText
|
||||||
, softLineBreak
|
|
||||||
-- Text is last so that anything can superseed it
|
-- Text is last so that anything can superseed it
|
||||||
, text
|
, text
|
||||||
]
|
]
|
||||||
|
|
||||||
|
inlineElement : PS Inline
|
||||||
|
inlineElement = oneOfE "" [
|
||||||
|
hardLineBreak
|
||||||
|
, softLineBreak
|
||||||
|
, inlineElementsNoNewlines
|
||||||
|
]
|
||||||
|
|
||||||
inline : PS (List1 Inline)
|
inline : PS (List1 Inline)
|
||||||
inline = atLeastOne "Expected Inline Content" inlineElement
|
inline = atLeastOne "Expected Inline Content" inlineElement
|
||||||
|
|
||||||
|
|
||||||
--*****************************************
|
--*****************************************
|
||||||
--* Utility Functions *
|
--* Block Syntax *
|
||||||
--*****************************************
|
--*****************************************
|
||||||
|
|
||||||
------------------
|
---------------
|
||||||
-- Constructors --
|
-- Paragraph --
|
||||||
------------------
|
---------------
|
||||||
|
|
||||||
namespace Inline
|
paragraph : PS Block
|
||||||
export
|
paragraph = do
|
||||||
fromString : String -> List (Inline)
|
inlines <- inline
|
||||||
fromString str with (asList str)
|
blankLineOrEnd
|
||||||
fromString "" | [] = []
|
pure $ Paragraph inlines
|
||||||
fromString (strCons c str) | (c :: x) =
|
|
||||||
Text c :: fromString str | x
|
--------------------------
|
||||||
|
-- Overall Block Parser --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
block : PS Block
|
||||||
|
block = do
|
||||||
|
-- eat up any blank lines
|
||||||
|
_ <- many blankLine
|
||||||
|
oneOfE "" [
|
||||||
|
paragraph
|
||||||
|
]
|
||||||
|
|
||||||
|
blocks : PS (List Block)
|
||||||
|
blocks = many block
|
||||||
|
|
||||||
--*****************************************
|
--*****************************************
|
||||||
--* Unit Tests *
|
--* Unit Tests *
|
||||||
|
@ -228,6 +266,18 @@ golden input ref parser = do
|
||||||
putStrLn "Output: \{show x}"
|
putStrLn "Output: \{show x}"
|
||||||
pure $ x == ref
|
pure $ x == ref
|
||||||
|
|
||||||
|
inlineFromString : String -> List (Inline)
|
||||||
|
inlineFromString str with (asList str)
|
||||||
|
inlineFromString "" | [] = []
|
||||||
|
inlineFromString (strCons c str) | (c :: x) =
|
||||||
|
Text c :: inlineFromString str | x
|
||||||
|
|
||||||
|
inlineFromString' : String -> List1 (Inline)
|
||||||
|
inlineFromString' str =
|
||||||
|
case inlineFromString str of
|
||||||
|
[] => assert_total $ idris_crash "Bad unit test fromString"
|
||||||
|
(x :: xs) => x ::: xs
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
-- Inline Syntax Tests --
|
-- Inline Syntax Tests --
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -242,26 +292,47 @@ inlineTextSmoke =
|
||||||
inlineEscapedSmoke : IO Bool
|
inlineEscapedSmoke : IO Bool
|
||||||
inlineEscapedSmoke =
|
inlineEscapedSmoke =
|
||||||
let input = "Hello\\n\\*World"
|
let input = "Hello\\n\\*World"
|
||||||
ref = fromString "Hello" ++ [Text '\n', Text '*'] ++ fromString "World"
|
ref = inlineFromString "Hello" ++ [Text '\n', Text '*'] ++ inlineFromString "World"
|
||||||
in golden input ref (map forget inline)
|
in golden input ref (map forget inline)
|
||||||
|
|
||||||
-- @@test Hard Line Break
|
-- @@test Hard Line Break
|
||||||
inlineHardBreakSmoke : IO Bool
|
inlineHardBreakSmoke : IO Bool
|
||||||
inlineHardBreakSmoke =
|
inlineHardBreakSmoke =
|
||||||
let input = "Hello\\\nWorld"
|
let input = "Hello\\\nWorld"
|
||||||
ref = fromString "Hello" ++ [HardLineBreak] ++ fromString "World"
|
ref = inlineFromString "Hello" ++ [HardLineBreak] ++ inlineFromString "World"
|
||||||
in golden input ref (map forget inline)
|
in golden input ref (map forget inline)
|
||||||
|
|
||||||
-- @@test Soft Line Break
|
-- @@test Soft Line Break
|
||||||
inlineSoftBreakSmoke : IO Bool
|
inlineSoftBreakSmoke : IO Bool
|
||||||
inlineSoftBreakSmoke =
|
inlineSoftBreakSmoke =
|
||||||
let input = "Hello\nWorld"
|
let input = "Hello\nWorld"
|
||||||
ref = fromString "Hello" ++ [SoftLineBreak] ++ fromString "World"
|
ref = inlineFromString "Hello" ++ [SoftLineBreak] ++ inlineFromString "World"
|
||||||
in golden input ref (map forget inline)
|
in golden input ref (map forget inline)
|
||||||
|
|
||||||
-- @@test Nonbreaking Space
|
-- @@test Nonbreaking Space
|
||||||
inlineNbspSmoke : IO Bool
|
inlineNbspSmoke : IO Bool
|
||||||
inlineNbspSmoke =
|
inlineNbspSmoke =
|
||||||
let input = "Hello\\ World"
|
let input = "Hello\\ World"
|
||||||
ref = fromString "Hello" ++ [NonBreakingSpace] ++ fromString "World"
|
ref = inlineFromString "Hello" ++ [NonBreakingSpace] ++ inlineFromString "World"
|
||||||
in golden input ref (map forget inline)
|
in golden input ref (map forget inline)
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
-- Block Syntax Tests --
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
-- @@test Paragraph
|
||||||
|
blockParagraphSmoke : IO Bool
|
||||||
|
blockParagraphSmoke =
|
||||||
|
let input = "Hello World"
|
||||||
|
ref = [Paragraph (inlineFromString' "Hello World")]
|
||||||
|
in golden input ref blocks
|
||||||
|
|
||||||
|
-- @@test Two Paragraph
|
||||||
|
blockTwoParagraphSmoke : IO Bool
|
||||||
|
blockTwoParagraphSmoke =
|
||||||
|
let input = "Hello World\n\nHello Again"
|
||||||
|
ref = [
|
||||||
|
Paragraph (inlineFromString' "Hello World")
|
||||||
|
, Paragraph (inlineFromString' "Hello Again")
|
||||||
|
]
|
||||||
|
in golden input ref blocks
|
||||||
|
|
77
todo.org
77
todo.org
|
@ -8,45 +8,50 @@ Decided to rename =Tag= to =Html=, and =Raw= to =Text=, which makes this make se
|
||||||
** TODO Refine =location= in =ParserLocation=
|
** TODO Refine =location= in =ParserLocation=
|
||||||
** TODO Error messages
|
** TODO Error messages
|
||||||
** TODO Combinators for predictive parsing
|
** TODO Combinators for predictive parsing
|
||||||
* Djot [2/40]
|
* Djot [3/42]
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:COOKIE_DATA: recursive
|
:COOKIE_DATA: recursive
|
||||||
:END:
|
:END:
|
||||||
** Inline Syntax [2/18]
|
** Parsing
|
||||||
*** DONE Ordinary Text
|
*** Inline Syntax [2/18]
|
||||||
*** TODO Link
|
**** DONE Ordinary Text
|
||||||
*** TODO Image
|
**** TODO Link
|
||||||
*** TODO Autolink
|
**** TODO Image
|
||||||
*** TODO Verbatim
|
**** TODO Autolink
|
||||||
*** TODO Emphasis/strong
|
**** TODO Verbatim
|
||||||
*** TODO Highlighted
|
**** TODO Emphasis/strong
|
||||||
*** TODO Super/subscript
|
**** TODO Highlighted
|
||||||
*** TODO Insert/delete
|
**** TODO Super/subscript
|
||||||
*** TODO Smart punctuation
|
**** TODO Insert/delete
|
||||||
*** TODO Math
|
**** TODO Smart punctuation
|
||||||
*** TODO Footnote reference
|
**** TODO Math
|
||||||
*** DONE Linebreak
|
**** TODO Footnote reference
|
||||||
*** TODO Comment
|
**** DONE Linebreak
|
||||||
*** TODO Symbols
|
**** TODO Comment
|
||||||
*** TODO Raw inline
|
**** TODO Symbols
|
||||||
*** TODO Span
|
**** TODO Raw inline
|
||||||
*** TODO Inline attributes
|
**** TODO Span
|
||||||
** Block Syntax [0/15]
|
**** TODO Inline attributes
|
||||||
*** TODO Paragraph
|
*** Block Syntax [1/16]
|
||||||
*** TODO Heading
|
**** DONE Paragraph
|
||||||
*** TODO Block quote
|
**** Heading
|
||||||
*** TODO List item
|
***** TODO Multiline without leading count
|
||||||
*** TODO List
|
***** TODO Basic
|
||||||
*** TODO Code block
|
**** TODO Block quote
|
||||||
*** TODO Thematic break
|
**** TODO List item
|
||||||
*** TODO Raw block
|
**** TODO List
|
||||||
*** TODO Div
|
**** TODO Code block
|
||||||
*** TODO Pipe table
|
**** TODO Thematic break
|
||||||
*** TODO Reference link
|
**** TODO Raw block
|
||||||
*** TODO definition
|
**** TODO Div
|
||||||
*** TODO Footnote
|
**** TODO Pipe table
|
||||||
*** TODO Block attributes
|
**** TODO Reference link
|
||||||
*** TODO Links to headings
|
**** TODO definition
|
||||||
|
**** TODO Footnote
|
||||||
|
**** TODO Block attributes
|
||||||
|
**** TODO Links to headings
|
||||||
|
** TODO Rendering
|
||||||
|
** Bugs [0/0]
|
||||||
** TODO Predictive parsing
|
** TODO Predictive parsing
|
||||||
** TODO Support all types of whitespace
|
** TODO Support all types of whitespace
|
||||||
*** TODO Escaping
|
*** TODO Escaping
|
||||||
|
|
Loading…
Add table
Reference in a new issue