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:
parent
68d388f833
commit
cd3282b08d
2 changed files with 114 additions and 2 deletions
|
@ -137,10 +137,13 @@ blockToOrg (RawBlock f str) | isRawFormat f =
|
||||||
return $ text str
|
return $ text str
|
||||||
blockToOrg (RawBlock _ _) = return empty
|
blockToOrg (RawBlock _ _) = return empty
|
||||||
blockToOrg HorizontalRule = return $ blankline $$ "--------------" $$ blankline
|
blockToOrg HorizontalRule = return $ blankline $$ "--------------" $$ blankline
|
||||||
blockToOrg (Header level _ inlines) = do
|
blockToOrg (Header level attr inlines) = do
|
||||||
contents <- inlineListToOrg inlines
|
contents <- inlineListToOrg inlines
|
||||||
let headerStr = text $ if level > 999 then " " else replicate level '*'
|
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
|
blockToOrg (CodeBlock (_,classes,_) str) = do
|
||||||
opts <- stOptions <$> get
|
opts <- stOptions <$> get
|
||||||
let tabstop = writerTabStop opts
|
let tabstop = writerTabStop opts
|
||||||
|
@ -230,6 +233,22 @@ definitionListItemToOrg (label, defs) = do
|
||||||
contents <- liftM vcat $ mapM blockListToOrg defs
|
contents <- liftM vcat $ mapM blockListToOrg defs
|
||||||
return $ hang 3 "- " $ label' <> " :: " <> (contents <> cr)
|
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.
|
-- | Convert list of Pandoc block elements to Org.
|
||||||
blockListToOrg :: [Block] -- ^ List of block elements
|
blockListToOrg :: [Block] -- ^ List of block elements
|
||||||
-> State WriterState Doc
|
-> State WriterState Doc
|
||||||
|
|
|
@ -9,30 +9,60 @@ markdown test suite.
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Headers
|
* Headers
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: headers
|
||||||
|
:END:
|
||||||
|
|
||||||
** Level 2 with an [[/url][embedded link]]
|
** Level 2 with an [[/url][embedded link]]
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-2-with-an-embedded-link
|
||||||
|
:END:
|
||||||
|
|
||||||
*** Level 3 with /emphasis/
|
*** Level 3 with /emphasis/
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-3-with-emphasis
|
||||||
|
:END:
|
||||||
|
|
||||||
**** Level 4
|
**** Level 4
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-4
|
||||||
|
:END:
|
||||||
|
|
||||||
***** Level 5
|
***** Level 5
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-5
|
||||||
|
:END:
|
||||||
|
|
||||||
* Level 1
|
* Level 1
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-1
|
||||||
|
:END:
|
||||||
|
|
||||||
** Level 2 with /emphasis/
|
** Level 2 with /emphasis/
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-2-with-emphasis
|
||||||
|
:END:
|
||||||
|
|
||||||
*** Level 3
|
*** Level 3
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-3
|
||||||
|
:END:
|
||||||
|
|
||||||
with no blank line
|
with no blank line
|
||||||
|
|
||||||
** Level 2
|
** Level 2
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: level-2
|
||||||
|
:END:
|
||||||
|
|
||||||
with no blank line
|
with no blank line
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Paragraphs
|
* Paragraphs
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: paragraphs
|
||||||
|
:END:
|
||||||
|
|
||||||
Here's a regular paragraph.
|
Here's a regular paragraph.
|
||||||
|
|
||||||
|
@ -48,6 +78,9 @@ here.
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Block Quotes
|
* Block Quotes
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: block-quotes
|
||||||
|
:END:
|
||||||
|
|
||||||
E-mail style:
|
E-mail style:
|
||||||
|
|
||||||
|
@ -87,6 +120,9 @@ And a following paragraph.
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Code Blocks
|
* Code Blocks
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: code-blocks
|
||||||
|
:END:
|
||||||
|
|
||||||
Code:
|
Code:
|
||||||
|
|
||||||
|
@ -111,8 +147,14 @@ And:
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Lists
|
* Lists
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: lists
|
||||||
|
:END:
|
||||||
|
|
||||||
** Unordered
|
** Unordered
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: unordered
|
||||||
|
:END:
|
||||||
|
|
||||||
Asterisks tight:
|
Asterisks tight:
|
||||||
|
|
||||||
|
@ -157,6 +199,9 @@ Minuses loose:
|
||||||
- Minus 3
|
- Minus 3
|
||||||
|
|
||||||
** Ordered
|
** Ordered
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: ordered
|
||||||
|
:END:
|
||||||
|
|
||||||
Tight:
|
Tight:
|
||||||
|
|
||||||
|
@ -197,6 +242,9 @@ Multiple paragraphs:
|
||||||
3. Item 3.
|
3. Item 3.
|
||||||
|
|
||||||
** Nested
|
** Nested
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: nested
|
||||||
|
:END:
|
||||||
|
|
||||||
- Tab
|
- Tab
|
||||||
|
|
||||||
|
@ -228,6 +276,9 @@ Same thing but with paragraphs:
|
||||||
3. Third
|
3. Third
|
||||||
|
|
||||||
** Tabs and spaces
|
** Tabs and spaces
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: tabs-and-spaces
|
||||||
|
:END:
|
||||||
|
|
||||||
- this is a list item indented with tabs
|
- 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
|
- this is an example list item indented with spaces
|
||||||
|
|
||||||
** Fancy list markers
|
** Fancy list markers
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: fancy-list-markers
|
||||||
|
:END:
|
||||||
|
|
||||||
2) begins with 2
|
2) begins with 2
|
||||||
3) and now 3
|
3) and now 3
|
||||||
|
@ -276,6 +330,9 @@ B. Williams
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Definition Lists
|
* Definition Lists
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: definition-lists
|
||||||
|
:END:
|
||||||
|
|
||||||
Tight using spaces:
|
Tight using spaces:
|
||||||
|
|
||||||
|
@ -342,6 +399,9 @@ Blank line after term, indented marker, alternate markers:
|
||||||
2. sublist
|
2. sublist
|
||||||
|
|
||||||
* HTML Blocks
|
* HTML Blocks
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: html-blocks
|
||||||
|
:END:
|
||||||
|
|
||||||
Simple block on one line:
|
Simple block on one line:
|
||||||
|
|
||||||
|
@ -569,6 +629,9 @@ Hr's:
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Inline Markup
|
* Inline Markup
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: inline-markup
|
||||||
|
:END:
|
||||||
|
|
||||||
This is /emphasized/, and so /is this/.
|
This is /emphasized/, and so /is this/.
|
||||||
|
|
||||||
|
@ -598,6 +661,9 @@ spaces: a\^b c\^d, a~b c~d.
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Smart quotes, ellipses, dashes
|
* Smart quotes, ellipses, dashes
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: smart-quotes-ellipses-dashes
|
||||||
|
:END:
|
||||||
|
|
||||||
"Hello," said the spider. "'Shelob' is my name."
|
"Hello," said the spider. "'Shelob' is my name."
|
||||||
|
|
||||||
|
@ -619,6 +685,9 @@ Ellipses...and...and....
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* LaTeX
|
* LaTeX
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: latex
|
||||||
|
:END:
|
||||||
|
|
||||||
- \cite[22-23]{smith.1899}
|
- \cite[22-23]{smith.1899}
|
||||||
- $2+2=4$
|
- $2+2=4$
|
||||||
|
@ -649,6 +718,9 @@ Cat & 1 \\ \hline
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Special Characters
|
* Special Characters
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: special-characters
|
||||||
|
:END:
|
||||||
|
|
||||||
Here is some unicode:
|
Here is some unicode:
|
||||||
|
|
||||||
|
@ -703,8 +775,14 @@ Minus: -
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Links
|
* Links
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: links
|
||||||
|
:END:
|
||||||
|
|
||||||
** Explicit
|
** Explicit
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: explicit
|
||||||
|
:END:
|
||||||
|
|
||||||
Just a [[/url/][URL]].
|
Just a [[/url/][URL]].
|
||||||
|
|
||||||
|
@ -725,6 +803,9 @@ Just a [[/url/][URL]].
|
||||||
[[][Empty]].
|
[[][Empty]].
|
||||||
|
|
||||||
** Reference
|
** Reference
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: reference
|
||||||
|
:END:
|
||||||
|
|
||||||
Foo [[/url/][bar]].
|
Foo [[/url/][bar]].
|
||||||
|
|
||||||
|
@ -753,6 +834,9 @@ Foo [[/url/][bar]].
|
||||||
Foo [[/url/][biz]].
|
Foo [[/url/][biz]].
|
||||||
|
|
||||||
** With ampersands
|
** With ampersands
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: with-ampersands
|
||||||
|
:END:
|
||||||
|
|
||||||
Here's a [[http://example.com/?foo=1&bar=2][link with an ampersand in the
|
Here's a [[http://example.com/?foo=1&bar=2][link with an ampersand in the
|
||||||
URL]].
|
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]].
|
Here's an [[/script?foo=1&bar=2][inline link in pointy braces]].
|
||||||
|
|
||||||
** Autolinks
|
** Autolinks
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: autolinks
|
||||||
|
:END:
|
||||||
|
|
||||||
With an ampersand: [[http://example.com/?foo=1&bar=2]]
|
With an ampersand: [[http://example.com/?foo=1&bar=2]]
|
||||||
|
|
||||||
|
@ -786,6 +873,9 @@ Auto-links should not occur here: =<http://example.com/>=
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Images
|
* Images
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: images
|
||||||
|
:END:
|
||||||
|
|
||||||
From "Voyage dans la Lune" by Georges Melies (1902):
|
From "Voyage dans la Lune" by Georges Melies (1902):
|
||||||
|
|
||||||
|
@ -797,6 +887,9 @@ Here is a movie [[movie.jpg]] icon.
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Footnotes
|
* Footnotes
|
||||||
|
:PROPERTIES:
|
||||||
|
:id: footnotes
|
||||||
|
:END:
|
||||||
|
|
||||||
Here is a footnote reference, [1] and another. [2] This should /not/ be a
|
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
|
footnote reference, because it contains a space.[\^my note] Here is an inline
|
||||||
|
|
Loading…
Add table
Reference in a new issue