Org writer: add :PROPERTIES: drawer support

This allows header attributes to be added to org documents in the form
of `:PROPERTIES:` drawers.  All available attributes are stored as
key/value pairs.  This reflects the way the org reader handles
`:PROPERTIES:` blocks.

This closes #1962.
This commit is contained in:
Albert Krewinkel 2016-05-20 16:29:15 +02:00
parent 68d388f833
commit cd3282b08d
2 changed files with 114 additions and 2 deletions

View file

@ -137,10 +137,13 @@ blockToOrg (RawBlock f str) | isRawFormat f =
return $ text str
blockToOrg (RawBlock _ _) = return empty
blockToOrg HorizontalRule = return $ blankline $$ "--------------" $$ blankline
blockToOrg (Header level _ inlines) = do
blockToOrg (Header level attr inlines) = do
contents <- inlineListToOrg inlines
let headerStr = text $ if level > 999 then " " else replicate level '*'
return $ headerStr <> " " <> contents <> blankline
let drawerStr = if attr == nullAttr
then empty
else cr <> nest (level + 1) (propertiesDrawer attr)
return $ headerStr <> " " <> contents <> drawerStr <> blankline
blockToOrg (CodeBlock (_,classes,_) str) = do
opts <- stOptions <$> get
let tabstop = writerTabStop opts
@ -230,6 +233,22 @@ definitionListItemToOrg (label, defs) = do
contents <- liftM vcat $ mapM blockListToOrg defs
return $ hang 3 "- " $ label' <> " :: " <> (contents <> cr)
-- | Convert list of key/value pairs to Org :PROPERTIES: drawer.
propertiesDrawer :: Attr -> Doc
propertiesDrawer (ident, classes, kv) =
let
drawerStart = text ":PROPERTIES:"
drawerEnd = text ":END:"
kv' = if (classes == mempty) then kv else ("class", unwords classes):kv
kv'' = if (ident == mempty) then kv' else ("id", ident):kv'
properties = vcat $ map kvToOrgProperty kv''
in
drawerStart <> cr <> properties <> cr <> drawerEnd
where
kvToOrgProperty :: (String, String) -> Doc
kvToOrgProperty (key, value) =
text ":" <> text key <> text ": " <> text value <> cr
-- | Convert list of Pandoc block elements to Org.
blockListToOrg :: [Block] -- ^ List of block elements
-> State WriterState Doc

View file

@ -9,30 +9,60 @@ markdown test suite.
--------------
* Headers
:PROPERTIES:
:id: headers
:END:
** Level 2 with an [[/url][embedded link]]
:PROPERTIES:
:id: level-2-with-an-embedded-link
:END:
*** Level 3 with /emphasis/
:PROPERTIES:
:id: level-3-with-emphasis
:END:
**** Level 4
:PROPERTIES:
:id: level-4
:END:
***** Level 5
:PROPERTIES:
:id: level-5
:END:
* Level 1
:PROPERTIES:
:id: level-1
:END:
** Level 2 with /emphasis/
:PROPERTIES:
:id: level-2-with-emphasis
:END:
*** Level 3
:PROPERTIES:
:id: level-3
:END:
with no blank line
** Level 2
:PROPERTIES:
:id: level-2
:END:
with no blank line
--------------
* Paragraphs
:PROPERTIES:
:id: paragraphs
:END:
Here's a regular paragraph.
@ -48,6 +78,9 @@ here.
--------------
* Block Quotes
:PROPERTIES:
:id: block-quotes
:END:
E-mail style:
@ -87,6 +120,9 @@ And a following paragraph.
--------------
* Code Blocks
:PROPERTIES:
:id: code-blocks
:END:
Code:
@ -111,8 +147,14 @@ And:
--------------
* Lists
:PROPERTIES:
:id: lists
:END:
** Unordered
:PROPERTIES:
:id: unordered
:END:
Asterisks tight:
@ -157,6 +199,9 @@ Minuses loose:
- Minus 3
** Ordered
:PROPERTIES:
:id: ordered
:END:
Tight:
@ -197,6 +242,9 @@ Multiple paragraphs:
3. Item 3.
** Nested
:PROPERTIES:
:id: nested
:END:
- Tab
@ -228,6 +276,9 @@ Same thing but with paragraphs:
3. Third
** Tabs and spaces
:PROPERTIES:
:id: tabs-and-spaces
:END:
- this is a list item indented with tabs
@ -238,6 +289,9 @@ Same thing but with paragraphs:
- this is an example list item indented with spaces
** Fancy list markers
:PROPERTIES:
:id: fancy-list-markers
:END:
2) begins with 2
3) and now 3
@ -276,6 +330,9 @@ B. Williams
--------------
* Definition Lists
:PROPERTIES:
:id: definition-lists
:END:
Tight using spaces:
@ -342,6 +399,9 @@ Blank line after term, indented marker, alternate markers:
2. sublist
* HTML Blocks
:PROPERTIES:
:id: html-blocks
:END:
Simple block on one line:
@ -569,6 +629,9 @@ Hr's:
--------------
* Inline Markup
:PROPERTIES:
:id: inline-markup
:END:
This is /emphasized/, and so /is this/.
@ -598,6 +661,9 @@ spaces: a\^b c\^d, a~b c~d.
--------------
* Smart quotes, ellipses, dashes
:PROPERTIES:
:id: smart-quotes-ellipses-dashes
:END:
"Hello," said the spider. "'Shelob' is my name."
@ -619,6 +685,9 @@ Ellipses...and...and....
--------------
* LaTeX
:PROPERTIES:
:id: latex
:END:
- \cite[22-23]{smith.1899}
- $2+2=4$
@ -649,6 +718,9 @@ Cat & 1 \\ \hline
--------------
* Special Characters
:PROPERTIES:
:id: special-characters
:END:
Here is some unicode:
@ -703,8 +775,14 @@ Minus: -
--------------
* Links
:PROPERTIES:
:id: links
:END:
** Explicit
:PROPERTIES:
:id: explicit
:END:
Just a [[/url/][URL]].
@ -725,6 +803,9 @@ Just a [[/url/][URL]].
[[][Empty]].
** Reference
:PROPERTIES:
:id: reference
:END:
Foo [[/url/][bar]].
@ -753,6 +834,9 @@ Foo [[/url/][bar]].
Foo [[/url/][biz]].
** With ampersands
:PROPERTIES:
:id: with-ampersands
:END:
Here's a [[http://example.com/?foo=1&bar=2][link with an ampersand in the
URL]].
@ -764,6 +848,9 @@ Here's an [[/script?foo=1&bar=2][inline link]].
Here's an [[/script?foo=1&bar=2][inline link in pointy braces]].
** Autolinks
:PROPERTIES:
:id: autolinks
:END:
With an ampersand: [[http://example.com/?foo=1&bar=2]]
@ -786,6 +873,9 @@ Auto-links should not occur here: =<http://example.com/>=
--------------
* Images
:PROPERTIES:
:id: images
:END:
From "Voyage dans la Lune" by Georges Melies (1902):
@ -797,6 +887,9 @@ Here is a movie [[movie.jpg]] icon.
--------------
* Footnotes
:PROPERTIES:
:id: footnotes
:END:
Here is a footnote reference, [1] and another. [2] This should /not/ be a
footnote reference, because it contains a space.[\^my note] Here is an inline