Skip to content

Commit 22cafcc

Browse files
committed
Added tables
1 parent 4e3969a commit 22cafcc

File tree

5 files changed

+181
-133
lines changed

5 files changed

+181
-133
lines changed

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Here, I have used the `exec` command of `cabal` to execute `neorg-pandoc` and pa
4747
- @ordered :x:
4848
- @color :x:
4949
- @name :x:
50-
- @table :x:
50+
- @table :heavy_check_mark:
5151
- @embed :heavy_check_mark:
5252
- @code :heavy_check_mark:
5353
- @math :heavy_check_mark:

pandoc/Main.hs

Lines changed: 82 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Main where
22

3+
import Control.Applicative
34
import Control.Monad.Trans.State
45
import Data.Aeson (encode)
56
import qualified Data.ByteString.Lazy as B
@@ -35,86 +36,95 @@ type Convert a = State () a
3536
runConvert :: Convert a -> a
3637
runConvert c = evalState c ()
3738

38-
convertDocument :: forall tags. tags ~ SupportedTags => GenerateTagParser tags => TagHandler tags (Convert P.Blocks) -> Document tags -> P.Pandoc
39-
convertDocument handler (Document blocks) = runConvert $ P.doc . V.foldMap id <$> traverse convertBlock blocks
40-
where
41-
convertBlock :: Block tags -> Convert P.Blocks
42-
convertBlock = \case
43-
Paragraph i -> convertParagraph i
44-
Heading heading -> convertHeading heading
45-
Quote quote -> convertQuote quote
46-
List list -> convertList list
47-
HorizonalLine -> convertHorizonalLine
48-
Marker marker -> convertMarker marker
49-
Tag tag -> convertTag tag
50-
51-
convertParagraph :: Inline -> Convert P.Blocks
52-
convertParagraph = fmap P.para . convertInline
53-
54-
convertMarker :: Marker -> Convert P.Blocks
55-
convertMarker = error "not implemented"
56-
57-
convertList :: List -> Convert P.Blocks
58-
convertList = \case
59-
UnorderedList ul ->
60-
fmap (P.bulletList . V.toList) $
61-
traverse (applicativeConcatMap convertListBlock) $
62-
ul ^. uListItems
63-
OrderedList ol ->
64-
fmap (P.bulletList . V.toList) $
65-
traverse (applicativeConcatMap convertListBlock) $
66-
ol ^. oListItems
67-
TaskList tl ->
68-
let convertTaskListBlock taskStatus lb = convertListBlock lb
69-
in fmap (P.bulletList . V.toList) $
70-
traverse (\(taskStatus, items) -> applicativeConcatMap (convertTaskListBlock taskStatus) items) $
71-
tl ^. tListItems
72-
convertQuote :: Quote -> Convert P.Blocks
73-
convertQuote quote = P.blockQuote . P.para <$> convertInline (quote ^. quoteContent)
74-
75-
convertListBlock :: ListBlock -> Convert P.Blocks
76-
convertListBlock = \case
77-
ListParagraph i -> P.para <$> convertInline i
78-
SubList l -> convertList l
79-
80-
convertHeading :: Heading tags -> Convert P.Blocks
81-
convertHeading heading = do
82-
text <- convertInline $ heading ^. headingText
83-
let header = P.header (succ . fromEnum $ heading ^. headingLevel) text
84-
subBlocks <- applicativeConcatMap convertBlock (heading ^. headingContent)
85-
pure $ header <> subBlocks
86-
87-
convertHorizonalLine :: Convert P.Blocks
88-
convertHorizonalLine = pure P.horizontalRule
89-
90-
convertInline :: Inline -> Convert P.Inlines
91-
convertInline = \case
92-
Text t -> pure $ P.text t
93-
Bold inline -> P.strong <$> convertInline inline
94-
Italic inline -> P.emph <$> convertInline inline
95-
Underline inline -> P.underline <$> convertInline inline
96-
Strikethrough inline -> P.strikeout <$> convertInline inline
97-
Superscript inline -> P.superscript <$> convertInline inline
98-
Subscript inline -> P.subscript <$> convertInline inline
99-
Spoiler inline -> P.strikeout <$> convertInline inline -- TODO: No native spoilers in pandoc
100-
ConcatInline inlines -> V.foldMap id <$> traverse convertInline inlines
101-
Link url inlines -> P.link url "" <$> convertInline inlines -- TODO: Investigate title field
102-
Space -> pure P.space
103-
Verbatim t -> pure $ P.code t
104-
Math t -> pure $ P.math t
105-
convertTag :: SomeTag tags -> Convert P.Blocks
106-
convertTag = handleSomeTag handler
107-
108-
type SupportedTags = FromList '["code", "math", "comment", "embed", "document.meta"]
39+
convertDocument :: GenerateTagParser tags => TagHandler tags (Convert P.Blocks) -> Document tags -> P.Pandoc
40+
convertDocument handler (Document blocks) = runConvert $ P.doc . V.foldMap id <$> traverse (convertBlock handler) blocks
41+
42+
convertBlock :: TagHandler tags (Convert P.Blocks) -> Block tags -> Convert P.Blocks
43+
convertBlock handler = \case
44+
Paragraph i -> convertParagraph i
45+
Heading heading -> convertHeading handler heading
46+
Quote quote -> convertQuote quote
47+
List list -> convertList list
48+
HorizonalLine -> convertHorizonalLine
49+
Marker marker -> convertMarker marker
50+
Tag tag -> handleSomeTag handler tag
51+
52+
convertParagraph :: Inline -> Convert P.Blocks
53+
convertParagraph = fmap P.para . convertInline
54+
55+
convertMarker :: Marker -> Convert P.Blocks
56+
convertMarker = error "not implemented"
57+
58+
convertList :: List -> Convert P.Blocks
59+
convertList = \case
60+
UnorderedList ul ->
61+
fmap (P.bulletList . V.toList) $
62+
traverse (applicativeConcatMap convertListBlock) $
63+
ul ^. uListItems
64+
OrderedList ol ->
65+
fmap (P.bulletList . V.toList) $
66+
traverse (applicativeConcatMap convertListBlock) $
67+
ol ^. oListItems
68+
TaskList tl ->
69+
let convertTaskListBlock taskStatus lb = convertListBlock lb
70+
in fmap (P.bulletList . V.toList) $
71+
traverse (\(taskStatus, items) -> applicativeConcatMap (convertTaskListBlock taskStatus) items) $
72+
tl ^. tListItems
73+
74+
convertQuote :: Quote -> Convert P.Blocks
75+
convertQuote quote = P.blockQuote . P.para <$> convertInline (quote ^. quoteContent)
76+
77+
convertListBlock :: ListBlock -> Convert P.Blocks
78+
convertListBlock = \case
79+
ListParagraph i -> P.para <$> convertInline i
80+
SubList l -> convertList l
81+
82+
convertHeading :: TagHandler tags (Convert P.Blocks) -> Heading tags -> Convert P.Blocks
83+
convertHeading handler heading = do
84+
text <- convertInline $ heading ^. headingText
85+
let header = P.header (succ . fromEnum $ heading ^. headingLevel) text
86+
subBlocks <- applicativeConcatMap (convertBlock handler) (heading ^. headingContent)
87+
pure $ header <> subBlocks
88+
89+
convertHorizonalLine :: Convert P.Blocks
90+
convertHorizonalLine = pure P.horizontalRule
91+
92+
convertInline :: Inline -> Convert P.Inlines
93+
convertInline = \case
94+
Text t -> pure $ P.text t
95+
Bold inline -> P.strong <$> convertInline inline
96+
Italic inline -> P.emph <$> convertInline inline
97+
Underline inline -> P.underline <$> convertInline inline
98+
Strikethrough inline -> P.strikeout <$> convertInline inline
99+
Superscript inline -> P.superscript <$> convertInline inline
100+
Subscript inline -> P.subscript <$> convertInline inline
101+
Spoiler inline -> P.strikeout <$> convertInline inline -- TODO: No native spoilers in pandoc
102+
ConcatInline inlines -> V.foldMap id <$> traverse convertInline inlines
103+
Link url inlines -> P.link url "" <$> convertInline inlines -- TODO: Investigate title field
104+
Space -> pure P.space
105+
Verbatim t -> pure $ P.code t
106+
Math t -> pure $ P.math t
107+
108+
type SupportedTags = FromList '["code", "math", "comment", "embed", "document.meta", "table"]
109109

