kramdown-man 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ require 'kramdown'
2
+
3
+ # HACK: load our version of kramdown/converter/man.rb and not kramdown's
4
+ require_relative './converter/man'
5
+ require_relative './man/version'
@@ -0,0 +1,70 @@
1
+ require 'kramdown'
2
+ require_relative '../converter/man'
3
+
4
+ require 'rake/tasklib'
5
+
6
+ module Kramdown
7
+ module Man
8
+ #
9
+ # Defines a `man` rake task that generates man-pages within the `man/`
10
+ # directory from `.md` files.
11
+ #
12
+ class Task < Rake::TaskLib
13
+
14
+ # Markdown file glob pattern
15
+ FILES = 'man/{**/}*.{markdown,mkd,md}'
16
+
17
+ # Additional options
18
+ #
19
+ # @return [Hash]
20
+ attr_reader :options
21
+
22
+ #
23
+ # Initializes the tasks.
24
+ #
25
+ # @param [Hash] options
26
+ # Additional options.
27
+ #
28
+ def initialize(options={})
29
+ @options = options
30
+ @markdown = FileList[FILES]
31
+ @man_pages = @markdown.pathmap('%X')
32
+
33
+ define
34
+ end
35
+
36
+ protected
37
+
38
+ #
39
+ # Defines the `man` tasks.
40
+ #
41
+ def define
42
+ desc 'Build UNIX manual pages from Markdown files in man/'
43
+ task 'man' => @man_pages
44
+
45
+ @markdown.zip(@man_pages).each do |markdown,man_page|
46
+ file(man_page => markdown) do
47
+ render(markdown,man_page)
48
+ end
49
+ end
50
+ end
51
+
52
+ #
53
+ # Renders a man_page from a markdown file.
54
+ #
55
+ # @param [String] markdown
56
+ # The path to the input markdown file.
57
+ #
58
+ # @param [String] man_page
59
+ # The path to the output man_page file.
60
+ #
61
+ def render(markdown,man_page)
62
+ doc = Kramdown::Document.new(File.read(markdown),@options)
63
+
64
+ File.open(man_page,'w') do |output|
65
+ output.write doc.to_man
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,6 @@
1
+ module Kramdown
2
+ module Man
3
+ # kramdown-man version
4
+ VERSION = "0.1.7"
5
+ end
6
+ end
@@ -0,0 +1,183 @@
1
+ .\" Generated by kramdown-man 0.1.7
2
+ .\" https://github.com/postmodern/kramdown-man#readme
3
+ .TH kramdown-man.1 "April 2013" kramdown-man "User Manuals"
4
+ .LP
5
+ .SH DESCRIPTION
6
+ .LP
7
+ .PP
8
+ A Kramdown
9
+ .UR http:\[sl]\[sl]kramdown\.gettalong\.org\[sl]
10
+ .UE plugin for converting Markdown files into man pages\.
11
+ .LP
12
+ .SH EXAMPLE
13
+ .LP
14
+ .nf
15
+ require \(aqkramdown\(aq
16
+ require \(aqkramdown\[sl]man\(aq
17
+
18
+ doc \[eq] Kramdown::Document\.new(File\.read(\(aqman\[sl]kramdown\-man\.1\.md\(aq))
19
+ File\.write(\(aqman\[sl]kramdown\-man\.1\(aq,doc\.to\[ru]man)
20
+ system \(aqman\(aq, \(aqman\[sl]kramdown\-man\.1\(aq
21
+ .fi
22
+ .LP
23
+ .SH SYNTAX
24
+ .LP
25
+ .SS FORMATTING
26
+ .LP
27
+ .nf
28
+ \`code\`
29
+ .fi
30
+ .LP
31
+ .PP
32
+ \fBcode\fR
33
+ .LP
34
+ .nf
35
+ *emphasis*
36
+ .fi
37
+ .LP
38
+ .PP
39
+ \fIemphasis\fP
40
+ .LP
41
+ .nf
42
+ **strong**
43
+ .fi
44
+ .LP
45
+ .PP
46
+ \fBstrong\fP
47
+ .LP
48
+ .SS PARAGRAPHS
49
+ .LP
50
+ .nf
51
+ Normal paragraph\.
52
+ .fi
53
+ .LP
54
+ .PP
55
+ Normal paragraph\.
56
+ .LP
57
+ .nf
58
+ \`command\` \[lB]\`\-\-foo\`\[rB] *FILE*
59
+ .fi
60
+ .LP
61
+ .HP
62
+ \fBcommand\fR \[lB]\fB--foo\fR\[rB] \fIFILE\fP
63
+ .LP
64
+ .nf
65
+ \`\-\-tagged\`
66
+ Text here\.
67
+ .fi
68
+ .LP
69
+ .TP
70
+ \fB--tagged\fR
71
+ Text here\.
72
+ .LP
73
+ .SS LINKS
74
+ .LP
75
+ .nf
76
+ \[lB]website\[rB](http:\[sl]\[sl]example\.com\[sl])
77
+ .fi
78
+ .LP
79
+ .PP
80
+ website
81
+ .UR http:\[sl]\[sl]example\.com\[sl]
82
+ .UE
83
+ .LP
84
+ .nf
85
+ \[lB]bash\[rB](man:bash(1))
86
+ .fi
87
+ .LP
88
+ .PP
89
+ .BR bash (1)
90
+ .LP
91
+ .nf
92
+ Email <bob\[at]example\.com>
93
+ .fi
94
+ .LP
95
+ .PP
96
+ Email
97
+ .MT bob\[at]example\.com
98
+ .ME
99
+ .LP
100
+ .SS LISTS
101
+ .LP
102
+ .nf
103
+ * one
104
+ * two
105
+ * three
106
+
107
+ extra paragraph
108
+ .fi
109
+ .LP
110
+ .RS
111
+ .IP \(bu 2
112
+ one
113
+ .IP \(bu 2
114
+ two
115
+ .IP \(bu 2
116
+ three
117
+ .IP \( 2
118
+ extra paragraph
119
+ .RE
120
+ .LP
121
+ .nr step1 0 1
122
+ .RS
123
+ .IP \n+[step1]
124
+ one
125
+ .IP \n+[step1]
126
+ two
127
+ .IP \n+[step1]
128
+ three
129
+ .IP \n
130
+ extra paragraph
131
+ .RE
132
+ .LP
133
+ .SS HORIZONTAL RULE
134
+ .LP
135
+ .nf
136
+ \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
137
+ .fi
138
+ .LP
139
+ .ti 0
140
+ \l'\n(.lu'
141
+ .LP
142
+ .SS BLOCKQUOTES
143
+ .LP
144
+ .nf
145
+ > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away\.
146
+ >
147
+ > \-\-Antoine de Saint\-Exup\['e]ry
148
+ .fi
149
+ .LP
150
+ .PP
151
+ .RS
152
+ Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away\.
153
+ .LP
154
+ \-\-Antoine de Saint\-Exup\['e]ry
155
+ .RE
156
+ .LP
157
+ .SS CODE BLOCKS
158
+ .LP
159
+ .nf
160
+ \[sh]include <stdio\.h>
161
+
162
+ int main()
163
+ \[lC]
164
+ printf(\[dq]hello world\en\[dq]);
165
+ return 0;
166
+ \[rC]
167
+
168
+ \[sh]include <stdio\.h>
169
+
170
+ int main()
171
+ \[lC]
172
+ printf(\[dq]hello world\en\[dq]);
173
+ return 0;
174
+ \[rC]
175
+ .fi
176
+ .LP
177
+ .SH AUTHOR
178
+ .LP
179
+ .PP
180
+ Postmodern
181
+ .MT postmodern\.mod3\[at]gmail\.com
182
+ .ME
183
+ .LP
@@ -0,0 +1,127 @@
1
+ # kramdown-man.1 "April 2013" kramdown-man "User Manuals"
2
+
3
+ ## DESCRIPTION
4
+
5
+ A [Kramdown][kramdown] plugin for converting Markdown files into man pages.
6
+
7
+ ## EXAMPLE
8
+
9
+ require 'kramdown'
10
+ require 'kramdown/man'
11
+
12
+ doc = Kramdown::Document.new(File.read('man/kramdown-man.1.md'))
13
+ File.write('man/kramdown-man.1',doc.to_man)
14
+ system 'man', 'man/kramdown-man.1'
15
+
16
+ ## SYNTAX
17
+
18
+ ### FORMATTING
19
+
20
+ `code`
21
+
22
+ `code`
23
+
24
+ *emphasis*
25
+
26
+ *emphasis*
27
+
28
+ **strong**
29
+
30
+ **strong**
31
+
32
+ ### PARAGRAPHS
33
+
34
+ Normal paragraph.
35
+
36
+ Normal paragraph.
37
+
38
+ `command` [`--foo`] *FILE*
39
+
40
+ `command` [`--foo`] *FILE*
41
+
42
+ `--tagged`
43
+ Text here.
44
+
45
+ `--tagged`
46
+ Text here.
47
+
48
+ ### LINKS
49
+
50
+ [website](http://example.com/)
51
+
52
+ [website](http://example.com/)
53
+
54
+ [bash](man:bash(1))
55
+
56
+ [bash](man:bash(1))
57
+
58
+ Email <bob@example.com>
59
+
60
+ Email <bob@example.com>
61
+
62
+ ### LISTS
63
+
64
+ * one
65
+ * two
66
+ * three
67
+
68
+ extra paragraph
69
+
70
+
71
+ * one
72
+ * two
73
+ * three
74
+
75
+ extra paragraph
76
+
77
+ 1. one
78
+ 2. two
79
+ 3. three
80
+
81
+ extra paragraph
82
+
83
+ 1. one
84
+ 2. two
85
+ 3. three
86
+
87
+ extra paragraph
88
+
89
+ ### HORIZONTAL RULE
90
+
91
+ -------------------------------------------------------------------------------
92
+
93
+ -------------------------------------------------------------------------------
94
+
95
+ ### BLOCKQUOTES
96
+
97
+ > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
98
+ >
99
+ > --Antoine de Saint-Exupéry
100
+
101
+ > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
102
+ >
103
+ > --Antoine de Saint-Exupéry
104
+
105
+ ### CODE BLOCKS
106
+
107
+ #include <stdio.h>
108
+
109
+ int main()
110
+ {
111
+ printf("hello world\n");
112
+ return 0;
113
+ }
114
+
115
+ #include <stdio.h>
116
+
117
+ int main()
118
+ {
119
+ printf("hello world\n");
120
+ return 0;
121
+ }
122
+
123
+ ## AUTHOR
124
+
125
+ Postmodern <postmodern.mod3@gmail.com>
126
+
127
+ [kramdown]: http://kramdown.gettalong.org/
@@ -0,0 +1,562 @@
1
+ # encoding: utf-8
2
+ require_relative '../../spec_helper'
3
+
4
+ # HACK: load our version of kramdown/converter/man.rb and not kramdown's
5
+ require_relative '../../../lib/kramdown/converter/man'
6
+
7
+ describe Kramdown::Converter::Man do
8
+ let(:markdown) { File.read('man/kramdown-man.1.md') }
9
+ let(:doc) { Kramdown::Document.new(markdown) }
10
+ let(:root) { doc.root }
11
+
12
+ subject { described_class.send(:new,root,{}) }
13
+
14
+ describe "#convert" do
15
+ let(:doc) do
16
+ Kramdown::Document.new(%{
17
+ # Header
18
+
19
+ Hello world.
20
+ }.strip)
21
+ end
22
+ let(:root) { doc.root }
23
+
24
+ it "should add the header" do
25
+ expect(subject.convert(root)).to eq([
26
+ described_class::HEADER,
27
+ ".TH Header",
28
+ ".LP",
29
+ ".PP",
30
+ 'Hello world\.'
31
+ ].join("\n"))
32
+ end
33
+ end
34
+
35
+ describe "#convert_root" do
36
+ let(:doc) do
37
+ Kramdown::Document.new(%{
38
+ # Header
39
+
40
+ Hello world.
41
+ }.strip)
42
+ end
43
+
44
+ let(:root) { doc.root }
45
+
46
+ it "should convert every element" do
47
+ expect(subject.convert_root(root)).to eq([
48
+ ".TH Header",
49
+ ".LP",
50
+ ".PP",
51
+ 'Hello world\.'
52
+ ].join("\n"))
53
+ end
54
+ end
55
+
56
+ describe "#convert_element" do
57
+ let(:doc) { Kramdown::Document.new(" puts 'hello'") }
58
+ let(:el) { doc.root.children[0] }
59
+
60
+ it "should convert the element based on it's type" do
61
+ expect(subject.convert_element(el)).to eq(subject.convert_codeblock(el))
62
+ end
63
+ end
64
+
65
+ describe "#convert_blank" do
66
+ let(:doc) { Kramdown::Document.new("foo\n\nbar") }
67
+ let(:blank) { doc.root.children[0].children[1] }
68
+
69
+ it "should convert blank elements to '.LP'" do
70
+ expect(subject.convert_blank(blank)).to eq('.LP')
71
+ end
72
+ end
73
+
74
+ describe "#convert_text" do
75
+ let(:content) { 'Foo bar' }
76
+ let(:doc) { Kramdown::Document.new(content) }
77
+ let(:text) { doc.root.children[0].children[0] }
78
+
79
+ it "should convert text elements" do
80
+ expect(subject.convert_text(text)).to eq(content)
81
+ end
82
+
83
+ context "when the text has two-space indentation" do
84
+ let(:content) { "Foo\n bar\n baz" }
85
+
86
+ it "should strip leading whitespace from each line" do
87
+ expect(subject.convert_text(text)).to eq(content.gsub("\n ","\n"))
88
+ end
89
+ end
90
+
91
+ context "when the text has tab indentation" do
92
+ let(:content) { "Foo\n\tbar\n\tbaz" }
93
+
94
+ it "should strip leading whitespace from each line" do
95
+ expect(subject.convert_text(text)).to eq(content.gsub("\n\t","\n"))
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#convert_typographic_sym" do
101
+ context "ndash" do
102
+ let(:doc) { Kramdown::Document.new("-- foo") }
103
+ let(:sym) { doc.root.children[0].children[0] }
104
+
105
+ it "should convert ndash symbols back into '\-\-'" do
106
+ expect(subject.convert_typographic_sym(sym)).to eq("\\-\\-")
107
+ end
108
+ end
109
+
110
+ context "mdash" do
111
+ let(:doc) { Kramdown::Document.new("--- foo") }
112
+ let(:sym) { doc.root.children[0].children[0] }
113
+
114
+ it "should convert mdash symbols into '\[em]'" do
115
+ expect(subject.convert_typographic_sym(sym)).to eq('\[em]')
116
+ end
117
+ end
118
+
119
+ context "hellip" do
120
+ let(:doc) { Kramdown::Document.new("... foo") }
121
+ let(:sym) { doc.root.children[0].children[0] }
122
+
123
+ it "should convert mdash symbols into '\\.\\.\\.'" do
124
+ expect(subject.convert_typographic_sym(sym)).to eq('\.\.\.')
125
+ end
126
+ end
127
+
128
+ context "laquo" do
129
+ let(:doc) { Kramdown::Document.new("<< foo") }
130
+ let(:sym) { doc.root.children[0].children[0] }
131
+
132
+ it "should convert mdash symbols into '\[Fo]'" do
133
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fo]')
134
+ end
135
+ end
136
+
137
+ context "raquo" do
138
+ let(:doc) { Kramdown::Document.new("foo >> bar") }
139
+ let(:sym) { doc.root.children[0].children[1] }
140
+
141
+ it "should convert mdash symbols into '\[Fc]'" do
142
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fc]')
143
+ end
144
+ end
145
+
146
+ context "laquo_space" do
147
+ let(:doc) { Kramdown::Document.new(" << foo") }
148
+ let(:sym) { doc.root.children[0].children[0] }
149
+
150
+ it "should convert mdash symbols into '\[Fo]'" do
151
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fo]')
152
+ end
153
+ end
154
+
155
+ context "raquo_space" do
156
+ let(:doc) { Kramdown::Document.new("foo >> bar") }
157
+ let(:sym) { doc.root.children[0].children[1] }
158
+
159
+ it "should convert mdash symbols into '\[Fc]'" do
160
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fc]')
161
+ end
162
+ end
163
+ end
164
+
165
+ describe "#convert_smart_quote" do
166
+ context "lsquo" do
167
+ let(:doc) { Kramdown::Document.new("'hello world'") }
168
+ let(:quote) { doc.root.children[0].children.first }
169
+
170
+ it "should convert lsquo quotes into '\[oq]'" do
171
+ expect(subject.convert_smart_quote(quote)).to eq('\[oq]')
172
+ end
173
+ end
174
+
175
+ context "rsquo" do
176
+ let(:doc) { Kramdown::Document.new("'hello world'") }
177
+ let(:quote) { doc.root.children[0].children.last }
178
+
179
+ it "should convert rsquo quotes into '\[cq]'" do
180
+ expect(subject.convert_smart_quote(quote)).to eq('\[cq]')
181
+ end
182
+ end
183
+
184
+ context "ldquo" do
185
+ let(:doc) { Kramdown::Document.new('"hello world"') }
186
+ let(:quote) { doc.root.children[0].children.first }
187
+
188
+ it "should convert lsquo quotes into '\[lq]'" do
189
+ expect(subject.convert_smart_quote(quote)).to eq('\[lq]')
190
+ end
191
+ end
192
+
193
+ context "rdquo" do
194
+ let(:doc) { Kramdown::Document.new('"hello world"') }
195
+ let(:quote) { doc.root.children[0].children.last }
196
+
197
+ it "should convert lsquo quotes into '\[rq]'" do
198
+ expect(subject.convert_smart_quote(quote)).to eq('\[rq]')
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "#convert_header" do
204
+ context "when level is 1" do
205
+ let(:doc) { Kramdown::Document.new("# Header") }
206
+ let(:header) { doc.root.children[0] }
207
+
208
+ it "should convert level 1 headers into '.TH text'" do
209
+ expect(subject.convert_header(header)).to eq(".TH Header")
210
+ end
211
+ end
212
+
213
+ context "when level is 2" do
214
+ let(:doc) { Kramdown::Document.new("## Header") }
215
+ let(:header) { doc.root.children[0] }
216
+
217
+ it "should convert level 2 headers into '.SH text'" do
218
+ expect(subject.convert_header(header)).to eq(".SH Header")
219
+ end
220
+ end
221
+
222
+ context "when level is 3" do
223
+ let(:doc) { Kramdown::Document.new("### Header") }
224
+ let(:header) { doc.root.children[0] }
225
+
226
+ it "should convert level 2 headers into '.SS text'" do
227
+ expect(subject.convert_header(header)).to eq(".SS Header")
228
+ end
229
+ end
230
+
231
+ context "when level is 4 or greater" do
232
+ let(:doc) { Kramdown::Document.new("#### Header") }
233
+ let(:header) { doc.root.children[0] }
234
+
235
+ it "should convert level 2 headers into '.SS text'" do
236
+ expect(subject.convert_header(header)).to eq(".SS Header")
237
+ end
238
+ end
239
+ end
240
+
241
+ describe "#convert_hr" do
242
+ let(:doc) { Kramdown::Document.new('------------------------------------') }
243
+ let(:hr) { doc.root.children[0] }
244
+
245
+ it "should convert hr elements into '.ti 0\\n\\\\l'\\\\n(.lu\\''" do
246
+ expect(subject.convert_hr(hr)).to eq(".ti 0\n\\l'\\n(.lu'")
247
+ end
248
+ end
249
+
250
+ describe "#convert_ul" do
251
+ let(:text1) { 'foo' }
252
+ let(:text2) { 'bar' }
253
+ let(:doc) { Kramdown::Document.new("* #{text1}\n* #{text2}") }
254
+ let(:ul) { doc.root.children[0] }
255
+
256
+ it "should convert ul elements into '.RS\\n...\\n.RE'" do
257
+ expect(subject.convert_ul(ul)).to eq([
258
+ ".RS",
259
+ ".IP \\(bu 2",
260
+ text1,
261
+ ".IP \\(bu 2",
262
+ text2,
263
+ ".RE"
264
+ ].join("\n"))
265
+ end
266
+ end
267
+
268
+ describe "#convert_ul_li" do
269
+ let(:text) { 'hello world' }
270
+ let(:doc) { Kramdown::Document.new("* #{text}") }
271
+ let(:li) { doc.root.children[0].children[0] }
272
+
273
+ it "should convert the first p element to '.IP \\\\(bu 2\\n...'" do
274
+ expect(subject.convert_ul_li(li)).to eq(".IP \\(bu 2\n#{text}")
275
+ end
276
+
277
+ context "with multiple multiple paragraphs" do
278
+ let(:text1) { 'hello' }
279
+ let(:text2) { 'world' }
280
+ let(:doc) { Kramdown::Document.new("* #{text1}\n\n #{text2}") }
281
+
282
+ it "should convert the other p elements to '.IP \\\\( 2\\n...'" do
283
+ expect(subject.convert_ul_li(li)).to eq([
284
+ ".IP \\(bu 2",
285
+ text1,
286
+ ".IP \\( 2",
287
+ text2
288
+ ].join("\n"))
289
+ end
290
+ end
291
+ end
292
+
293
+ describe "#convert_ol" do
294
+ let(:text1) { 'foo' }
295
+ let(:text2) { 'bar' }
296
+ let(:doc) { Kramdown::Document.new("1. #{text1}\n2. #{text2}") }
297
+ let(:ol) { doc.root.children[0] }
298
+
299
+ it "should convert ol elements into '.RS\\n...\\n.RE'" do
300
+ expect(subject.convert_ol(ol)).to eq([
301
+ ".nr step1 0 1",
302
+ ".RS",
303
+ ".IP \\n+[step1]",
304
+ text1,
305
+ ".IP \\n+[step1]",
306
+ text2,
307
+ ".RE"
308
+ ].join("\n"))
309
+ end
310
+ end
311
+
312
+ describe "#convert_ol_li" do
313
+ let(:text) { 'hello world' }
314
+ let(:doc) { Kramdown::Document.new("1. #{text}") }
315
+ let(:li) { doc.root.children[0].children[0] }
316
+
317
+ it "should convert the first p element to '.IP \\\\n+[step0]\\n...'" do
318
+ expect(subject.convert_ol_li(li)).to eq(".IP \\n+[step0]\n#{text}")
319
+ end
320
+
321
+ context "with multiple multiple paragraphs" do
322
+ let(:text1) { 'hello' }
323
+ let(:text2) { 'world' }
324
+ let(:doc) { Kramdown::Document.new("1. #{text1}\n\n #{text2}") }
325
+
326
+ it "should convert the other p elements to '.IP \\\\n\\n...'" do
327
+ expect(subject.convert_ol_li(li)).to eq([
328
+ ".IP \\n+[step0]",
329
+ text1,
330
+ ".IP \\n",
331
+ text2
332
+ ].join("\n"))
333
+ end
334
+ end
335
+ end
336
+
337
+ describe "#convert_abbreviation" do
338
+ let(:acronym) { 'HTML' }
339
+ let(:definition) { 'Hyper Text Markup Language' }
340
+ let(:doc) { Kramdown::Document.new("This is an #{acronym} example.\n\n*[#{acronym}]: #{definition}") }
341
+ let(:abbreviation) { doc.root.children[0].children[1] }
342
+
343
+ it "should convert abbreviation elements into their text" do
344
+ expect(subject.convert_abbreviation(abbreviation)).to eq(acronym)
345
+ end
346
+ end
347
+
348
+ describe "#convert_blockquote" do
349
+ let(:text) { "Some quote." }
350
+ let(:escaped_text) { 'Some quote\.' }
351
+ let(:doc) { Kramdown::Document.new("> #{text}") }
352
+ let(:blockquote) { doc.root.children[0] }
353
+
354
+ it "should convert blockquote elements into '.PP\\n.RS\\ntext...\\n.RE'" do
355
+ expect(subject.convert_blockquote(blockquote)).to eq(".PP\n.RS\n#{escaped_text}\n.RE")
356
+ end
357
+ end
358
+
359
+ describe "#convert_codeblock" do
360
+ let(:code) { "puts 'hello world'" }
361
+ let(:escaped_code) { 'puts \(aqhello world\(aq' }
362
+ let(:doc) { Kramdown::Document.new(" #{code}\n") }
363
+ let(:codeblock) { doc.root.children[0] }
364
+
365
+ it "should convert codeblock elements into '.nf\\ntext...\\n.fi'" do
366
+ expect(subject.convert_codeblock(codeblock)).to eq(".nf\n#{escaped_code}\n.fi")
367
+ end
368
+ end
369
+
370
+ describe "#convert_comment" do
371
+ let(:text) { "Copyright (c) 2013" }
372
+ let(:doc) { Kramdown::Document.new("{::comment}\n#{text}\n{:/comment}") }
373
+ let(:comment) { doc.root.children[0] }
374
+
375
+ it "should convert comment elements into '.\\\" text...'" do
376
+ expect(subject.convert_comment(comment)).to eq(".\\\" #{text}")
377
+ end
378
+ end
379
+
380
+ describe "#convert_p" do
381
+ let(:text) { "Hello world." }
382
+ let(:escaped_text) { 'Hello world\.' }
383
+ let(:doc) { Kramdown::Document.new(text) }
384
+ let(:p) { doc.root.children[0] }
385
+
386
+ it "should convert p elements into '.PP\\ntext'" do
387
+ expect(subject.convert_p(p)).to eq(".PP\n#{escaped_text}")
388
+ end
389
+
390
+ context "when the paragraph starts with a codespan element" do
391
+ let(:option) { '--foo' }
392
+ let(:text) { 'Foo bar baz' }
393
+ let(:doc) { Kramdown::Document.new("`#{option}`\n\t#{text}") }
394
+
395
+ it "should convert p elements into '.TP\\n\\fB--option\\fR\\ntext...'" do
396
+ expect(subject.convert_p(p)).to eq(".TP\n\\fB#{option}\\fR\n#{text}")
397
+ end
398
+
399
+ context "when there is only one codespan element" do
400
+ let(:code) { 'code' }
401
+ let(:doc) { Kramdown::Document.new("`#{code}`") }
402
+
403
+ it "should convert p elements into '.PP\\n\\fB...\\fR'" do
404
+ expect(subject.convert_p(p)).to eq(".PP\n\\fB#{code}\\fR")
405
+ end
406
+ end
407
+
408
+ context "when there are more than one codespan element" do
409
+ let(:flag) { '-f' }
410
+ let(:option) { '--foo' }
411
+ let(:text) { 'Foo bar baz' }
412
+ let(:doc) { Kramdown::Document.new("`#{flag}`, `#{option}`\n\t#{text}") }
413
+
414
+ it "should convert p elements into '.TP\\n\\fB-o\\fR, \\fB--option\\fR\\ntext...'" do
415
+ expect(subject.convert_p(p)).to eq(".TP\n\\fB#{flag}\\fR, \\fB#{option}\\fR\n#{text}")
416
+ end
417
+
418
+ context "when there is no newline" do
419
+ let(:doc) { Kramdown::Document.new("`#{flag}` `#{option}`") }
420
+
421
+ it "should convert the p element into a '.HP\\n...'" do
422
+ expect(subject.convert_p(p)).to eq(".HP\n\\fB#{flag}\\fR \\fB#{option}\\fR")
423
+ end
424
+ end
425
+ end
426
+ end
427
+
428
+ context "when the paragraph starts with a em element" do
429
+ let(:option) { '--foo' }
430
+ let(:escaped_option) { "\\-\\-foo" }
431
+ let(:text) { 'Foo bar baz' }
432
+
433
+ let(:doc) do
434
+ Kramdown::Document.new("*#{option}*\n\t#{text}")
435
+ end
436
+
437
+ it "should convert p elements into '.TP\\n\\fI--option\\fP\\ntext...'" do
438
+ expect(subject.convert_p(p)).to eq(".TP\n\\fI#{escaped_option}\\fP\n#{text}")
439
+ end
440
+
441
+ context "when there is only one em element" do
442
+ let(:text) { 'foo' }
443
+ let(:doc) { Kramdown::Document.new("*#{text}*") }
444
+
445
+ it "should convert p elements into '.PP\\n\\fI...\\fP'" do
446
+ expect(subject.convert_p(p)).to eq(".PP\n\\fI#{text}\\fP")
447
+ end
448
+ end
449
+
450
+ context "when there are more than one em element" do
451
+ let(:flag) { '-f' }
452
+ let(:escaped_flag) { "\\-f" }
453
+ let(:text) { 'Foo bar baz' }
454
+
455
+ let(:doc) do
456
+ Kramdown::Document.new("*#{flag}*, *#{option}*\n\t#{text}")
457
+ end
458
+
459
+ it "should convert p elements into '.TP\\n\\fI-o\\fP, \\fI\\-\\-option\\fP\\ntext...'" do
460
+ expect(subject.convert_p(p)).to eq(".TP\n\\fI#{escaped_flag}\\fP, \\fI#{escaped_option}\\fP\n#{text}")
461
+ end
462
+
463
+ context "when there is no newline" do
464
+ let(:doc) { Kramdown::Document.new("*#{flag}* *#{option}*") }
465
+
466
+ it "should convert the p element into a '.HP\\n...'" do
467
+ expect(subject.convert_p(p)).to eq(".HP\n\\fI#{escaped_flag}\\fP \\fI#{escaped_option}\\fP")
468
+ end
469
+ end
470
+ end
471
+ end
472
+ end
473
+
474
+ describe "#convert_em" do
475
+ let(:text) { "hello world" }
476
+ let(:doc) { Kramdown::Document.new("*#{text}*") }
477
+ let(:em) { doc.root.children[0].children[0] }
478
+
479
+ it "should convert em elements into '\\fItext\\fP'" do
480
+ expect(subject.convert_em(em)).to eq("\\fI#{text}\\fP")
481
+ end
482
+ end
483
+
484
+ describe "#convert_strong" do
485
+ let(:text) { "hello world" }
486
+ let(:doc) { Kramdown::Document.new("**#{text}**") }
487
+ let(:strong) { doc.root.children[0].children[0] }
488
+
489
+ it "should convert strong elements into '\\fBtext\\fP'" do
490
+ expect(subject.convert_strong(strong)).to eq("\\fB#{text}\\fP")
491
+ end
492
+ end
493
+
494
+ describe "#convert_codespan" do
495
+ let(:code) { "puts 'hello world'" }
496
+ let(:doc) { Kramdown::Document.new("`#{code}`") }
497
+ let(:codespan) { doc.root.children[0].children[0] }
498
+
499
+ it "should convert codespan elements into '\\fBcode\\fR'" do
500
+ expect(subject.convert_codespan(codespan)).to eq("\\fB#{code}\\fR")
501
+ end
502
+ end
503
+
504
+ describe "#convert_a" do
505
+ let(:text) { 'example' }
506
+ let(:href) { 'http://example.com/' }
507
+ let(:escaped_href) { 'http:\[sl]\[sl]example\.com\[sl]' }
508
+ let(:doc) { Kramdown::Document.new("[#{text}](#{href})") }
509
+ let(:link) { doc.root.children[0].children[0] }
510
+
511
+ it "should convert a link elements into 'text\\n.UR href\\n.UE'" do
512
+ expect(subject.convert_a(link)).to eq("#{text}\n.UR #{escaped_href}\n.UE")
513
+ end
514
+
515
+ context "when the href begins with mailto:" do
516
+ let(:text) { 'Bob' }
517
+ let(:email) { 'bob@example.com' }
518
+ let(:escaped_email) { 'bob\[at]example\.com' }
519
+ let(:doc) { Kramdown::Document.new("[#{text}](mailto:#{email})") }
520
+
521
+ it "should convert the link elements into '.MT email\\n.ME'" do
522
+ expect(subject.convert_a(link)).to eq("#{text}\n.MT #{escaped_email}\n.ME")
523
+ end
524
+
525
+ context "when link is <email>" do
526
+ let(:doc) { Kramdown::Document.new("<#{email}>") }
527
+
528
+ it "should convert the link elements into '.MT email\\n.ME'" do
529
+ expect(subject.convert_a(link)).to eq("\n.MT #{escaped_email}\n.ME")
530
+ end
531
+ end
532
+ end
533
+
534
+ context "when the href begins with man:" do
535
+ let(:man) { 'bash' }
536
+ let(:doc) { Kramdown::Document.new("[#{man}](man:#{man})") }
537
+
538
+ it "should convert the link elements into '.BR man'" do
539
+ expect(subject.convert_a(link)).to eq("\n.BR #{man}")
540
+ end
541
+
542
+ context "when a section number is specified" do
543
+ let(:section) { '1' }
544
+ let(:doc) { Kramdown::Document.new("[#{man}](man:#{man}(#{section}))") }
545
+
546
+ it "should convert the link elements into '.BR man (section)'" do
547
+ expect(subject.convert_a(link)).to eq("\n.BR #{man} (#{section})")
548
+ end
549
+ end
550
+ end
551
+ end
552
+
553
+ describe "#escape" do
554
+ let(:text) { "hello\nworld" }
555
+
556
+ described_class::GLYPHS.each do |char,glyph|
557
+ it "should convert #{char.dump} into #{glyph.dump}" do
558
+ expect(subject.escape("#{text} #{char}")).to eq("#{text} #{glyph}")
559
+ end
560
+ end
561
+ end
562
+ end