{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
module Text.Pandoc.Extensions ( Extension(..)
, Extensions
, emptyExtensions
, extensionsFromList
, parseFormatSpec
, extensionEnabled
, enableExtension
, disableExtension
, getDefaultExtensions
, getAllExtensions
, pandocExtensions
, plainExtensions
, strictExtensions
, phpMarkdownExtraExtensions
, githubMarkdownExtensions
, multimarkdownExtensions )
where
import Data.Bits (clearBit, setBit, testBit, (.|.))
import Data.Data (Data)
import qualified Data.Text as T
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Safe (readMay)
import Text.Parsec
import Data.Aeson.TH (deriveJSON, defaultOptions)
newtype Extensions = Extensions Integer
deriving (Show, Read, Eq, Ord, Data, Typeable, Generic)
instance Semigroup Extensions where
(Extensions a) <> (Extensions b) = Extensions (a .|. b)
instance Monoid Extensions where
mempty = Extensions 0
mappend = (<>)
extensionsFromList :: [Extension] -> Extensions
extensionsFromList = foldr enableExtension emptyExtensions
emptyExtensions :: Extensions
emptyExtensions = Extensions 0
extensionEnabled :: Extension -> Extensions -> Bool
extensionEnabled x (Extensions exts) = testBit exts (fromEnum x)
enableExtension :: Extension -> Extensions -> Extensions
enableExtension x (Extensions exts) = Extensions (setBit exts (fromEnum x))
disableExtension :: Extension -> Extensions -> Extensions
disableExtension x (Extensions exts) = Extensions (clearBit exts (fromEnum x))
data Extension =
Ext_abbreviations
| Ext_all_symbols_escapable
| Ext_amuse
| Ext_angle_brackets_escapable
| Ext_ascii_identifiers
| Ext_auto_identifiers
| Ext_autolink_bare_uris
| Ext_backtick_code_blocks
| Ext_blank_before_blockquote
| Ext_blank_before_header
| Ext_bracketed_spans
| Ext_citations
| Ext_compact_definition_lists
| Ext_definition_lists
| Ext_east_asian_line_breaks
| Ext_emoji
| Ext_empty_paragraphs
| Ext_epub_html_exts
| Ext_escaped_line_breaks
| Ext_example_lists
| Ext_fancy_lists
| Ext_fenced_code_attributes
| Ext_fenced_code_blocks
| Ext_fenced_divs
| Ext_footnotes
| Ext_four_space_rule
| Ext_gfm_auto_identifiers
| Ext_grid_tables
| Ext_hard_line_breaks
| Ext_header_attributes
| Ext_ignore_line_breaks
| Ext_implicit_figures
| Ext_implicit_header_references
| Ext_inline_code_attributes
| Ext_inline_notes
| Ext_intraword_underscores
| Ext_latex_macros
| Ext_line_blocks
| Ext_link_attributes
| Ext_lists_without_preceding_blankline
| Ext_literate_haskell
| Ext_markdown_attribute
| Ext_markdown_in_html_blocks
| Ext_mmd_header_identifiers
| Ext_mmd_link_attributes
| Ext_mmd_title_block
| Ext_multiline_tables
| Ext_native_divs
| Ext_native_spans
| Ext_native_numbering
| Ext_ntb
| Ext_old_dashes
| Ext_pandoc_title_block
| Ext_pipe_tables
| Ext_raw_attribute
| Ext_raw_html
| Ext_raw_tex
| Ext_shortcut_reference_links
| Ext_simple_tables
| Ext_smart
| Ext_space_in_atx_header
| Ext_spaced_reference_links
| Ext_startnum
| Ext_strikeout
| Ext_subscript
| Ext_superscript
| Ext_styles
| Ext_task_lists
| Ext_table_captions
| Ext_tex_math_dollars
| Ext_tex_math_double_backslash
| Ext_tex_math_single_backslash
| Ext_yaml_metadata_block
| Ext_gutenberg
deriving (Show, Read, Enum, Eq, Ord, Bounded, Data, Typeable, Generic)
pandocExtensions :: Extensions
pandocExtensions = extensionsFromList
[ Ext_footnotes
, Ext_inline_notes
, Ext_pandoc_title_block
, Ext_yaml_metadata_block
, Ext_table_captions
, Ext_implicit_figures
, Ext_simple_tables
, Ext_multiline_tables
, Ext_grid_tables
, Ext_pipe_tables
, Ext_citations
, Ext_raw_tex
, Ext_raw_html
, Ext_tex_math_dollars
, Ext_latex_macros
, Ext_fenced_code_blocks
, Ext_fenced_code_attributes
, Ext_backtick_code_blocks
, Ext_inline_code_attributes
, Ext_raw_attribute
, Ext_markdown_in_html_blocks
, Ext_native_divs
, Ext_fenced_divs
, Ext_native_spans
, Ext_bracketed_spans
, Ext_escaped_line_breaks
, Ext_fancy_lists
, Ext_startnum
, Ext_definition_lists
, Ext_example_lists
, Ext_all_symbols_escapable
, Ext_intraword_underscores
, Ext_blank_before_blockquote
, Ext_blank_before_header
, Ext_space_in_atx_header
, Ext_strikeout
, Ext_superscript
, Ext_subscript
, Ext_task_lists
, Ext_auto_identifiers
, Ext_header_attributes
, Ext_link_attributes
, Ext_implicit_header_references
, Ext_line_blocks
, Ext_shortcut_reference_links
, Ext_smart
]
plainExtensions :: Extensions
plainExtensions = extensionsFromList
[ Ext_table_captions
, Ext_implicit_figures
, Ext_simple_tables
, Ext_multiline_tables
, Ext_grid_tables
, Ext_latex_macros
, Ext_fancy_lists
, Ext_startnum
, Ext_definition_lists
, Ext_example_lists
, Ext_intraword_underscores
, Ext_blank_before_blockquote
, Ext_blank_before_header
, Ext_strikeout
]
phpMarkdownExtraExtensions :: Extensions
phpMarkdownExtraExtensions = extensionsFromList
[ Ext_footnotes
, Ext_pipe_tables
, Ext_raw_html
, Ext_markdown_attribute
, Ext_fenced_code_blocks
, Ext_definition_lists
, Ext_intraword_underscores
, Ext_header_attributes
, Ext_link_attributes
, Ext_abbreviations
, Ext_shortcut_reference_links
, Ext_spaced_reference_links
]
githubMarkdownExtensions :: Extensions
githubMarkdownExtensions = extensionsFromList
[ Ext_all_symbols_escapable
, Ext_pipe_tables
, Ext_raw_html
, Ext_fenced_code_blocks
, Ext_auto_identifiers
, Ext_gfm_auto_identifiers
, Ext_backtick_code_blocks
, Ext_autolink_bare_uris
, Ext_space_in_atx_header
, Ext_intraword_underscores
, Ext_strikeout
, Ext_task_lists
, Ext_emoji
, Ext_lists_without_preceding_blankline
, Ext_shortcut_reference_links
]
multimarkdownExtensions :: Extensions
multimarkdownExtensions = extensionsFromList
[ Ext_pipe_tables
, Ext_raw_html
, Ext_markdown_attribute
, Ext_mmd_link_attributes
, Ext_tex_math_double_backslash
, Ext_tex_math_dollars
, Ext_intraword_underscores
, Ext_mmd_title_block
, Ext_footnotes
, Ext_definition_lists
, Ext_all_symbols_escapable
, Ext_implicit_header_references
, Ext_shortcut_reference_links
, Ext_auto_identifiers
, Ext_mmd_header_identifiers
, Ext_implicit_figures
, Ext_superscript
, Ext_subscript
, Ext_backtick_code_blocks
, Ext_spaced_reference_links
, Ext_raw_attribute
]
strictExtensions :: Extensions
strictExtensions = extensionsFromList
[ Ext_raw_html
, Ext_shortcut_reference_links
, Ext_spaced_reference_links
]
getDefaultExtensions :: T.Text -> Extensions
getDefaultExtensions "markdown_strict" = strictExtensions
getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
getDefaultExtensions "markdown_github" = githubMarkdownExtensions
getDefaultExtensions "markdown" = pandocExtensions
getDefaultExtensions "ipynb" =
extensionsFromList
[ Ext_all_symbols_escapable
, Ext_pipe_tables
, Ext_raw_html
, Ext_fenced_code_blocks
, Ext_auto_identifiers
, Ext_gfm_auto_identifiers
, Ext_backtick_code_blocks
, Ext_autolink_bare_uris
, Ext_space_in_atx_header
, Ext_intraword_underscores
, Ext_strikeout
, Ext_task_lists
, Ext_lists_without_preceding_blankline
, Ext_shortcut_reference_links
, Ext_tex_math_dollars
]
getDefaultExtensions "muse" = extensionsFromList
[Ext_amuse,
Ext_auto_identifiers]
getDefaultExtensions "plain" = plainExtensions
getDefaultExtensions "gfm" = githubMarkdownExtensions
getDefaultExtensions "commonmark" = extensionsFromList
[Ext_raw_html]
getDefaultExtensions "org" = extensionsFromList
[Ext_citations,
Ext_auto_identifiers]
getDefaultExtensions "html" = extensionsFromList
[Ext_auto_identifiers,
Ext_native_divs,
Ext_line_blocks,
Ext_native_spans]
getDefaultExtensions "html4" = getDefaultExtensions "html"
getDefaultExtensions "html5" = getDefaultExtensions "html"
getDefaultExtensions "epub" = extensionsFromList
[Ext_raw_html,
Ext_native_divs,
Ext_native_spans,
Ext_epub_html_exts]
getDefaultExtensions "epub2" = getDefaultExtensions "epub"
getDefaultExtensions "epub3" = getDefaultExtensions "epub"
getDefaultExtensions "latex" = extensionsFromList
[Ext_smart,
Ext_latex_macros,
Ext_auto_identifiers]
getDefaultExtensions "beamer" = extensionsFromList
[Ext_smart,
Ext_latex_macros,
Ext_auto_identifiers]
getDefaultExtensions "context" = extensionsFromList
[Ext_smart,
Ext_auto_identifiers]
getDefaultExtensions "textile" = extensionsFromList
[Ext_old_dashes,
Ext_smart,
Ext_raw_html,
Ext_auto_identifiers]
getDefaultExtensions "opml" = pandocExtensions
getDefaultExtensions _ = extensionsFromList
[Ext_auto_identifiers]
getAllExtensions :: T.Text -> Extensions
getAllExtensions f = universalExtensions <> getAll f
where
autoIdExtensions = extensionsFromList
[ Ext_auto_identifiers
, Ext_gfm_auto_identifiers
, Ext_ascii_identifiers
]
universalExtensions = extensionsFromList
[ Ext_east_asian_line_breaks ]
allMarkdownExtensions =
pandocExtensions <> autoIdExtensions <>
extensionsFromList
[ Ext_old_dashes
, Ext_angle_brackets_escapable
, Ext_lists_without_preceding_blankline
, Ext_four_space_rule
, Ext_spaced_reference_links
, Ext_hard_line_breaks
, Ext_ignore_line_breaks
, Ext_east_asian_line_breaks
, Ext_emoji
, Ext_tex_math_single_backslash
, Ext_tex_math_double_backslash
, Ext_markdown_attribute
, Ext_mmd_title_block
, Ext_abbreviations
, Ext_autolink_bare_uris
, Ext_mmd_link_attributes
, Ext_mmd_header_identifiers
, Ext_compact_definition_lists
, Ext_gutenberg
, Ext_smart
, Ext_literate_haskell
]
getAll "markdown_strict" = allMarkdownExtensions
getAll "markdown_phpextra" = allMarkdownExtensions
getAll "markdown_mmd" = allMarkdownExtensions
getAll "markdown_github" = allMarkdownExtensions
getAll "markdown" = allMarkdownExtensions
getAll "ipynb" = allMarkdownExtensions
getAll "docx" = extensionsFromList
[ Ext_empty_paragraphs
, Ext_styles
]
getAll "opendocument" = extensionsFromList
[ Ext_empty_paragraphs
, Ext_native_numbering
]
getAll "odt" = getAll "opendocument" <> autoIdExtensions
getAll "muse" = autoIdExtensions <>
extensionsFromList
[ Ext_amuse ]
getAll "asciidoc" = autoIdExtensions
getAll "plain" = allMarkdownExtensions
getAll "gfm" = githubMarkdownExtensions <>
autoIdExtensions <>
extensionsFromList
[ Ext_raw_html
, Ext_raw_tex
, Ext_hard_line_breaks
, Ext_smart
]
getAll "commonmark" = getAll "gfm"
getAll "org" = autoIdExtensions <>
extensionsFromList
[ Ext_citations
, Ext_smart
]
getAll "html" = autoIdExtensions <>
extensionsFromList
[ Ext_native_divs
, Ext_line_blocks
, Ext_native_spans
, Ext_empty_paragraphs
, Ext_raw_html
, Ext_raw_tex
, Ext_task_lists
, Ext_tex_math_dollars
, Ext_tex_math_single_backslash
, Ext_tex_math_double_backslash
, Ext_literate_haskell
, Ext_epub_html_exts
, Ext_smart
]
getAll "html4" = getAll "html"
getAll "html5" = getAll "html"
getAll "epub" = getAll "html"
getAll "epub2" = getAll "epub"
getAll "epub3" = getAll "epub"
getAll "latex" = autoIdExtensions <>
extensionsFromList
[ Ext_smart
, Ext_latex_macros
, Ext_raw_tex
, Ext_task_lists
, Ext_literate_haskell
]
getAll "beamer" = getAll "latex"
getAll "context" = autoIdExtensions <>
extensionsFromList
[ Ext_smart
, Ext_raw_tex
, Ext_ntb
]
getAll "textile" = autoIdExtensions <>
extensionsFromList
[ Ext_old_dashes
, Ext_smart
, Ext_raw_tex
]
getAll "opml" = allMarkdownExtensions
getAll "twiki" = autoIdExtensions <>
extensionsFromList
[ Ext_smart ]
getAll "vimwiki" = autoIdExtensions
getAll "dokuwiki" = autoIdExtensions
getAll "tikiwiki" = autoIdExtensions
getAll "rst" = autoIdExtensions <>
extensionsFromList
[ Ext_smart
, Ext_literate_haskell
]
getAll "mediawiki" = autoIdExtensions <>
extensionsFromList
[ Ext_smart ]
getAll _ = mempty
parseFormatSpec :: T.Text
-> Either ParseError (T.Text, [Extension], [Extension])
parseFormatSpec = parse formatSpec ""
where formatSpec = do
name <- formatName
(extsToEnable, extsToDisable) <- foldl (flip ($)) ([],[]) <$>
many extMod
return (T.pack name, reverse extsToEnable, reverse extsToDisable)
formatName = many1 $ noneOf "-+"
extMod = do
polarity <- oneOf "-+"
name <- many $ noneOf "-+"
ext <- case readMay ("Ext_" ++ name) of
Just n -> return n
Nothing
| name == "lhs" -> return Ext_literate_haskell
| otherwise -> Prelude.fail $
"Unknown extension: " ++ name
return $ \(extsToEnable, extsToDisable) ->
case polarity of
'+' -> (ext : extsToEnable, extsToDisable)
_ -> (extsToEnable, ext : extsToDisable)
$(deriveJSON defaultOptions ''Extension)
$(deriveJSON defaultOptions ''Extensions)