Skip to content

Commit f77408a

Browse files
committed
Added commonmark-pandoc.
1 parent b50b237 commit f77408a

File tree

7 files changed

+307
-0
lines changed

7 files changed

+307
-0
lines changed

commonmark-pandoc/LICENSE

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright Author name here (c) 2018
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following
13+
disclaimer in the documentation and/or other materials provided
14+
with the distribution.
15+
16+
* Neither the name of Author name here nor the names of other
17+
contributors may be used to endorse or promote products derived
18+
from this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

commonmark-pandoc/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# commonmark-pandoc
2+
3+
This package provides the core parsing functionality
4+
for commonmark, without any renderers.
5+

commonmark-pandoc/Setup.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

commonmark-pandoc/changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Changelog for commonmark-pandoc
2+
3+
## Unreleased changes
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: commonmark-pandoc
2+
version: 0.1.0.0
3+
synopsis: Bridge between commonmark and pandoc AST.
4+
description:
5+
homepage: https://github.com/jgm/commonmark-hs
6+
bug-reports: https://github.com/jgm/commonmark-hs/issues
7+
author: John MacFarlane
8+
maintainer: [email protected]
9+
copyright: 2018 John MacFarlane
10+
license: BSD3
11+
license-file: LICENSE
12+
build-type: Simple
13+
cabal-version: >= 1.10
14+
15+
extra-source-files:
16+
changelog.md
17+
README.md
18+
19+
source-repository head
20+
type: git
21+
location: https://github.com/jgm/commonmark-hs
22+
23+
library
24+
hs-source-dirs:
25+
src
26+
build-depends:
27+
base >=4.7 && <5
28+
, commonmark
29+
, pandoc-types
30+
, text
31+
, containers
32+
if !impl(ghc >= 8.0)
33+
build-depends: semigroups == 0.18.*
34+
exposed-modules:
35+
Commonmark.Pandoc
36+
ghc-options: -Wall -fno-warn-unused-do-bind
37+
default-language: Haskell2010
+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
{-# LANGUAGE DeriveDataTypeable #-}
2+
{-# LANGUAGE ExtendedDefaultRules #-}
3+
{-# LANGUAGE FlexibleContexts #-}
4+
{-# LANGUAGE FlexibleInstances #-}
5+
{-# LANGUAGE FunctionalDependencies #-}
6+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+
{-# LANGUAGE MultiParamTypeClasses #-}
8+
{-# LANGUAGE OverloadedStrings #-}
9+
{-# LANGUAGE TypeSynonymInstances #-}
10+
11+
module Commonmark.Pandoc
12+
( CmPandoc(..)
13+
, CmRangedPandoc(..)
14+
)
15+
16+
where
17+
18+
import Data.Semigroup (Semigroup, (<>))
19+
import Text.Pandoc.Definition
20+
import Commonmark.Types
21+
import Commonmark.Extensions.Math
22+
import Commonmark.Extensions.PipeTable
23+
import Commonmark.Extensions.Strikethrough
24+
import Commonmark.Extensions.Footnote
25+
26+
newtype CmPandoc = CmPandoc { unCmPandoc :: Pandoc }
27+
deriving (Show, Semigroup, Monoid)
28+
29+
newtype CmRangedPandoc = CmRangedPandoc { unCmRangedPandoc :: Pandoc }
30+
deriving (Show, Semigroup, Monoid)
31+
32+
{-
33+
instance IsInline CmPandoc where
34+
lineBreak = Html5 $ br_ [] <> "\n"
35+
softBreak = Html5 $ "\n"
36+
str t = Html5 $ toHtml t
37+
entity t
38+
| illegalCodePoint t = Html5 $ toHtml ("\xFFFD" :: Text)
39+
| otherwise = Html5 $ toHtmlRaw t
40+
escapedChar c = Html5 $ toHtml (T.singleton c)
41+
emph ils = Html5 $ em_ $ unHtml5 ils
42+
strong ils = Html5 $ strong_ $ unHtml5 ils
43+
link target title ils = Html5 $
44+
a_ (href_ (escapeURI target) : [title_ title | not (T.null title)])
45+
$ unHtml5 ils
46+
image target title ils = Html5 $
47+
img_ ([src_ (escapeURI target),
48+
alt_ (renderAlt $ unHtml5 ils)] ++
49+
[title_ title | not (T.null title)])
50+
code t = Html5 $ code_ (toHtml t)
51+
rawInline f t
52+
| f == Format "html" = Html5 $ toHtmlRaw t
53+
| otherwise = Html5 $ mempty
54+
55+
escapeURI :: Text -> Text
56+
escapeURI = T.pack . escapeURIString
57+
(\c -> isAllowedInURI c && c /= '[' && c /= ']') . T.unpack
58+
59+
renderAlt :: Html () -> Text
60+
renderAlt = mconcat . map textOrAlt . parseTags . TL.toStrict . renderText
61+
where textOrAlt (TagText t) = t
62+
textOrAlt tag@(TagOpen "img" _) = fromAttrib "alt" tag
63+
textOrAlt _ = mempty
64+
65+
illegalCodePoint :: Text -> Bool
66+
illegalCodePoint t =
67+
"&#" `T.isPrefixOf` t &&
68+
let t' = T.drop 2 $ T.filter (/=';') t
69+
badvalue (n, r) = not (T.null r) ||
70+
n < 1 ||
71+
n > (0x10FFFF :: Integer)
72+
in
73+
case T.uncons t' of
74+
Nothing -> True
75+
Just (x, rest)
76+
| x == 'x' || x == 'X'
77+
-> either (const True) badvalue (TR.hexadecimal rest)
78+
| otherwise
79+
-> either (const True) badvalue (TR.decimal t')
80+
81+
instance IsBlock Html5 Html5 where
82+
paragraph ils = Html5 $ p_ (unHtml5 ils) <> nl
83+
plain ils = Html5 $ unHtml5 ils <> nl
84+
thematicBreak = Html5 $ hr_ [] <> nl
85+
blockQuote bs = Html5 $ blockquote_ (nl <> unHtml5 bs) <> nl
86+
codeBlock info t = Html5 $ pre_ (with code_ attr (toHtml t)) <> nl
87+
where attr = [class_ ("language-" <> lang) | not (T.null info)]
88+
lang = T.takeWhile (not . isSpace) info
89+
header level ils = Html5 $ h (unHtml5 ils) <> nl
90+
where h = case level of
91+
1 -> h1_
92+
2 -> h2_
93+
3 -> h3_
94+
4 -> h4_
95+
5 -> h5_
96+
6 -> h6_
97+
_ -> p_
98+
rawBlock f t
99+
| f == Format "html" = Html5 $ toHtmlRaw t
100+
| otherwise = Html5 $ mempty
101+
referenceLinkDefinition _ _ = Html5 $ mempty
102+
list (BulletList _) lSpacing items = Html5 $ ul_
103+
(nl <> mconcat (map (li . unHtml5) items)) <> nl
104+
where li x = if lSpacing == TightList
105+
then li_ x <> nl
106+
else li_ (nl <> x) <> nl
107+
list (OrderedList startnum _) lSpacing items = Html5 $ with ol_ attr
108+
(nl <> mconcat (map (li . unHtml5) items)) <> nl
109+
where li x = if lSpacing == TightList
110+
then li_ x <> nl
111+
else li_ (nl <> x) <> nl
112+
attr = [start_ (T.pack (show startnum)) | startnum /= 1]
113+
114+
nl :: Html ()
115+
nl = toHtmlRaw ("\n" :: Text)
116+
117+
newtype RangedHtml5 = RangedHtml5 {unRangedHtml5 :: Html ()}
118+
deriving (Show, Semigroup, Monoid)
119+
120+
instance IsInline RangedHtml5 where
121+
lineBreak = RangedHtml5 $ br_ [] <> "\n"
122+
softBreak = RangedHtml5 "\n"
123+
str t = RangedHtml5 $ span_ $ toHtml t
124+
entity t
125+
| illegalCodePoint t = RangedHtml5 $ span_ $ toHtml ("\xFFFD" :: Text)
126+
| otherwise = RangedHtml5 $ span_ $ toHtmlRaw t
127+
escapedChar c = RangedHtml5 $ span_ $ toHtml (T.singleton c)
128+
emph ils = RangedHtml5 $ em_ $ unRangedHtml5 ils
129+
strong ils = RangedHtml5 $ strong_ $ unRangedHtml5 ils
130+
link target title ils = RangedHtml5 $
131+
a_ (href_ (escapeURI target) : [title_ title | not (T.null title)])
132+
$ unRangedHtml5 ils
133+
image target title ils = RangedHtml5 $
134+
img_ ([src_ (escapeURI target), alt_ (renderAlt $ unRangedHtml5 ils)] ++
135+
[title_ title | not (T.null title)])
136+
code t = RangedHtml5 $ code_ (toHtml t)
137+
rawInline f t
138+
| f == Format "html" = RangedHtml5 $ span_ $ toHtmlRaw t
139+
| otherwise = mempty
140+
141+
instance IsBlock RangedHtml5 RangedHtml5 where
142+
paragraph ils = RangedHtml5 $ p_ (unRangedHtml5 ils) <> nl
143+
plain ils = RangedHtml5 $ unRangedHtml5 ils <> nl
144+
thematicBreak = RangedHtml5 $ hr_ [] <> nl
145+
blockQuote bs = RangedHtml5 $ blockquote_ (nl <> unRangedHtml5 bs) <> nl
146+
codeBlock info t = RangedHtml5 $ pre_ (with code_ attr (toHtml t)) <> nl
147+
where attr = [class_ ("language-" <> lang) | not (T.null info)]
148+
lang = T.takeWhile (not . isSpace) info
149+
header level ils = RangedHtml5 $ h (unRangedHtml5 ils) <> nl
150+
where h = case level of
151+
1 -> h1_
152+
2 -> h2_
153+
3 -> h3_
154+
4 -> h4_
155+
5 -> h5_
156+
6 -> h6_
157+
_ -> p_
158+
rawBlock f t
159+
| f == Format "html" = RangedHtml5 $ toHtmlRaw t
160+
| otherwise = mempty
161+
referenceLinkDefinition _ _ = mempty
162+
list (BulletList _) lSpacing items = RangedHtml5 $ ul_
163+
(nl <> mconcat (map (li . unRangedHtml5) items)) <> nl
164+
where li x = if lSpacing == TightList
165+
then li_ x <> nl
166+
else li_ (nl <> x) <> nl
167+
list (OrderedList startnum _) lSpacing items = RangedHtml5 $ with ol_ attr
168+
(nl <> mconcat (map (li . unRangedHtml5) items)) <> nl
169+
where li x = if lSpacing == TightList
170+
then li_ x <> nl
171+
else li_ (nl <> x) <> nl
172+
attr = [start_ (T.pack (show startnum)) | startnum /= 1]
173+
174+
instance Rangeable RangedHtml5 where
175+
ranged r (RangedHtml5 x) =
176+
RangedHtml5 $ with x [data_ "sourcepos" (T.pack (show r))]
177+
178+
instance Rangeable Html5 where
179+
ranged _ x = x
180+
181+
instance HasMath Html5 where
182+
inlineMath t = Html5 $
183+
span_ [class_ ("math inline")] ("\\(" <> toHtml t <> "\\)")
184+
displayMath t = Html5 $
185+
span_ [class_ ("math display")] ("\\[" <> toHtml t <> "\\]")
186+
187+
instance HasMath RangedHtml5 where
188+
inlineMath t = RangedHtml5 (unHtml5 $ inlineMath t)
189+
displayMath t = RangedHtml5 (unHtml5 $ displayMath t)
190+
191+
instance HasPipeTable Html5 Html5 where
192+
pipeTable aligns headerCells rows = Html5 $ do
193+
let alignToAttr LeftAlignedCol = [style_ "text-align: left;"]
194+
alignToAttr CenterAlignedCol = [style_ "text-align: center;"]
195+
alignToAttr RightAlignedCol = [style_ "text-align: right;"]
196+
alignToAttr DefaultAlignedCol = []
197+
let toCell constructor align cell = do
198+
with constructor (alignToAttr align) (unHtml5 cell)
199+
"\n"
200+
table_ $ do
201+
"\n"
202+
thead_ $ do
203+
"\n"
204+
tr_ $ do
205+
"\n"
206+
zipWithM_ (toCell th_) aligns headerCells
207+
"\n"
208+
"\n"
209+
unless (null rows) $ do
210+
tbody_ $ do
211+
"\n"
212+
mapM_ ((>> "\n") . tr_ . ("\n" >>) .
213+
zipWithM_ (toCell td_) aligns) rows
214+
"\n"
215+
"\n"
216+
217+
instance HasPipeTable RangedHtml5 RangedHtml5 where
218+
pipeTable aligns headerCells rows =
219+
RangedHtml5 $ unHtml5 $ pipeTable aligns
220+
(map (Html5 . unRangedHtml5) headerCells)
221+
(map (map (Html5 . unRangedHtml5)) rows)
222+
223+
instance HasStrikethrough Html5 where
224+
strikethrough ils = Html5 $ del_ (unHtml5 ils)
225+
226+
instance HasStrikethrough RangedHtml5 where
227+
strikethrough (RangedHtml5 ils) = RangedHtml5 $ del_ ils
228+
-}

stack.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
resolver: lts-10.10
22
extra-deps:
33
- criterion-1.4.0.0
4+
- pandoc-types-1.17.4.2
45
ghc-options:
56
"$locals": -fhide-source-paths
67
packages:
78
- commonmark
89
- commonmark-cli
910
- commonmark-lucid
11+
- commonmark-pandoc

0 commit comments

Comments
 (0)