Test linebreaks and nbsps

This commit is contained in:
Nathan McCarty 2025-02-21 16:17:31 -05:00
parent 72b102d071
commit 85ead54619
7 changed files with 132 additions and 11 deletions

View file

@ -33,7 +33,6 @@ data Inline : Type where
-- Combine adjacent `Text`s in the parsed output
combineTexts : List1 Inline -> Eval (List1 Inline)
combineTexts xs@(Text c ::: []) = pure xs
combineTexts (Text c ::: (Text d :: xs)) =
combineTexts (Text (c ++ d) ::: xs)
combineTexts (x ::: tail) = do
@ -49,6 +48,23 @@ combineTexts (x ::: tail) = do
rest <- combineTexts' ys
pure $ y :: rest
-- Combine adjacent soft line breaks into one
combineSoftBreaks : List1 Inline -> Eval (List1 Inline)
combineSoftBreaks (SoftLineBreak ::: (SoftLineBreak :: xs)) =
combineSoftBreaks (SoftLineBreak ::: xs)
combineSoftBreaks (head ::: tail) = do
tail <- combineSoftBreaks' tail
pure $ head ::: tail
where
combineSoftBreaks' : List Inline -> Eval (List Inline)
combineSoftBreaks' [] = pure []
combineSoftBreaks' (x :: []) = pure [x]
combineSoftBreaks' (SoftLineBreak :: (SoftLineBreak :: xs)) =
combineSoftBreaks' (SoftLineBreak :: xs)
combineSoftBreaks' (x :: xs) = do
rest <- combineSoftBreaks' xs
pure $ x :: rest
-- Remove a trailing soft line break from a list of inlines
removeTrailingSoftBreak : List1 Inline -> Eval (List1 Inline)
removeTrailingSoftBreak (head ::: tail) = do
@ -66,6 +82,7 @@ removeTrailingSoftBreak (head ::: tail) = do
postProcess : List1 Inline -> List1 Inline
postProcess xs = eval $ do
xs <- combineTexts xs
xs <- combineSoftBreaks xs
xs <- removeTrailingSoftBreak xs
pure xs
@ -91,6 +108,8 @@ nbsp = do
softLineBreak : PS Inline
softLineBreak = do
-- Slurp up any horizontal whitespace before the line break
_ <- spaces
_ <- lineEnding
-- Check to see if the next line is empty, if it is, we are at the end of the inline
-- content, go ahead and bail
@ -98,6 +117,17 @@ softLineBreak = do
Nothing <- tryMaybe blankLine
| Just _ => throw "End of inline"
load state
-- Slurp up any horizontal whitespace after the line break
_ <- spaces
pure $ SoftLineBreak
escapedNewLine : PS Inline
escapedNewLine = do
-- Slurp up any horizontal whitespace before the line break
_ <- spaces
_ <- thisString "\\n"
-- Slurp up any horizontal whitespace after the line break
_ <- spaces
pure $ SoftLineBreak
---------------------
@ -124,19 +154,15 @@ text = do
-- Overall Inline Parser --
---------------------------
inlineElementsNoNewlines : PS Inline
inlineElementsNoNewlines = oneOfE "" [
nbsp
, escapedText
-- Text is last so that anything can superseed it
, text
]
inlineElement : PS Inline
inlineElement = oneOfE "" [
hardLineBreak
, softLineBreak
, inlineElementsNoNewlines
, escapedNewLine
, nbsp
, escapedText
-- Text is last so that anything can superseed it
, text
]
export

View file

@ -9,6 +9,7 @@ import Data.String
import Data.List1
import Data.List
import Control.Monad.Eval
import Structures.Dependent.DList
-- Maybe because specifically Soft line breaks don't generate any html of their
@ -24,10 +25,27 @@ renderInline NonBreakingSpace =
renderInline (Text c) =
Just (_ ** Text c)
combineTexts : (types : List String ** DList _ Html types)
-> Eval (types : List String ** DList _ Html types)
combineTexts (_ ** []) = pure (_ ** [])
-- We do a little bit of magic insert of whitespace, so we have some special handling for
-- nbsps to not insert spaces around them
combineTexts (_ ** (Text c :: Text "&nbsp;" :: Text "&nbsp;" :: rest)) =
combineTexts (_ ** Text (c ++ "&nbsp;") :: Text "&nbsp;" :: rest)
combineTexts (_ ** (Text c :: Text "&nbsp;" :: Text d :: rest)) =
combineTexts (_ ** Text (c ++ "&nbsp;" ++ d) :: rest)
combineTexts (_ ** (Text c :: Text "&nbsp;" :: rest)) =
combineTexts (_ ** Text (c ++ "&nbsp;") :: rest)
combineTexts (_ ** (Text c :: Text d :: rest)) =
combineTexts (_ ** Text (c ++ " " ++ d) :: rest)
combineTexts (_ ** (elem :: rest)) = do
(_ ** rest) <- combineTexts (_ ** rest)
pure $ (_ ** elem :: rest)
export
renderInlines : List Inline -> (types : List String ** DList _ Html types)
renderInlines xs =
fromList . catMaybes . map renderInline $ xs
eval . combineTexts . fromList . catMaybes . map renderInline $ xs
headingLevel : HeaderLevel -> (h : String ** IsNormal h)
headingLevel H1 = ("h1" ** IsH1)

View file

@ -0,0 +1,16 @@
module Main
import SSG.Djot
import SSG.HTML
import System
import System.File
main : IO ()
main = do
Right contents <- readFile "test.dj"
| Left err => do
printLn err
exitFailure
let parsed = djot contents
putStr . render . renderHtml $ parsed

View file

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html lang=en>
<body>
<p>A paragraph with a normal newline in the middle of it</p>
<p>
A paragraph with a hard line break
<br>
in the middle of it
</p>
<p>
A paragraph with a hard line break
<br>
in the middle of it with extra spaces
</p>
<p>
A paragraph with a hard line break
<br>
in the middle of it with no spaces
</p>
<p>A paragraph with an explicit soft line break in the middle of it</p>
<p>Multiple soft breaks should coalesce into one</p>
<p>Same should apply when mixing explicit and implied soft breaks</p>
<p>An escaped space&nbsp;should render as a nonbreaking space</p>
<p>We also want to test&nbsp;&nbsp;multiple&nbsp;&nbsp;&nbsp;nonbreaking&nbsp;&nbsp;&nbsp;&nbsp;spaces&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in a row</p>
</body>
</html>

View file

@ -0,0 +1,6 @@
rm -rf build/
flock "$1" pack -q install-deps test.ipkg
pack -q run test.ipkg
rm -rf build/

View file

@ -0,0 +1,22 @@
A paragraph with a normal newline
in the middle of it
A paragraph with a hard line break \
in the middle of it
A paragraph with a hard line break \
in the middle of it with extra spaces
A paragraph with a hard line break \
in the middle of it with no spaces
A paragraph with an explicit soft line break \n in the middle of it
Multiple soft breaks should coalesce \n\n\n into one
Same should apply when mixing explicit \n
and implied soft breaks
An escaped space\ should render as a nonbreaking space
We also want to test\ \ multiple\ \ \ nonbreaking\ \ \ \ spaces\ \ \ \ \ in a row

View file

@ -0,0 +1,7 @@
package a-test
depends = SSG
main = Main
executable = test