Skip to content

Commit 9f951a0

Browse files
committed
Chapter 4.4 - Markup parsing
1 parent 2a4691d commit 9f951a0

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

Markup.hs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
-- Markup.hs
2+
3+
module Markup
4+
( Document
5+
, Structure(..)
6+
, parse
7+
)
8+
where
9+
10+
import Numeric.Natural
11+
import Data.Maybe (maybeToList)
12+
13+
type Document
14+
= [Structure]
15+
16+
data Structure
17+
= Heading Natural String
18+
| Paragraph String
19+
| UnorderedList [String]
20+
| OrderedList [String]
21+
| CodeBlock [String]
22+
deriving (Eq, Show)
23+
24+
25+
parse :: String -> Document
26+
parse = parseLines Nothing . lines
27+
28+
parseLines :: Maybe Structure -> [String] -> Document
29+
parseLines context txts =
30+
case txts of
31+
-- done case
32+
[] -> maybeToList context
33+
34+
-- Heading 1 case
35+
('*' : ' ' : line) : rest ->
36+
maybe id (:) context (Heading 1 (trim line) : parseLines Nothing rest)
37+
38+
-- Unordered list case
39+
('-' : ' ' : line) : rest ->
40+
case context of
41+
Just (UnorderedList list) ->
42+
parseLines (Just (UnorderedList (list <> [trim line]))) rest
43+
44+
_ ->
45+
maybe id (:) context (parseLines (Just (UnorderedList [trim line])) rest)
46+
47+
-- Ordered list case
48+
('#' : ' ' : line) : rest ->
49+
case context of
50+
Just (OrderedList list) ->
51+
parseLines (Just (OrderedList (list <> [trim line]))) rest
52+
53+
_ ->
54+
maybe id (:) context (parseLines (Just (OrderedList [trim line])) rest)
55+
56+
-- Code block case
57+
('>' : ' ' : line) : rest ->
58+
case context of
59+
Just (CodeBlock code) ->
60+
parseLines (Just (CodeBlock (code <> [line]))) rest
61+
62+
_ ->
63+
maybe id (:) context (parseLines (Just (CodeBlock [line])) rest)
64+
65+
-- Paragraph case
66+
currentLine : rest ->
67+
let
68+
line = trim currentLine
69+
in
70+
if line == ""
71+
then
72+
maybe id (:) context (parseLines Nothing rest)
73+
else
74+
case context of
75+
Just (Paragraph paragraph) ->
76+
parseLines (Just (Paragraph (unwords [paragraph, line]))) rest
77+
_ ->
78+
maybe id (:) context (parseLines (Just (Paragraph line)) rest)
79+
80+
trim :: String -> String
81+
trim = unwords . words

0 commit comments

Comments
 (0)