git.iko.soy/typeable/pandoc
on master help sign in
FB2 writer: allow emphasis and notes in titles
ff3ed5cAlexander Krotov
src/Text/Pandoc/Writers/FB2.hs+4−6
@@ -46,7 +46,7 @@ import Data.ByteString.Base64 (encode)
46import qualified Data.ByteString.Char8 as B8
46import qualified Data.ByteString.Char8 as B8
47import Data.Char (isAscii, isControl, isSpace, toLower)
47import Data.Char (isAscii, isControl, isSpace, toLower)
48import Data.Either (lefts, rights)
48import Data.Either (lefts, rights)
49−import Data.List (intercalate, intersperse, isPrefixOf, stripPrefix)
49+import Data.List (intercalate, isPrefixOf, stripPrefix)
50import Data.Text (Text, pack)
50import Data.Text (Text, pack)
51import Network.HTTP (urlEncode)
51import Network.HTTP (urlEncode)
52import Text.XML.Light
52import Text.XML.Light
@@ -180,7 +180,7 @@ renderSection :: PandocMonad m => Int -> ([Inline], [Block]) -> FBM m Content
180renderSection level (ttl, body) = do
180renderSection level (ttl, body) = do
181 title <- if null ttl
181 title <- if null ttl
182 then return []
182 then return []
183− else return . list . el "title" . formatTitle $ ttl
183+ else list . el "title" <$> formatTitle ttl
184 content <- if hasSubsections body
184 content <- if hasSubsections body
185 then renderSections (level + 1) body
185 then renderSections (level + 1) body
186 else cMapM blockToXml body
186 else cMapM blockToXml body
@@ -189,11 +189,9 @@ renderSection level (ttl, body) = do
189 hasSubsections = any isHeaderBlock
189 hasSubsections = any isHeaderBlock
190
190
191-- | Only <p> and <empty-line> are allowed within <title> in FB2.
191-- | Only <p> and <empty-line> are allowed within <title> in FB2.
192−formatTitle :: [Inline] -> [Content]
192+formatTitle :: PandocMonad m => [Inline] -> FBM m [Content]
193formatTitle inlines =
193formatTitle inlines =
194− let lns = split isLineBreak inlines
194+ cMapM (blockToXml . Para) $ split (== LineBreak) inlines
195− lns' = map (el "p" . cMap plain) lns
196− in intersperse (el "empty-line" ()) lns'
197
195
198split :: (a -> Bool) -> [a] -> [[a]]
196split :: (a -> Bool) -> [a] -> [[a]]
199split _ [] = []
197split _ [] = []
test/fb2/titles.fb2+1−1
@@ -1,3 +1,3 @@
1<?xml version="1.0" encoding="UTF-8"?>
1<?xml version="1.0" encoding="UTF-8"?>
2−<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section><title><p>Simple title</p></title><p>This example tests if Pandoc doesn’t insert forbidden elements in FictionBook titles.</p></section><section><title><p>Emphasized Strong Title</p></title></section></body></FictionBook>
2+<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink"><description><title-info><genre>unrecognised</genre></title-info><document-info><program-used>pandoc</program-used></document-info></description><body><title><p /></title><section><title><p>Simple title</p></title><p>This example tests FictionBook titles.</p></section><section><title><p><emphasis>Emphasized</emphasis> <strong>Strong</strong> Title</p></title></section></body></FictionBook>
3
3
test/fb2/titles.markdown+1−1
@@ -1,6 +1,6 @@
1# Simple title
1# Simple title
2
2
3−This example tests if Pandoc doesn't insert forbidden elements in FictionBook titles.
3+This example tests FictionBook titles.
4
4
5# *Emphasized* **Strong** Title
5# *Emphasized* **Strong** Title
6
6
test/writer.fb2+101−87
@@ -33,11 +33,15 @@
33</title>
33</title>
34<section>
34<section>
35<title>
35<title>
36−<p>Level 2 with an embedded link &lt;/url&gt;</p>
36+<p>Level 2 with an embedded link<a l:href="#l1" type="note">
37+<sup>[1]</sup>
38+</a>
39+</p>
37</title>
40</title>
38<section>
41<section>
39<title>
42<title>
40−<p>Level 3 with emphasis</p>
43+<p>Level 3 with <emphasis>emphasis</emphasis>
44+</p>
41</title>
45</title>
42<section>
46<section>
43<title>
47<title>
@@ -58,7 +62,8 @@
58</title>
62</title>
59<section>
63<section>
60<title>
64<title>
61−<p>Level 2 with emphasis</p>
65+<p>Level 2 with <emphasis>emphasis</emphasis>
66+</p>
62</title>
67</title>
63<section>
68<section>
64<title>
69<title>
@@ -485,8 +490,8 @@
485</title>
490</title>
486<p>This is <emphasis>emphasized</emphasis>, and so <emphasis>is this</emphasis>.</p>
491<p>This is <emphasis>emphasized</emphasis>, and so <emphasis>is this</emphasis>.</p>
487<p>This is <strong>strong</strong>, and so <strong>is this</strong>.</p>
492<p>This is <strong>strong</strong>, and so <strong>is this</strong>.</p>
488−<p>An <emphasis>emphasized link<a l:href="#l1" type="note">
493+<p>An <emphasis>emphasized link<a l:href="#l2" type="note">
489−<sup>[1]</sup>
494+<sup>[2]</sup>
490</a>
495</a>
491</emphasis>.</p>
496</emphasis>.</p>
492<p>
497<p>
@@ -526,8 +531,8 @@
526<p>‘A’, ‘B’, and ‘C’ are letters.</p>
531<p>‘A’, ‘B’, and ‘C’ are letters.</p>
527<p>‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’</p>
532<p>‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’</p>
528<p>‘He said, “I want to go.”’ Were you alive in the 70’s?</p>
533<p>‘He said, “I want to go.”’ Were you alive in the 70’s?</p>
529−<p>Here is some quoted ‘<code>code</code>’ and a “quoted link<a l:href="#l2" type="note">
534+<p>Here is some quoted ‘<code>code</code>’ and a “quoted link<a l:href="#l3" type="note">
530−<sup>[2]</sup>
535+<sup>[3]</sup>
531</a>”.</p>
536</a>”.</p>
532<p>Some dashes: one—two — three—four — five.</p>
537<p>Some dashes: one—two — three—four — five.</p>
533<p>Dashes between numbers: 5–7, 255–66, 1987–1999.</p>
538<p>Dashes between numbers: 5–7, 255–66, 1987–1999.</p>
@@ -606,10 +611,7 @@
606<title>
611<title>
607<p>Explicit</p>
612<p>Explicit</p>
608</title>
613</title>
609−<p>Just a URL<a l:href="#l3" type="note">
614+<p>Just a URL<a l:href="#l4" type="note">
610−<sup>[3]</sup>
611−</a>.</p>
612−<p>URL and title<a l:href="#l4" type="note">
613<sup>[4]</sup>
615<sup>[4]</sup>
614</a>.</p>
616</a>.</p>
615<p>URL and title<a l:href="#l5" type="note">
617<p>URL and title<a l:href="#l5" type="note">
@@ -620,97 +622,100 @@
620</a>.</p>
622</a>.</p>
621<p>URL and title<a l:href="#l7" type="note">
623<p>URL and title<a l:href="#l7" type="note">
622<sup>[7]</sup>
624<sup>[7]</sup>
623−</a>
625+</a>.</p>
624−</p>
625<p>URL and title<a l:href="#l8" type="note">
626<p>URL and title<a l:href="#l8" type="note">
626<sup>[8]</sup>
627<sup>[8]</sup>
627</a>
628</a>
628</p>
629</p>
629−<p>with_underscore<a l:href="#l9" type="note">
630+<p>URL and title<a l:href="#l9" type="note">
630<sup>[9]</sup>
631<sup>[9]</sup>
631</a>
632</a>
632</p>
633</p>
633−<p>Email link<a l:href="#l10" type="note">
634+<p>with_underscore<a l:href="#l10" type="note">
634<sup>[10]</sup>
635<sup>[10]</sup>
635</a>
636</a>
636</p>
637</p>
637−<p>Empty<a l:href="#l11" type="note">
638+<p>Email link<a l:href="#l11" type="note">
638<sup>[11]</sup>
639<sup>[11]</sup>
640+</a>
641+</p>
642+<p>Empty<a l:href="#l12" type="note">
643+<sup>[12]</sup>
639</a>.</p>
644</a>.</p>
640</section>
645</section>
641<section>
646<section>
642<title>
647<title>
643<p>Reference</p>
648<p>Reference</p>
644</title>
649</title>
645−<p>Foo bar<a l:href="#l12" type="note">
650+<p>Foo bar<a l:href="#l13" type="note">
646−<sup>[12]</sup>
647−</a>.</p>
648−<p>With embedded [brackets]<a l:href="#l13" type="note">
649<sup>[13]</sup>
651<sup>[13]</sup>
650</a>.</p>
652</a>.</p>
651−<p>b<a l:href="#l14" type="note">
653+<p>With embedded [brackets]<a l:href="#l14" type="note">
652<sup>[14]</sup>
654<sup>[14]</sup>
653−</a> by itself should be a link.</p>
654−<p>Indented once<a l:href="#l15" type="note">
655−<sup>[15]</sup>
656</a>.</p>
655</a>.</p>
656+<p>b<a l:href="#l15" type="note">
657+<sup>[15]</sup>
658+</a> by itself should be a link.</p>
657−<p>Indented twice<a l:href="#l16" type="note">
659+<p>Indented once<a l:href="#l16" type="note">
658<sup>[16]</sup>
660<sup>[16]</sup>
659</a>.</p>
661</a>.</p>
660−<p>Indented thrice<a l:href="#l17" type="note">
662+<p>Indented twice<a l:href="#l17" type="note">
661<sup>[17]</sup>
663<sup>[17]</sup>
662</a>.</p>
664</a>.</p>
665+<p>Indented thrice<a l:href="#l18" type="note">
666+<sup>[18]</sup>
667+</a>.</p>
663<p>This should [not][] be a link.</p>
668<p>This should [not][] be a link.</p>
664<empty-line />
669<empty-line />
665<p>
670<p>
666<code>[not]: /url</code>
671<code>[not]: /url</code>
667</p>
672</p>
668<empty-line />
673<empty-line />
669−<p>Foo bar<a l:href="#l18" type="note">
674+<p>Foo bar<a l:href="#l19" type="note">
670−<sup>[18]</sup>
671−</a>.</p>
672−<p>Foo biz<a l:href="#l19" type="note">
673<sup>[19]</sup>
675<sup>[19]</sup>
674</a>.</p>
676</a>.</p>
677+<p>Foo biz<a l:href="#l20" type="note">
678+<sup>[20]</sup>
679+</a>.</p>
675</section>
680</section>
676<section>
681<section>
677<title>
682<title>
678<p>With ampersands</p>
683<p>With ampersands</p>
679</title>
684</title>
680−<p>Here’s a link with an ampersand in the URL<a l:href="#l20" type="note">
685+<p>Here’s a link with an ampersand in the URL<a l:href="#l21" type="note">
681−<sup>[20]</sup>
682−</a>.</p>
683−<p>Here’s a link with an amersand in the link text: AT&amp;T<a l:href="#l21" type="note">
684<sup>[21]</sup>
686<sup>[21]</sup>
685</a>.</p>
687</a>.</p>
686−<p>Here’s an inline link<a l:href="#l22" type="note">
688+<p>Here’s a link with an amersand in the link text: AT&amp;T<a l:href="#l22" type="note">
687<sup>[22]</sup>
689<sup>[22]</sup>
688</a>.</p>
690</a>.</p>
689−<p>Here’s an inline link in pointy braces<a l:href="#l23" type="note">
691+<p>Here’s an inline link<a l:href="#l23" type="note">
690<sup>[23]</sup>
692<sup>[23]</sup>
691</a>.</p>
693</a>.</p>
694+<p>Here’s an inline link in pointy braces<a l:href="#l24" type="note">
695+<sup>[24]</sup>
696+</a>.</p>
692</section>
697</section>
693<section>
698<section>
694<title>
699<title>
695<p>Autolinks</p>
700<p>Autolinks</p>
696</title>
701</title>
697−<p>With an ampersand: http://example.com/?foo=1&amp;bar=2<a l:href="#l24" type="note">
702+<p>With an ampersand: http://example.com/?foo=1&amp;bar=2<a l:href="#l25" type="note">
698−<sup>[24]</sup>
703+<sup>[25]</sup>
699</a>
704</a>
700</p>
705</p>
701<p>• In a list?</p>
706<p>• In a list?</p>
702−<p>• http://example.com/<a l:href="#l25" type="note">
707+<p>• http://example.com/<a l:href="#l26" type="note">
703−<sup>[25]</sup>
708+<sup>[26]</sup>
704</a>
709</a>
705</p>
710</p>
706<p>• It should.</p>
711<p>• It should.</p>
707−<p>An e-mail address: nobody@nowhere.net<a l:href="#l26" type="note">
712+<p>An e-mail address: nobody@nowhere.net<a l:href="#l27" type="note">
708−<sup>[26]</sup>
713+<sup>[27]</sup>
709</a>
714</a>
710</p>
715</p>
711<cite>
716<cite>
712−<p>Blockquoted: http://example.com/<a l:href="#l27" type="note">
717+<p>Blockquoted: http://example.com/<a l:href="#l28" type="note">
713−<sup>[27]</sup>
718+<sup>[28]</sup>
714</a>
719</a>
715</p>
720</p>
716</cite>
721</cite>
@@ -741,22 +746,22 @@
741<title>
746<title>
742<p>Footnotes</p>
747<p>Footnotes</p>
743</title>
748</title>
744−<p>Here is a footnote reference,<a l:href="#n28" type="note">
749+<p>Here is a footnote reference,<a l:href="#n29" type="note">
745−<sup>[28]</sup>
746−</a> and another.<a l:href="#n29" type="note">
747<sup>[29]</sup>
750<sup>[29]</sup>
748−</a> This should <emphasis>not</emphasis> be a footnote reference, because it contains a space.[^my note] Here is an inline note.<a l:href="#n30" type="note">
751+</a> and another.<a l:href="#n30" type="note">
749<sup>[30]</sup>
752<sup>[30]</sup>
753+</a> This should <emphasis>not</emphasis> be a footnote reference, because it contains a space.[^my note] Here is an inline note.<a l:href="#n31" type="note">
754+<sup>[31]</sup>
750</a>
755</a>
751</p>
756</p>
752<cite>
757<cite>
753−<p>Notes can go in quotes.<a l:href="#n31" type="note">
758+<p>Notes can go in quotes.<a l:href="#n32" type="note">
754−<sup>[31]</sup>
759+<sup>[32]</sup>
755</a>
760</a>
756</p>
761</p>
757</cite>
762</cite>
758−<p>1. And in list items.<a l:href="#n32" type="note">
763+<p>1. And in list items.<a l:href="#n33" type="note">
759−<sup>[32]</sup>
764+<sup>[33]</sup>
760</a>
765</a>
761</p>
766</p>
762<p>This paragraph should not be part of the note, as it is not indented.</p>
767<p>This paragraph should not be part of the note, as it is not indented.</p>
@@ -776,7 +781,7 @@
776<p>2</p>
781<p>2</p>
777</title>
782</title>
778<p>
783<p>
779−<code>http://example.com/?foo=1&amp;bar=2</code>
784+<code>/url</code>
780</p>
785</p>
781</section>
786</section>
782<section id="l3">
787<section id="l3">
@@ -784,50 +789,50 @@
784<p>3</p>
789<p>3</p>
785</title>
790</title>
786<p>
791<p>
787−<code>/url/</code>
792+<code>http://example.com/?foo=1&amp;bar=2</code>
788</p>
793</p>
789</section>
794</section>
790<section id="l4">
795<section id="l4">
791<title>
796<title>
792<p>4</p>
797<p>4</p>
793</title>
798</title>
799+<p>
794−<p>title: <code>/url/</code>
800+<code>/url/</code>
795</p>
801</p>
796</section>
802</section>
797<section id="l5">
803<section id="l5">
798<title>
804<title>
799<p>5</p>
805<p>5</p>
800</title>
806</title>
801−<p>title preceded by two spaces: <code>/url/</code>
807+<p>title: <code>/url/</code>
802</p>
808</p>
803</section>
809</section>
804<section id="l6">
810<section id="l6">
805<title>
811<title>
806<p>6</p>
812<p>6</p>
807</title>
813</title>
808−<p>title preceded by a tab: <code>/url/</code>
814+<p>title preceded by two spaces: <code>/url/</code>
809</p>
815</p>
810</section>
816</section>
811<section id="l7">
817<section id="l7">
812<title>
818<title>
813<p>7</p>
819<p>7</p>
814</title>
820</title>
815−<p>title with &quot;quotes&quot; in it: <code>/url/</code>
821+<p>title preceded by a tab: <code>/url/</code>
816</p>
822</p>
817</section>
823</section>
818<section id="l8">
824<section id="l8">
819<title>
825<title>
820<p>8</p>
826<p>8</p>
821</title>
827</title>
822−<p>title with single quotes: <code>/url/</code>
828+<p>title with &quot;quotes&quot; in it: <code>/url/</code>
823</p>
829</p>
824</section>
830</section>
825<section id="l9">
831<section id="l9">
826<title>
832<title>
827<p>9</p>
833<p>9</p>
828</title>
834</title>
829−<p>
835+<p>title with single quotes: <code>/url/</code>
830−<code>/url/with_underscore</code>
831</p>
836</p>
832</section>
837</section>
833<section id="l10">
838<section id="l10">
@@ -835,7 +840,7 @@
835<p>10</p>
840<p>10</p>
836</title>
841</title>
837<p>
842<p>
838−<code>mailto:nobody@nowhere.net</code>
843+<code>/url/with_underscore</code>
839</p>
844</p>
840</section>
845</section>
841<section id="l11">
846<section id="l11">
@@ -843,8 +848,7 @@
843<p>11</p>
848<p>11</p>
844</title>
849</title>
845<p>
850<p>
846−<code>
851+<code>mailto:nobody@nowhere.net</code>
847−</code>
848</p>
852</p>
849</section>
853</section>
850<section id="l12">
854<section id="l12">
@@ -852,7 +856,8 @@
852<p>12</p>
856<p>12</p>
853</title>
857</title>
854<p>
858<p>
855−<code>/url/</code>
859+<code>
860+</code>
856</p>
861</p>
857</section>
862</section>
858<section id="l13">
863<section id="l13">
@@ -876,7 +881,7 @@
876<p>15</p>
881<p>15</p>
877</title>
882</title>
878<p>
883<p>
879−<code>/url</code>
884+<code>/url/</code>
880</p>
885</p>
881</section>
886</section>
882<section id="l16">
887<section id="l16">
@@ -899,37 +904,37 @@
899<title>
904<title>
900<p>18</p>
905<p>18</p>
901</title>
906</title>
907+<p>
902−<p>Title with &quot;quotes&quot; inside: <code>/url/</code>
908+<code>/url</code>
903</p>
909</p>
904</section>
910</section>
905<section id="l19">
911<section id="l19">
906<title>
912<title>
907<p>19</p>
913<p>19</p>
908</title>
914</title>
909−<p>Title with &quot;quote&quot; inside: <code>/url/</code>
915+<p>Title with &quot;quotes&quot; inside: <code>/url/</code>
910</p>
916</p>
911</section>
917</section>
912<section id="l20">
918<section id="l20">
913<title>
919<title>
914<p>20</p>
920<p>20</p>
915</title>
921</title>
916−<p>
922+<p>Title with &quot;quote&quot; inside: <code>/url/</code>
917−<code>http://example.com/?foo=1&amp;bar=2</code>
918</p>
923</p>
919</section>
924</section>
920<section id="l21">
925<section id="l21">
921<title>
926<title>
922<p>21</p>
927<p>21</p>
923</title>
928</title>
929+<p>
924−<p>AT&amp;T: <code>http://att.com/</code>
930+<code>http://example.com/?foo=1&amp;bar=2</code>
925</p>
931</p>
926</section>
932</section>
927<section id="l22">
933<section id="l22">
928<title>
934<title>
929<p>22</p>
935<p>22</p>
930</title>
936</title>
931−<p>
937+<p>AT&amp;T: <code>http://att.com/</code>
932−<code>/script?foo=1&amp;bar=2</code>
933</p>
938</p>
934</section>
939</section>
935<section id="l23">
940<section id="l23">
@@ -945,7 +950,7 @@
945<p>24</p>
950<p>24</p>
946</title>
951</title>
947<p>
952<p>
948−<code>http://example.com/?foo=1&amp;bar=2</code>
953+<code>/script?foo=1&amp;bar=2</code>
949</p>
954</p>
950</section>
955</section>
951<section id="l25">
956<section id="l25">
@@ -953,7 +958,7 @@
953<p>25</p>
958<p>25</p>
954</title>
959</title>
955<p>
960<p>
956−<code>http://example.com/</code>
961+<code>http://example.com/?foo=1&amp;bar=2</code>
957</p>
962</p>
958</section>
963</section>
959<section id="l26">
964<section id="l26">
@@ -961,7 +966,7 @@
961<p>26</p>
966<p>26</p>
962</title>
967</title>
963<p>
968<p>
964−<code>mailto:nobody@nowhere.net</code>
969+<code>http://example.com/</code>
965</p>
970</p>
966</section>
971</section>
967<section id="l27">
972<section id="l27">
@@ -969,19 +974,27 @@
969<p>27</p>
974<p>27</p>
970</title>
975</title>
971<p>
976<p>
972−<code>http://example.com/</code>
977+<code>mailto:nobody@nowhere.net</code>
973</p>
978</p>
974</section>
979</section>
975−<section id="n28">
980+<section id="l28">
976<title>
981<title>
977<p>28</p>
982<p>28</p>
978</title>
983</title>
979−<p>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.</p>
984+<p>
985+<code>http://example.com/</code>
986+</p>
980</section>
987</section>
981<section id="n29">
988<section id="n29">
982<title>
989<title>
983<p>29</p>
990<p>29</p>
984</title>
991</title>
992+<p>Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.</p>
993+</section>
994+<section id="n30">
995+<title>
996+<p>30</p>
997+</title>
985<p>Here’s the long note. This one contains multiple blocks.</p>
998<p>Here’s the long note. This one contains multiple blocks.</p>
986<p>Subsequent blocks are indented to show that they belong to the footnote (as with list items).</p>
999<p>Subsequent blocks are indented to show that they belong to the footnote (as with list items).</p>
987<empty-line />
1000<empty-line />
@@ -991,25 +1004,26 @@
991<empty-line />
1004<empty-line />
992<p>If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.</p>
1005<p>If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.</p>
993</section>
1006</section>
994−<section id="n30">
1007+<section id="n31">
995<title>
1008<title>
996−<p>30</p>
1009+<p>31</p>
997</title>
1010</title>
998−<p>This is <emphasis>easier</emphasis> to type. Inline notes may contain links<a l:href="#l30" type="note">
1011+<p>This is <emphasis>easier</emphasis> to type. Inline notes may contain links<a l:href="#l31" type="note">
999−<sup>[30]</sup>
1012+<sup>[31]</sup>
1000</a> and <code>]</code> verbatim characters, as well as [bracketed text].</p>
1013</a> and <code>]</code> verbatim characters, as well as [bracketed text].</p>
1001</section>
1014</section>
1002−<section id="n31">
1015+<section id="n32">
1003<title>
1016<title>
1004−<p>31</p>
1017+<p>32</p>
1005</title>
1018</title>
1006<p>In quote.</p>
1019<p>In quote.</p>
1007</section>
1020</section>
1008−<section id="n32">
1021+<section id="n33">
1009<title>
1022<title>
1010−<p>32</p>
1023+<p>33</p>
1011</title>
1024</title>
1012<p>In list.</p>
1025<p>In list.</p>
1013</section>
1026</section>
1014</body>
1027</body>
1015</FictionBook>
1028</FictionBook>
1029+