{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Text.Pandoc.Extensions ( Extension(..)
, Extensions
, emptyExtensions
, extensionsFromList
, parseFormatSpec
, extensionEnabled
, enableExtension
, disableExtension
, getDefaultExtensions
, pandocExtensions
, plainExtensions
, strictExtensions
, phpMarkdownExtraExtensions
, githubMarkdownExtensions
, multimarkdownExtensions )
where
import Prelude
import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions)
import Data.Aeson.TH (deriveJSON)
import Data.Bits (clearBit, setBit, testBit, (.|.))
import Data.Data (Data)
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Text.Pandoc.Shared (safeRead)
import Text.Parsec
newtype Extensions = Extensions Integer
deriving (Show, Read, Eq, Ord, Data, Typeable, Generic, ToJSON, FromJSON)
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_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_table_captions
| Ext_tex_math_dollars
| Ext_tex_math_double_backslash
| Ext_tex_math_single_backslash
| Ext_yaml_metadata_block
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_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_angle_brackets_escapable
, Ext_pipe_tables
, Ext_raw_html
, Ext_fenced_code_blocks
, Ext_gfm_auto_identifiers
, Ext_ascii_identifiers
, Ext_backtick_code_blocks
, Ext_autolink_bare_uris
, Ext_space_in_atx_header
, Ext_intraword_underscores
, Ext_strikeout
, 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_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 :: String -> Extensions
getDefaultExtensions "markdown_strict" = strictExtensions
getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
getDefaultExtensions "markdown_github" = githubMarkdownExtensions
getDefaultExtensions "markdown" = pandocExtensions
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]
parseFormatSpec :: String
-> Either ParseError (String, Extensions -> Extensions)
parseFormatSpec = parse formatSpec ""
where formatSpec = do
name <- formatName
extMods <- many extMod
return (name, \x -> foldl (flip ($)) x extMods)
formatName = many1 $ noneOf "-+"
extMod = do
polarity <- oneOf "-+"
name <- many $ noneOf "-+"
ext <- case safeRead ("Ext_" ++ name) of
Just n -> return n
Nothing
| name == "lhs" -> return Ext_literate_haskell
| otherwise -> fail $ "Unknown extension: " ++ name
return $ case polarity of
'-' -> disableExtension ext
_ -> enableExtension ext
$(deriveJSON defaultOptions ''Extension)