git.iko.soy/typeable/pandoc
on master help sign in
Man writer: break lines at end of each sentence.

groff expects this and treats . and ? differently when followed by line ending as opposed to ordinary space. Also, don't escape periods. Instead, use zero-width character \& to avoid unwanted interpretation of periods at start of line. Resolves Issue #148. git-svn-id: https://pandoc.googlecode.com/svn/trunk@1580 788f1e2b-df1e-0410-8736-df70ead52e1b

commita0da2816bda209dec2d701f90abcda57944d7ad3 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateSat 6 Jun 2009, 21:27 (17 years ago) parent314c332
3 files changed+153−107
src/Text/Pandoc/Writers/Man.hs+36−3 tests/tables.man+13−11 tests/writer.man+104−93
src/Text/Pandoc/Writers/Man.hs+36−3
@@ -35,6 +35,7 @@ import Text.Printf ( printf )
3535import Data.List ( isPrefixOf, drop, nub, intersperse, intercalate )
3636import Text.PrettyPrint.HughesPJ hiding ( Str )
3737import Control.Monad.State
38+import Control.Monad ( liftM )
3839
3940type Notes = [[Block]]
4041type Preprocessors = [String] -- e.g. "t" for tbl
@@ -100,7 +101,7 @@ noteToMan opts num note = do
100101
101102-- | Association list of characters to escape.
102103manEscapes :: [(Char, String)]
103−manEscapes = [('\160', "\\ "), ('\'', "\\[aq]")] ++ backslashEscapes ".@\\"
104+manEscapes = [('\160', "\\ "), ('\'', "\\[aq]")] ++ backslashEscapes "@\\"
104105
105106-- | Escape special characters for Man.
106107escapeString :: String -> String
@@ -110,15 +111,43 @@ escapeString = escapeStringUsing manEscapes
110111escapeCode :: String -> String
111112escapeCode = escapeStringUsing (manEscapes ++ backslashEscapes "\t ")
112113
114+-- We split inline lists into sentences, and print one sentence per
115+-- line. groff/troff treats the line-ending period differently.
116+-- See http://code.google.com/p/pandoc/issues/detail?id=148.
117+
118+-- | Returns the first sentence in a list of inlines, and the rest.
119+breakSentence :: [Inline] -> ([Inline], [Inline])
120+breakSentence [] = ([],[])
121+breakSentence xs =
122+ let isSentenceEndInline (Str ".") = True
123+ isSentenceEndInline (Str "?") = True
124+ isSentenceEndInline _ = False
125+ (as, bs) = break isSentenceEndInline xs
126+ in case bs of
127+ [] -> (as, [])
128+ [c] -> (as ++ [c], [])
129+ (c:Space:cs) -> (as ++ [c], cs)
130+ (Str ".":Str ")":cs) -> (as ++ [Str ".", Str ")"], cs)
131+ (c:cs) -> (as ++ [c] ++ ds, es)
132+ where (ds, es) = breakSentence cs
133+
134+-- | Split a list of inlines into sentences.
135+splitSentences :: [Inline] -> [[Inline]]
136+splitSentences xs =
137+ let (sent, rest) = breakSentence xs
138+ in if null rest then [sent] else sent : splitSentences rest
139+
113140-- | Convert Pandoc block element to man.
114141blockToMan :: WriterOptions -- ^ Options
115142 -> Block -- ^ Block element
116143 -> State WriterState Doc
117144blockToMan _ Null = return empty
118145blockToMan opts (Plain inlines) =
119− wrapIfNeeded opts (inlineListToMan opts) inlines
146+ liftM vcat $ mapM (wrapIfNeeded opts (inlineListToMan opts)) $
147+ splitSentences inlines
120148blockToMan opts (Para inlines) = do
121− contents <- wrapIfNeeded opts (inlineListToMan opts) inlines
149+ contents <- liftM vcat $ mapM (wrapIfNeeded opts (inlineListToMan opts)) $
150+ splitSentences inlines
122151 return $ text ".PP" $$ contents
123152blockToMan _ (RawHtml str) = return $ text str
124153blockToMan _ HorizontalRule = return $ text $ ".PP\n * * * * *"
@@ -237,6 +266,10 @@ blockListToMan opts blocks =
237266
238267-- | Convert list of Pandoc inline elements to man.
239268inlineListToMan :: WriterOptions -> [Inline] -> State WriterState Doc
269+-- if list starts with ., insert a zero-width character \& so it
270+-- won't be interpreted as markup if it falls at the beginning of a line.
271+inlineListToMan opts lst@(Str "." : _) = mapM (inlineToMan opts) lst >>=
272+ (return . (text "\\&" <>) . hcat)
240273inlineListToMan opts lst = mapM (inlineToMan opts) lst >>= (return . hcat)
241274
242275-- | Convert Pandoc inline element to man.
tests/tables.man+13−11
@@ -1,7 +1,7 @@
11.PP
22Simple table with caption:
33.PP
4−Demonstration of simple table syntax\.
4+Demonstration of simple table syntax.
55.TS
66tab(@);
77rw(10.50n) lw(6.13n) cw(11.38n) lw(8.75n).
@@ -90,7 +90,7 @@ T}
9090.PP
9191Simple table indented two spaces:
9292.PP
93−Demonstration of simple table syntax\.
93+Demonstration of simple table syntax.
9494.TS
9595tab(@);
9696rw(10.50n) lw(6.13n) cw(11.38n) lw(8.75n).
@@ -135,7 +135,7 @@ T}
135135.PP
136136Multiline table with caption:
137137.PP
138−Here\[aq]s the caption\. It may span multiple lines\.
138+Here\[aq]s the caption. It may span multiple lines.
139139.TS
140140tab(@);
141141cw(10.50n) lw(9.63n) rw(11.38n) lw(23.63n).
@@ -154,18 +154,19 @@ First
154154T}@T{
155155row
156156T}@T{
157−12\.0
157+12.0
158158T}@T{
159−Example of a row that spans multiple lines\.
159+Example of a row that spans multiple lines.
160160T}
161161T{
162162Second
163163T}@T{
164164row
165165T}@T{
166−5\.0
166+5.0
167167T}@T{
168−Here\[aq]s another one\. Note the blank line between rows\.
168+Here\[aq]s another one.
169+Note the blank line between rows.
169170T}
170171.TE
171172.PP
@@ -189,17 +190,18 @@ First
189190T}@T{
190191row
191192T}@T{
192−12\.0
193+12.0
193194T}@T{
194−Example of a row that spans multiple lines\.
195+Example of a row that spans multiple lines.
195196T}
196197T{
197198Second
198199T}@T{
199200row
200201T}@T{
201−5\.0
202+5.0
202203T}@T{
203−Here\[aq]s another one\. Note the blank line between rows\.
204+Here\[aq]s another one.
205+Note the blank line between rows.
204206T}
205207.TE
tests/writer.man+104−93
@@ -1,7 +1,7 @@
11.TH Pandoc "" "July 17, 2006" "Test Suite"
22.PP
3−This is a set of tests for pandoc\. Most of them are adapted from
4−John Gruber's markdown test suite\.
3+This is a set of tests for pandoc.
4+Most of them are adapted from John Gruber's markdown test suite.
55.PP
66 * * * * *
77.SH Headers
@@ -21,19 +21,22 @@ with no blank line
2121 * * * * *
2222.SH Paragraphs
2323.PP
24−Here's a regular paragraph\.
24+Here's a regular paragraph.
2525.PP
26−In Markdown 1\.0\.0 and earlier\. Version 8\. This line turns into
27−a list item\. Because a hard-wrapped line in the middle of a
28−paragraph looked like a list item\.
26+In Markdown 1.0.0 and earlier.
27+Version 8.
28+This line turns into a list item.
29+Because a hard-wrapped line in the middle of a paragraph looked
30+like a list item.
2931.PP
30−Here's one with a bullet\. * criminey\.
32+Here's one with a bullet.
33+* criminey.
3134.PP
3235There should be a hard line break
3336.PD 0
3437.P
3538.PD
36−here\.
39+here.
3740.PP
3841 * * * * *
3942.SH Block Quotes
@@ -41,7 +44,8 @@ here\.
4144E-mail style:
4245.RS
4346.PP
44−This is a block quote\. It is pretty short\.
47+This is a block quote.
48+It is pretty short.
4549.RE
4650.RS
4751.PP
@@ -70,9 +74,9 @@ nested
7074.RE
7175.RE
7276.PP
73−This should not be a block quote: 2 > 1\.
77+This should not be a block quote: 2 > 1.
7478.PP
75−And a following paragraph\.
79+And a following paragraph.
7680.PP
7781 * * * * *
7882.SH Code Blocks
@@ -184,16 +188,17 @@ Three
184188.PP
185189Multiple paragraphs:
186190.IP "1." 3
187−Item 1, graf one\.
191+Item 1, graf one.
188192.RS 4
189193.PP
190−Item 1\. graf two\. The quick brown fox jumped over the lazy dog's
191−back\.
194+Item 1.
195+graf two.
196+The quick brown fox jumped over the lazy dog's back.
192197.RE
193198.IP "2." 3
194−Item 2\.
199+Item 2.
195200.IP "3." 3
196−Item 3\.
201+Item 3.
197202.SS Nested
198203.IP \[bu] 2
199204Tab
@@ -273,7 +278,7 @@ Nesting:
273278Upper Alpha
274279.RS 4
275280.IP "I." 3
276−Upper Roman\.
281+Upper Roman.
277282.RS 4
278283.IP "(6)" 4
279284Decimal start with 6
@@ -286,19 +291,20 @@ Lower alpha with paren
286291.PP
287292Autonumbering:
288293.IP "1." 3
289−Autonumber\.
294+Autonumber.
290295.IP "2." 3
291−More\.
296+More.
292297.RS 4
293298.IP "1." 3
294−Nested\.
299+Nested.
295300.RE
296301.PP
297302Should not be a list item:
298303.PP
299−M\.A\.\ 2007
304+M.A.\ 2007
300305.PP
301−B\. Williams
306+B.
307+Williams
302308.PP
303309 * * * * *
304310.SH Definition Lists
@@ -497,51 +503,53 @@ Hr's:
497503 * * * * *
498504.SH Inline Markup
499505.PP
500−This is \f[I]emphasized\f[], and so \f[I]is this\f[]\.
506+This is \f[I]emphasized\f[], and so \f[I]is this\f[].
501507.PP
502−This is \f[B]strong\f[], and so \f[B]is this\f[]\.
508+This is \f[B]strong\f[], and so \f[B]is this\f[].
503509.PP
504−An \f[I]emphasized link (/url)\f[]\.
510+An \f[I]emphasized link (/url)\f[].
505511.PP
506−\f[B]\f[I]This is strong and em\.\f[]\f[]
512+\f[B]\f[I]This is strong and em.\f[]\f[]
507513.PP
508−So is \f[B]\f[I]this\f[]\f[] word\.
514+So is \f[B]\f[I]this\f[]\f[] word.
509515.PP
510−\f[B]\f[I]This is strong and em\.\f[]\f[]
516+\f[B]\f[I]This is strong and em.\f[]\f[]
511517.PP
512−So is \f[B]\f[I]this\f[]\f[] word\.
518+So is \f[B]\f[I]this\f[]\f[] word.
513519.PP
514520This is code: \f[B]>\f[], \f[B]$\f[], \f[B]\\\f[], \f[B]\\$\f[],
515−\f[B]<html>\f[]\.
521+\f[B]<html>\f[].
516522.PP
517−[STRIKEOUT:This is \f[I]strikeout\f[]\.]
523+[STRIKEOUT:This is \f[I]strikeout\f[].]
518524.PP
519−Superscripts: a^bc^d a^\f[I]hello\f[]^ a^hello\ there^\.
525+Superscripts: a^bc^d a^\f[I]hello\f[]^ a^hello\ there^.
520526.PP
521−Subscripts: H~2~O, H~23~O, H~many\ of\ them~O\.
527+Subscripts: H~2~O, H~23~O, H~many\ of\ them~O.
522528.PP
523529These should not be superscripts or subscripts, because of the
524−unescaped spaces: a^b c^d, a~b c~d\.
530+unescaped spaces: a^b c^d, a~b c~d.
525531.PP
526532 * * * * *
527533.SH Smart quotes, ellipses, dashes
528534.PP
529−\[lq]Hello,\[rq] said the spider\. \[lq]`Shelob' is my name\.\[rq]
535+\[lq]Hello,\[rq] said the spider.
536+\[lq]`Shelob' is my name.\[rq]
530537.PP
531−`A', `B', and `C' are letters\.
538+`A', `B', and `C' are letters.
532539.PP
533−`Oak,' `elm,' and `beech' are names of trees\. So is `pine\.'
540+`Oak,' `elm,' and `beech' are names of trees.
541+So is `pine.'
534542.PP
535−`He said, \[lq]I want to go\.\[rq]' Were you alive in the 70's?
543+`He said, \[lq]I want to go.\[rq]' Were you alive in the 70's?
536544.PP
537545Here is some quoted `\f[B]code\f[]' and a
538−\[lq]quoted link (http://example.com/?foo=1&bar=2)\[rq]\.
546+\[lq]quoted link (http://example.com/?foo=1&bar=2)\[rq].
539547.PP
540−Some dashes: one\[em]two \[em] three\[em]four \[em] five\.
548+Some dashes: one\[em]two \[em] three\[em]four \[em] five.
541549.PP
542−Dashes between numbers: 5\[en]7, 255\[en]66, 1987\[en]1999\.
550+Dashes between numbers: 5\[en]7, 255\[en]66, 1987\[en]1999.
543551.PP
544−Ellipses\&...and\&...and\&...\.
552+Ellipses\&...and\&...and\&....
545553.PP
546554 * * * * *
547555.SH LaTeX
@@ -563,18 +571,19 @@ Here's some display math:
563571.RE
564572.IP \[bu] 2
565573Here's one that has a line break in it:
566−\f[B]\\alpha\ +\ \\omega\ \\times\ x^2\f[]\.
574+\f[B]\\alpha\ +\ \\omega\ \\times\ x^2\f[].
567575.PP
568576These shouldn't be math:
569577.IP \[bu] 2
570−To get the famous equation, write \f[B]$e\ =\ mc^2$\f[]\.
578+To get the famous equation, write \f[B]$e\ =\ mc^2$\f[].
571579.IP \[bu] 2
572−$22,000 is a \f[I]lot\f[] of money\. So is $34,000\. (It worked if
573−\[lq]lot\[rq] is emphasized\.)
580+$22,000 is a \f[I]lot\f[] of money.
581+So is $34,000.
582+(It worked if \[lq]lot\[rq] is emphasized.)
574583.IP \[bu] 2
575−Shoes ($20) and socks ($5)\.
584+Shoes ($20) and socks ($5).
576585.IP \[bu] 2
577−Escaped \f[B]$\f[]: $73 \f[I]this should be emphasized\f[] 23$\.
586+Escaped \f[B]$\f[]: $73 \f[I]this should be emphasized\f[] 23$.
578587.PP
579588Here's a LaTeX table:
580589.PP
@@ -594,15 +603,15 @@ set membership: ∈
594603.IP \[bu] 2
595604copyright: ©
596605.PP
597−AT&T has an ampersand in their name\.
606+AT&T has an ampersand in their name.
598607.PP
599−AT&T is another way to write it\.
608+AT&T is another way to write it.
600609.PP
601−This & that\.
610+This & that.
602611.PP
603−4 < 5\.
612+4 < 5.
604613.PP
605−6 > 5\.
614+6 > 5.
606615.PP
607616Backslash: \\
608617.PP
@@ -628,7 +637,7 @@ Greater-than: >
628637.PP
629638Hash: #
630639.PP
631−Period: \.
640+Period: \&.
632641.PP
633642Bang: !
634643.PP
@@ -640,13 +649,13 @@ Minus: -
640649.SH Links
641650.SS Explicit
642651.PP
643−Just a URL (/url/)\.
652+Just a URL (/url/).
644653.PP
645−URL and title (/url/)\.
654+URL and title (/url/).
646655.PP
647−URL and title (/url/)\.
656+URL and title (/url/).
648657.PP
649−URL and title (/url/)\.
658+URL and title (/url/).
650659.PP
651660URL and title (/url/)
652661.PP
@@ -656,45 +665,45 @@ with_underscore (/url/with_underscore)
656665.PP
657666Email link (mailto:nobody@nowhere.net)
658667.PP
659−Empty ()\.
668+Empty ().
660669.SS Reference
661670.PP
662−Foo bar (/url/)\.
671+Foo bar (/url/).
663672.PP
664−Foo bar (/url/)\.
673+Foo bar (/url/).
665674.PP
666−Foo bar (/url/)\.
675+Foo bar (/url/).
667676.PP
668−With embedded [brackets] (/url/)\.
677+With embedded [brackets] (/url/).
669678.PP
670−b (/url/) by itself should be a link\.
679+b (/url/) by itself should be a link.
671680.PP
672−Indented once (/url)\.
681+Indented once (/url).
673682.PP
674−Indented twice (/url)\.
683+Indented twice (/url).
675684.PP
676−Indented thrice (/url)\.
685+Indented thrice (/url).
677686.PP
678−This should [not][] be a link\.
687+This should [not][] be a link.
679688.PP
680689\f[CR]
681690 [not]:\ /url
682691\f[]
683692.PP
684−Foo bar (/url/)\.
693+Foo bar (/url/).
685694.PP
686−Foo biz (/url/)\.
695+Foo biz (/url/).
687696.SS With ampersands
688697.PP
689698Here's a
690−link with an ampersand in the URL (http://example.com/?foo=1&bar=2)\.
699+link with an ampersand in the URL (http://example.com/?foo=1&bar=2).
691700.PP
692701Here's a link with an amersand in the link text:
693−AT&T (http://att.com/)\.
702+AT&T (http://att.com/).
694703.PP
695−Here's an inline link (/script?foo=1&bar=2)\.
704+Here's an inline link (/script?foo=1&bar=2).
696705.PP
697−Here's an inline link in pointy braces (/script?foo=1&bar=2)\.
706+Here's an inline link in pointy braces (/script?foo=1&bar=2).
698707.SS Autolinks
699708.PP
700709With an ampersand: <http://example.com/?foo=1&bar=2>
@@ -703,7 +712,7 @@ In a list?
703712.IP \[bu] 2
704713<http://example.com/>
705714.IP \[bu] 2
706−It should\.
715+It should.
707716.PP
708717An e-mail address: <nobody@nowhere.net>
709718.RS
@@ -711,10 +720,10 @@ An e-mail address: <nobody@nowhere.net>
711720Blockquoted: <http://example.com/>
712721.RE
713722.PP
714−Auto-links should not occur here: \f[B]<http://example\.com/>\f[]
723+Auto-links should not occur here: \f[B]<http://example.com/>\f[]
715724.PP
716725\f[CR]
717− or\ here:\ <http://example\.com/>
726+ or\ here:\ <http://example.com/>
718727\f[]
719728.PP
720729 * * * * *
@@ -724,56 +733,58 @@ From \[lq]Voyage dans la Lune\[rq] by Georges Melies (1902):
724733.PP
725734[IMAGE: lalune (lalune.jpg)]
726735.PP
727−Here is a movie [IMAGE: movie (movie.jpg)] icon\.
736+Here is a movie [IMAGE: movie (movie.jpg)] icon.
728737.PP
729738 * * * * *
730739.SH Footnotes
731740.PP
732−Here is a footnote reference,[1] and another\.[2] This should
741+Here is a footnote reference,[1] and another.[2] This should
733742\f[I]not\f[] be a footnote reference, because it contains a
734−space\.[^my note] Here is an inline note\.[3]
743+space.[^my note] Here is an inline note.[3]
735744.RS
736745.PP
737−Notes can go in quotes\.[4]
746+Notes can go in quotes.[4]
738747.RE
739748.IP "1." 3
740−And in list items\.[5]
749+And in list items.[5]
741750.PP
742751This paragraph should not be part of the note, as it is not
743−indented\.
752+indented.
744753.SH NOTES
745754
746755.SS [1]
747756.PP
748−Here is the footnote\. It can go anywhere after the footnote
749−reference\. It need not be placed at the end of the document\.
757+Here is the footnote.
758+It can go anywhere after the footnote reference.
759+It need not be placed at the end of the document.
750760
751761.SS [2]
752762.PP
753−Here's the long note\. This one contains multiple blocks\.
763+Here's the long note.
764+This one contains multiple blocks.
754765.PP
755766Subsequent blocks are indented to show that they belong to the
756−footnote (as with list items)\.
767+footnote (as with list items).
757768.PP
758769\f[CR]
759770 \ \ {\ <code>\ }
760771\f[]
761772.PP
762773If you want, you can indent every line, but you can also be lazy
763−and just indent the first line of each block\.
774+and just indent the first line of each block.
764775
765776.SS [3]
766777.PP
767−This is \f[I]easier\f[] to type\. Inline notes may contain
768−links (http://google.com) and \f[B]]\f[] verbatim characters, as
769−well as [bracketed text]\.
778+This is \f[I]easier\f[] to type.
779+Inline notes may contain links (http://google.com) and \f[B]]\f[]
780+verbatim characters, as well as [bracketed text].
770781
771782.SS [4]
772783.PP
773−In quote\.
784+In quote.
774785
775786.SS [5]
776787.PP
777−In list\.
788+In list.
778789.SH AUTHORS
779790John MacFarlane, Anonymous