110110
tagHandler :: TagHandler SupportedTags (Convert P.Blocks)
111-
tagHandler = code `mergeHandler` math `mergeHandler` comment `mergeHandler` embed `mergeHandler` documentMeta
111+
tagHandler = code `mergeHandler` math `mergeHandler` comment `mergeHandler` embed `mergeHandler` documentMeta `mergeHandler` table
112112
where
113113
code = handleTag @"code" $ \_language text -> pure $ P.codeBlock text
114114
math = handleTag @"math" $ \_ text -> pure $ P.plain $ P.displayMath text
115115
comment = handleTag @"comment" $ \_ text -> pure mempty
116116
embed = handleTag @"embed" $ \_embedType url -> pure $ P.plain $ P.image url "" mempty
117117
documentMeta = handleTag @"document.meta" $ \_ _ -> pure mempty
118+
table = handleTag @"table" $ \_ (Table rows) ->
119+
if V.length rows == 0
120+
then pure mempty
121+
else
122+
let header = V.head rows
123+
body = V.drop 1 rows
124+
in P.simpleTable <$> convertTableRow header <*> traverse convertTableRow (V.toList body)
125+
where
126+
convertTableRow TableRowDelimiter = pure [P.horizontalRule]
127+
convertTableRow (TableRowInlines inlines) = traverse (fmap P.plain . convertInline) (V.toList inlines)
118128

119129
vecToMany :: V.Vector a -> P.Many a
120130
vecToMany = P.Many . S.fromList . V.toList

src/Neorg/Document.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,9 @@ instance Tag "table" where
298298
type TagArguments "table" = ()
299299
type TagContent "table" = Table
300300

301-
newtype Table = Table (V.Vector (V.Vector Inline)) deriving (Show, Eq)
301+
newtype Table = Table (V.Vector TableRow) deriving (Show, Eq)
302+
303+
data TableRow = TableRowDelimiter | TableRowInlines (V.Vector Inline) deriving (Show, Eq)
302304

303305
makeLenses ''Document
304306
makeLenses ''DocumentMeta

0 commit comments

Comments
 (0)