kramdown-man 0.1.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,969 @@
1
+ require 'spec_helper'
2
+ require 'kramdown/man/converter'
3
+
4
+ describe Kramdown::Man::Converter do
5
+ let(:markdown) { File.read('man/kramdown-man.1.md') }
6
+ let(:doc) { Kramdown::Document.new(markdown) }
7
+ let(:root) { doc.root }
8
+
9
+ subject { described_class.send(:new,root,{}) }
10
+
11
+ describe "#convert" do
12
+ let(:markdown) do
13
+ <<~MARKDOWN
14
+ # Header
15
+
16
+ Hello world.
17
+ MARKDOWN
18
+ end
19
+
20
+ let(:root) { doc.root }
21
+
22
+ it "should add the header" do
23
+ expect(subject.convert(root)).to eq(
24
+ <<~ROFF
25
+ #{described_class::HEADER.chomp}
26
+ .TH Header
27
+ .PP
28
+ Hello world\\.
29
+ ROFF
30
+ )
31
+ end
32
+ end
33
+
34
+ describe "#convert_root" do
35
+ let(:markdown) do
36
+ <<~MARKDOWN
37
+ # Header
38
+
39
+ Hello world.
40
+ MARKDOWN
41
+ end
42
+
43
+ let(:root) { doc.root }
44
+
45
+ it "should convert every element" do
46
+ expect(subject.convert_root(root)).to eq(
47
+ <<~ROFF
48
+ .TH Header
49
+ .PP
50
+ Hello world\\.
51
+ ROFF
52
+ )
53
+ end
54
+ end
55
+
56
+ describe "#convert_element" do
57
+ let(:markdown) { " 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(:markdown) do
67
+ <<~MARKDOWN
68
+ foo
69
+
70
+ bar
71
+ MARKDOWN
72
+ end
73
+
74
+ let(:blank) { doc.root.children[0].children[1] }
75
+
76
+ it "must return nil" do
77
+ expect(subject.convert_blank(blank)).to be(nil)
78
+ end
79
+ end
80
+
81
+ describe "#convert_text" do
82
+ let(:content) { 'Foo bar' }
83
+ let(:markdown) { content }
84
+ let(:text) { doc.root.children[0].children[0] }
85
+
86
+ it "should convert text elements" do
87
+ expect(subject.convert_text(text)).to eq(content)
88
+ end
89
+ end
90
+
91
+ describe "#convert_typographic_sym" do
92
+ context "ndash" do
93
+ let(:markdown) { "-- foo" }
94
+ let(:sym) { doc.root.children[0].children[0] }
95
+
96
+ it "should convert ndash symbols back into '\-\-'" do
97
+ expect(subject.convert_typographic_sym(sym)).to eq("\\-\\-")
98
+ end
99
+ end
100
+
101
+ context "mdash" do
102
+ let(:markdown) { "--- foo" }
103
+ let(:sym) { doc.root.children[0].children[0] }
104
+
105
+ it "should convert mdash symbols into '\[em]'" do
106
+ expect(subject.convert_typographic_sym(sym)).to eq('\[em]')
107
+ end
108
+ end
109
+
110
+ context "hellip" do
111
+ let(:markdown) { "... foo" }
112
+ let(:sym) { doc.root.children[0].children[0] }
113
+
114
+ it "should convert mdash symbols into '\\.\\.\\.'" do
115
+ expect(subject.convert_typographic_sym(sym)).to eq('\.\.\.')
116
+ end
117
+ end
118
+
119
+ context "laquo" do
120
+ let(:markdown) { "<< foo" }
121
+ let(:sym) { doc.root.children[0].children[0] }
122
+
123
+ it "should convert mdash symbols into '\[Fo]'" do
124
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fo]')
125
+ end
126
+ end
127
+
128
+ context "raquo" do
129
+ let(:markdown) { "foo >> bar" }
130
+ let(:sym) { doc.root.children[0].children[1] }
131
+
132
+ it "should convert mdash symbols into '\[Fc]'" do
133
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fc]')
134
+ end
135
+ end
136
+
137
+ context "laquo_space" do
138
+ let(:markdown) { " << foo" }
139
+ let(:sym) { doc.root.children[0].children[0] }
140
+
141
+ it "should convert mdash symbols into '\[Fo]'" do
142
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fo]')
143
+ end
144
+ end
145
+
146
+ context "raquo_space" do
147
+ let(:markdown) { "foo >> bar" }
148
+ let(:sym) { doc.root.children[0].children[1] }
149
+
150
+ it "should convert mdash symbols into '\[Fc]'" do
151
+ expect(subject.convert_typographic_sym(sym)).to eq('\[Fc]')
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "#convert_smart_quote" do
157
+ context "lsquo" do
158
+ let(:markdown) { "'hello world'" }
159
+ let(:quote) { doc.root.children[0].children.first }
160
+
161
+ it "should convert lsquo quotes into '\[oq]'" do
162
+ expect(subject.convert_smart_quote(quote)).to eq('\[oq]')
163
+ end
164
+ end
165
+
166
+ context "rsquo" do
167
+ let(:markdown) { "'hello world'" }
168
+ let(:quote) { doc.root.children[0].children.last }
169
+
170
+ it "should convert rsquo quotes into '\[cq]'" do
171
+ expect(subject.convert_smart_quote(quote)).to eq('\[cq]')
172
+ end
173
+ end
174
+
175
+ context "ldquo" do
176
+ let(:markdown) { '"hello world"' }
177
+ let(:quote) { doc.root.children[0].children.first }
178
+
179
+ it "should convert lsquo quotes into '\[lq]'" do
180
+ expect(subject.convert_smart_quote(quote)).to eq('\[lq]')
181
+ end
182
+ end
183
+
184
+ context "rdquo" do
185
+ let(:markdown) { '"hello world"' }
186
+ let(:quote) { doc.root.children[0].children.last }
187
+
188
+ it "should convert lsquo quotes into '\[rq]'" do
189
+ expect(subject.convert_smart_quote(quote)).to eq('\[rq]')
190
+ end
191
+ end
192
+ end
193
+
194
+ describe "#convert_header" do
195
+ let(:title) { 'Header' }
196
+
197
+ context "when level is 1" do
198
+ let(:markdown) { "# #{title}" }
199
+ let(:header) { doc.root.children[0] }
200
+
201
+ it "should convert level 1 headers into '.TH text'" do
202
+ expect(subject.convert_header(header)).to eq(
203
+ <<~ROFF
204
+ .TH #{title}
205
+ ROFF
206
+ )
207
+ end
208
+ end
209
+
210
+ context "when level is 2" do
211
+ let(:markdown) { "## #{title}" }
212
+ let(:header) { doc.root.children[0] }
213
+
214
+ it "should convert level 2 headers into '.SH text'" do
215
+ expect(subject.convert_header(header)).to eq(
216
+ <<~ROFF
217
+ .SH #{title}
218
+ ROFF
219
+ )
220
+ end
221
+ end
222
+
223
+ context "when level is 3" do
224
+ let(:markdown) { "### #{title}" }
225
+ let(:header) { doc.root.children[0] }
226
+
227
+ it "should convert level 2 headers into '.SS text'" do
228
+ expect(subject.convert_header(header)).to eq(
229
+ <<~ROFF
230
+ .SS #{title}
231
+ ROFF
232
+ )
233
+ end
234
+ end
235
+
236
+ context "when level is 4 or greater" do
237
+ let(:markdown) { "#### #{title}" }
238
+ let(:header) { doc.root.children[0] }
239
+
240
+ it "should convert level 2 headers into '.SS text'" do
241
+ expect(subject.convert_header(header)).to eq(
242
+ <<~ROFF
243
+ .SS #{title}
244
+ ROFF
245
+ )
246
+ end
247
+ end
248
+ end
249
+
250
+ describe "#convert_hr" do
251
+ let(:markdown) { '------------------------------------' }
252
+ let(:hr) { doc.root.children[0] }
253
+
254
+ it "must return nil" do
255
+ expect(subject.convert_hr(hr)).to be(nil)
256
+ end
257
+ end
258
+
259
+ describe "#convert_ul" do
260
+ let(:text1) { 'foo' }
261
+ let(:text2) { 'bar' }
262
+ let(:markdown) do
263
+ <<~MARKDOWN
264
+ * #{text1}
265
+ * #{text2}
266
+ MARKDOWN
267
+ end
268
+
269
+ let(:ul) { doc.root.children[0] }
270
+
271
+ it "should convert ul elements into '.RS\\n...\\n.RE\\n'" do
272
+ expect(subject.convert_ul(ul)).to eq(
273
+ <<~ROFF
274
+ .RS
275
+ .IP \\(bu 2
276
+ #{text1}
277
+ .IP \\(bu 2
278
+ #{text2}
279
+ .RE
280
+ ROFF
281
+ )
282
+ end
283
+ end
284
+
285
+ describe "#convert_ul_li" do
286
+ let(:text) { 'hello world' }
287
+ let(:markdown) { "* #{text}" }
288
+
289
+ let(:li) { doc.root.children[0].children[0] }
290
+
291
+ it "should convert the first p element to '.IP \\\\(bu 2\\n...'" do
292
+ expect(subject.convert_ul_li(li)).to eq(
293
+ <<~ROFF
294
+ .IP \\(bu 2
295
+ #{text}
296
+ ROFF
297
+ )
298
+ end
299
+
300
+ context "with multiple multiple paragraphs" do
301
+ let(:text1) { 'hello' }
302
+ let(:text2) { 'world' }
303
+ let(:markdown) do
304
+ <<~MARKDOWN
305
+ * #{text1}
306
+
307
+ #{text2}
308
+ MARKDOWN
309
+ end
310
+
311
+ it "should convert the other p elements to '.IP \\\\( 2\\n...'" do
312
+ expect(subject.convert_ul_li(li)).to eq(
313
+ <<~ROFF
314
+ .IP \\(bu 2
315
+ #{text1}
316
+ .IP \\( 2
317
+ #{text2}
318
+ ROFF
319
+ )
320
+ end
321
+ end
322
+ end
323
+
324
+ describe "#convert_ol" do
325
+ let(:text1) { 'foo' }
326
+ let(:text2) { 'bar' }
327
+ let(:markdown) do
328
+ <<~MARKDOWN
329
+ 1. #{text1}
330
+ 2. #{text2}
331
+ MARKDOWN
332
+ end
333
+
334
+ let(:ol) { doc.root.children[0] }
335
+
336
+ it "should convert ol elements into '.RS\\n...\\n.RE'" do
337
+ expect(subject.convert_ol(ol)).to eq(
338
+ <<~ROFF
339
+ .nr step1 0 1
340
+ .RS
341
+ .IP \\n+[step1]
342
+ #{text1}
343
+ .IP \\n+[step1]
344
+ #{text2}
345
+ .RE
346
+ ROFF
347
+ )
348
+ end
349
+ end
350
+
351
+ describe "#convert_ol_li" do
352
+ let(:text) { 'hello world' }
353
+ let(:markdown) { "1. #{text}" }
354
+
355
+ let(:li) { doc.root.children[0].children[0] }
356
+
357
+ it "should convert the first p element to '.IP \\\\n+[step0]\\n...'" do
358
+ expect(subject.convert_ol_li(li)).to eq(
359
+ <<~ROFF
360
+ .IP \\n+[step0]
361
+ #{text}
362
+ ROFF
363
+ )
364
+ end
365
+
366
+ context "with multiple multiple paragraphs" do
367
+ let(:text1) { 'hello' }
368
+ let(:text2) { 'world' }
369
+ let(:markdown) do
370
+ <<~MARKDOWN
371
+ 1. #{text1}
372
+
373
+ #{text2}
374
+ MARKDOWN
375
+ end
376
+
377
+ it "should convert the other p elements to '.IP \\\\n\\n...'" do
378
+ expect(subject.convert_ol_li(li)).to eq(
379
+ <<~ROFF
380
+ .IP \\n+[step0]
381
+ #{text1}
382
+ .IP \\n
383
+ #{text2}
384
+ ROFF
385
+ )
386
+ end
387
+ end
388
+ end
389
+
390
+ describe "#convert_dl" do
391
+ let(:term) { "foo bar" }
392
+ let(:definition) { "baz qux" }
393
+ let(:markdown) do
394
+ <<~MARKDOWN
395
+ #{term}
396
+ : #{definition}
397
+ MARKDOWN
398
+ end
399
+
400
+ let(:dl) { doc.root.children[0] }
401
+
402
+ it "must convert dl elements into '.TP\n...\n...'" do
403
+ expect(subject.convert_dl(dl)).to eq(
404
+ <<~ROFF
405
+ .TP
406
+ #{term}
407
+ #{definition}
408
+ ROFF
409
+ )
410
+ end
411
+
412
+ context "when there are multiple term lines" do
413
+ let(:term1) { "foo" }
414
+ let(:term2) { "bar" }
415
+ let(:markdown) do
416
+ <<~MARKDOWN
417
+ #{term1}
418
+ #{term2}
419
+ : #{definition}
420
+ MARKDOWN
421
+ end
422
+
423
+ it "must convert the multi-term dl element into '.TP\\nterm1\\n.TQ\\nterm2\\n...'" do
424
+ expect(subject.convert_dl(dl)).to eq(
425
+ <<~ROFF
426
+ .TP
427
+ #{term1}
428
+ .TQ
429
+ #{term2}
430
+ #{definition}
431
+ ROFF
432
+ )
433
+ end
434
+ end
435
+
436
+ context "when there are multiple definitions for a term" do
437
+ let(:term) { "foo" }
438
+ let(:definition1) { "Foo bar." }
439
+ let(:definition2) { "Baz qux." }
440
+ let(:markdown) do
441
+ <<~MARKDOWN
442
+ #{term}
443
+ : #{definition1}
444
+
445
+ : #{definition2}
446
+ MARKDOWN
447
+ end
448
+
449
+ let(:dl) { doc.root.children[0] }
450
+
451
+ let(:escaped_definition1) { definition1.gsub('.',"\\.") }
452
+ let(:escaped_definition2) { definition2.gsub('.',"\\.") }
453
+
454
+ it "must convert the following p children into '.RS\\n.PP\\n...\\n.RE'" do
455
+ expect(subject.convert_dl(dl)).to eq(
456
+ <<~ROFF
457
+ .TP
458
+ #{term}
459
+ #{escaped_definition1}
460
+ .RS
461
+ .PP
462
+ #{escaped_definition2}
463
+ .RE
464
+ ROFF
465
+ )
466
+ end
467
+ end
468
+ end
469
+
470
+ describe "#convert_dt" do
471
+ let(:word1) { "foo" }
472
+ let(:word2) { "bar" }
473
+ let(:word3) { "baz" }
474
+ let(:term) { "#{word1} `#{word2}` *#{word3}*" }
475
+ let(:definition) { "abc xyz" }
476
+ let(:markdown) do
477
+ <<~MARKDOWN
478
+ #{term}
479
+ : #{definition}
480
+ MARKDOWN
481
+ end
482
+
483
+ let(:dt) { doc.root.children[0].children[0] }
484
+
485
+ it "must convert the dt element into '.TP\n...'" do
486
+ expect(subject.convert_dt(dt)).to eq(
487
+ <<~ROFF
488
+ .TP
489
+ #{word1} \\fB#{word2}\\fR \\fI#{word3}\\fP
490
+ ROFF
491
+ )
492
+ end
493
+
494
+ context "when given the index: keyword" do
495
+ context "and it's greater than 1" do
496
+ it "must convert the dt element into '.TQ\n...'" do
497
+ expect(subject.convert_dt(dt, index: 1)).to eq(
498
+ <<~ROFF
499
+ .TQ
500
+ #{word1} \\fB#{word2}\\fR \\fI#{word3}\\fP
501
+ ROFF
502
+ )
503
+ end
504
+ end
505
+ end
506
+ end
507
+
508
+ describe "#convert_dd" do
509
+ let(:term) { "abc xyz" }
510
+ let(:word1) { "foo" }
511
+ let(:word2) { "bar" }
512
+ let(:word3) { "baz" }
513
+ let(:definition) { "#{word1} `#{word2}` *#{word3}*" }
514
+ let(:markdown) do
515
+ <<~MARKDOWN
516
+ #{term}
517
+ : #{definition}
518
+ MARKDOWN
519
+ end
520
+
521
+ let(:dd) { doc.root.children[0].children[1] }
522
+
523
+ it "must convert the children p element within the dd element" do
524
+ expect(subject.convert_dd(dd)).to eq(
525
+ <<~ROFF
526
+ #{word1} \\fB#{word2}\\fR \\fI#{word3}\\fP
527
+ ROFF
528
+ )
529
+ end
530
+
531
+ context "when the given index: is 0" do
532
+ context "and when the dd element contains multiple p children" do
533
+ let(:word4) { "qux" }
534
+ let(:definition1) { "#{word1} #{word2}" }
535
+ let(:definition2) { "`#{word3}` *#{word4}*" }
536
+ let(:markdown) do
537
+ <<~MARKDOWN
538
+ #{term}
539
+ : #{definition1}
540
+
541
+ #{definition2}
542
+ MARKDOWN
543
+ end
544
+
545
+ it "must convert the following p children into '.RS\\n.PP\\n...\\n.RE'" do
546
+ expect(subject.convert_dd(dd)).to eq(
547
+ <<~ROFF
548
+ #{word1} #{word2}
549
+ .RS
550
+ .PP
551
+ \\fB#{word3}\\fR \\fI#{word4}\\fP
552
+ .RE
553
+ ROFF
554
+ )
555
+ end
556
+ end
557
+ end
558
+
559
+ context "when the given index: is greater than 0" do
560
+ let(:word4) { "qux" }
561
+ let(:definition1) { "#{word1} #{word2}" }
562
+ let(:definition2) { "`#{word3}` *#{word4}*" }
563
+ let(:markdown) do
564
+ <<~MARKDOWN
565
+ #{term}
566
+ : #{definition1}
567
+
568
+ : #{definition2}
569
+ MARKDOWN
570
+ end
571
+
572
+ let(:dd) { doc.root.children[0].children[2] }
573
+
574
+ it "must convert the child elements into '.RS\\n...\\n.RE'" do
575
+ expect(subject.convert_dd(dd, index: 1)).to eq(
576
+ <<~ROFF
577
+ .RS
578
+ .PP
579
+ \\fB#{word3}\\fR \\fI#{word4}\\fP
580
+ .RE
581
+ ROFF
582
+ )
583
+ end
584
+ end
585
+ end
586
+
587
+ describe "#convert_abbreviation" do
588
+ let(:acronym) { 'HTML' }
589
+ let(:definition) { 'Hyper Text Markup Language' }
590
+ let(:markdown) do
591
+ <<~MARKDOWN
592
+ This is an #{acronym} example.
593
+
594
+ *[#{acronym}]: #{definition}
595
+ MARKDOWN
596
+ end
597
+
598
+ let(:abbreviation) { doc.root.children[0].children[1] }
599
+
600
+ it "should convert abbreviation elements into their text" do
601
+ expect(subject.convert_abbreviation(abbreviation)).to eq(acronym)
602
+ end
603
+ end
604
+
605
+ describe "#convert_blockquote" do
606
+ let(:text) { "Some quote." }
607
+ let(:markdown) do
608
+ <<~MARKDOWN
609
+ > #{text}
610
+ MARKDOWN
611
+ end
612
+ let(:escaped_text) { 'Some quote\.' }
613
+ let(:blockquote) { doc.root.children[0] }
614
+
615
+ it "should convert blockquote elements into '.RS\\n.PP\\ntext...\\n.RE'" do
616
+ expect(subject.convert_blockquote(blockquote)).to eq(
617
+ <<~ROFF
618
+ .RS
619
+ .PP
620
+ #{escaped_text}
621
+ .RE
622
+ ROFF
623
+ )
624
+ end
625
+ end
626
+
627
+ describe "#convert_codeblock" do
628
+ let(:code) { "puts 'hello world'" }
629
+ let(:escaped_code) { 'puts \(aqhello world\(aq' }
630
+ let(:markdown) do
631
+ " #{code}"
632
+ end
633
+
634
+ let(:codeblock) { doc.root.children[0] }
635
+
636
+ it "should convert codeblock elements into '.PP\\n.EX\\ntext...\\n.EE'" do
637
+ expect(subject.convert_codeblock(codeblock)).to eq(
638
+ <<~ROFF
639
+ .PP
640
+ .RS 4
641
+ .EX
642
+ #{escaped_code}
643
+ .EE
644
+ .RE
645
+ ROFF
646
+ )
647
+ end
648
+ end
649
+
650
+ describe "#convert_comment" do
651
+ let(:text) { "Copyright (c) 2013" }
652
+ let(:markdown) do
653
+ <<~MARKDOWN
654
+ {::comment}
655
+ #{text}
656
+ {:/comment}
657
+ MARKDOWN
658
+ end
659
+
660
+ let(:comment) { doc.root.children[0] }
661
+
662
+ it "should convert comment elements into '.\\\" text...'" do
663
+ expect(subject.convert_comment(comment)).to eq(
664
+ <<~ROFF
665
+ .\\\" #{text}
666
+ ROFF
667
+ )
668
+ end
669
+ end
670
+
671
+ describe "#convert_p" do
672
+ let(:text) { "Hello world." }
673
+ let(:markdown) { text }
674
+ let(:escaped_text) { 'Hello world\.' }
675
+
676
+ let(:p) { doc.root.children[0] }
677
+
678
+ it "should convert p elements into '.PP\\ntext'" do
679
+ expect(subject.convert_p(p)).to eq(
680
+ <<~ROFF
681
+ .PP
682
+ #{escaped_text}
683
+ ROFF
684
+ )
685
+ end
686
+ end
687
+
688
+ describe "#convert_em" do
689
+ let(:text) { "hello world" }
690
+ let(:markdown) { "*#{text}*" }
691
+
692
+ let(:em) { doc.root.children[0].children[0] }
693
+
694
+ it "should convert em elements into '\\fItext\\fP'" do
695
+ expect(subject.convert_em(em)).to eq("\\fI#{text}\\fP")
696
+ end
697
+ end
698
+
699
+ describe "#convert_strong" do
700
+ let(:text) { "hello world" }
701
+ let(:markdown) { "**#{text}**" }
702
+
703
+ let(:strong) { doc.root.children[0].children[0] }
704
+
705
+ it "should convert strong elements into '\\fBtext\\fP'" do
706
+ expect(subject.convert_strong(strong)).to eq("\\fB#{text}\\fP")
707
+ end
708
+ end
709
+
710
+ describe "#convert_codespan" do
711
+ let(:code) { "puts 'hello world'" }
712
+ let(:markdown) { "`#{code}`" }
713
+
714
+ let(:codespan) { doc.root.children[0].children[0] }
715
+
716
+ it "should convert codespan elements into '\\fBcode\\fR'" do
717
+ expect(subject.convert_codespan(codespan)).to eq("\\fB#{code}\\fR")
718
+ end
719
+ end
720
+
721
+ describe "#convert_a" do
722
+ let(:text) { 'example' }
723
+ let(:href) { 'http://example.com/' }
724
+ let(:markdown) { "[#{text}](#{href})" }
725
+ let(:escaped_href) { 'http:\[sl]\[sl]example\.com\[sl]' }
726
+
727
+ let(:link) { doc.root.children[0].children[0] }
728
+
729
+ it "should convert a link elements into 'text\\n.UR href\\n.UE'" do
730
+ expect(subject.convert_a(link)).to eq(
731
+ <<~ROFF
732
+ #{text}
733
+ .UR #{escaped_href}
734
+ .UE
735
+ ROFF
736
+ )
737
+ end
738
+
739
+ context "when the href is to another .1.md file" do
740
+ let(:man) { 'foo-bar' }
741
+ let(:section) { '1' }
742
+ let(:markdown) { "[#{man}](#{man}.#{section}.md)" }
743
+
744
+ let(:escaped_man) { man.gsub('-','\\-') }
745
+
746
+ it "should convert the link elements into '.BR page (section)'" do
747
+ expect(subject.convert_a(link)).to eq(
748
+ <<~ROFF
749
+ .BR #{escaped_man} (#{section})
750
+ ROFF
751
+ )
752
+ end
753
+ end
754
+
755
+ context "when the href begins with mailto:" do
756
+ let(:text) { 'Bob' }
757
+ let(:email) { 'bob@example.com' }
758
+ let(:markdown) { "[#{text}](mailto:#{email})" }
759
+
760
+ let(:escaped_email) { 'bob\[at]example\.com' }
761
+
762
+ it "should convert the link elements into '.MT email\\n.ME'" do
763
+ expect(subject.convert_a(link)).to eq(
764
+ <<~ROFF
765
+ #{text}
766
+ .MT #{escaped_email}
767
+ .ME
768
+ ROFF
769
+ )
770
+ end
771
+
772
+ context "when link is <email>" do
773
+ let(:markdown) { "<#{email}>" }
774
+
775
+ it "should convert the link elements into '.MT email\\n.ME'" do
776
+ expect(subject.convert_a(link)).to eq(
777
+ <<~ROFF
778
+ .MT #{escaped_email}
779
+ .ME
780
+ ROFF
781
+ )
782
+ end
783
+ end
784
+ end
785
+
786
+ context "when the href begins with man:" do
787
+ let(:man) { 'bash' }
788
+ let(:markdown) { "[#{man}](man:#{man})" }
789
+
790
+ it "should convert the link elements into '.BR man'" do
791
+ expect(subject.convert_a(link)).to eq(
792
+ <<~ROFF
793
+ .BR #{man}
794
+ ROFF
795
+ )
796
+ end
797
+
798
+ context "and when the path is of the form 'page(section)'" do
799
+ let(:section) { '1' }
800
+ let(:markdown) { "[#{man}](man:#{man}(#{section}))" }
801
+
802
+ it "should convert the link elements into '.BR page (section)'" do
803
+ expect(subject.convert_a(link)).to eq(
804
+ <<~ROFF
805
+ .BR #{man} (#{section})
806
+ ROFF
807
+ )
808
+ end
809
+ end
810
+
811
+ context "and when the path is of the form 'page.section'" do
812
+ let(:section) { '1' }
813
+ let(:markdown) { "[#{man}](man:#{man}.#{section})" }
814
+
815
+ it "should convert the link elements into '.BR page (section)'" do
816
+ expect(subject.convert_a(link)).to eq(
817
+ <<~ROFF
818
+ .BR #{man} (#{section})
819
+ ROFF
820
+ )
821
+ end
822
+ end
823
+
824
+ context "when the path ends with a file extension" do
825
+ let(:file) { 'shard.yml' }
826
+ let(:escaped_file) { file.gsub('.','\\.') }
827
+ let(:markdown) { "[#{man}](man:#{file})" }
828
+
829
+ it "should convert the link elements into '.BR file'" do
830
+ expect(subject.convert_a(link)).to eq(
831
+ <<~ROFF
832
+ .BR #{escaped_file}
833
+ ROFF
834
+ )
835
+ end
836
+ end
837
+ end
838
+ end
839
+
840
+ describe "#man_page_link" do
841
+ let(:man) { 'foo-bar' }
842
+
843
+ let(:escaped_man) { man.gsub('-','\\-') }
844
+
845
+ it "should convert the link elements into '.BR man'" do
846
+ expect(subject.man_page_link(man)).to eq(
847
+ <<~ROFF
848
+ .BR #{escaped_man}
849
+ ROFF
850
+ )
851
+ end
852
+
853
+ context "when a section argument is given" do
854
+ let(:section) { '1' }
855
+
856
+ it "should convert the link elements into '.BR page (section)'" do
857
+ expect(subject.man_page_link(man,section)).to eq(
858
+ <<~ROFF
859
+ .BR #{escaped_man} (#{section})
860
+ ROFF
861
+ )
862
+ end
863
+ end
864
+ end
865
+
866
+ describe "#convert_children_of" do
867
+ let(:markdown) do
868
+ <<~MARKDOWN
869
+ A paragraph
870
+
871
+ * a list
872
+ MARKDOWN
873
+ end
874
+
875
+ let(:element) { doc.root }
876
+
877
+ it "must convert each element and join them into a String" do
878
+ expect(subject.convert_children_of(element)).to eq(
879
+ [
880
+ subject.convert_element(element.children[0]),
881
+ subject.convert_element(element.children[2])
882
+ ].join
883
+ )
884
+ end
885
+
886
+ context "when the given elements contains an element that cannot be converted" do
887
+ let(:markdown) do
888
+ <<~MARKDOWN
889
+ A paragraph
890
+
891
+ ----------------------------------------------------------------------
892
+
893
+ * a list
894
+ MARKDOWN
895
+ end
896
+
897
+ it "must omit the non-convertable elements" do
898
+ expect(subject.convert_children_of(element)).to eq(
899
+ [
900
+ subject.convert_element(element.children[0]),
901
+ subject.convert_element(element.children[4])
902
+ ].join
903
+ )
904
+ end
905
+ end
906
+ end
907
+
908
+ describe "#convert_text_elements" do
909
+ let(:markdown) do
910
+ <<~MARKDOWN
911
+ Word *emphasis* **strong** `code`
912
+ MARKDOWN
913
+ end
914
+ let(:elements) { doc.root.children[0].children }
915
+
916
+ it "must convert each text element and join the results together" do
917
+ expect(subject.convert_text_elements(elements)).to eq(
918
+ [
919
+ subject.convert_element(elements[0]),
920
+ subject.convert_element(elements[1]),
921
+ subject.convert_element(elements[2]),
922
+ subject.convert_element(elements[3]),
923
+ subject.convert_element(elements[4]),
924
+ subject.convert_element(elements[5])
925
+ ].join
926
+ )
927
+ end
928
+
929
+ context "when the text elements contain a 'a' type element" do
930
+ let(:markdown) do
931
+ <<~MARKDOWN
932
+ Word1 [link](https://example.com) word2.
933
+ MARKDOWN
934
+ end
935
+
936
+ it "must remove leading spaces from each line" do
937
+ expect(subject.convert_text_elements(elements)).to_not match(/^ /)
938
+ end
939
+ end
940
+
941
+ context "when the text elements contain consecutive 'a' elements" do
942
+ let(:markdown) do
943
+ <<~MARKDOWN
944
+ [link1](link1.html) [link2](link2.html) [link3](link3.html)
945
+ MARKDOWN
946
+ end
947
+
948
+ it "must avoid adding duplicate newlines" do
949
+ expect(subject.convert_text_elements(elements)).to eq(
950
+ [
951
+ subject.convert_element(elements[0]),
952
+ subject.convert_element(elements[2]),
953
+ subject.convert_element(elements[4]),
954
+ ].join
955
+ )
956
+ end
957
+ end
958
+ end
959
+
960
+ describe "#escape" do
961
+ let(:text) { "hello\nworld" }
962
+
963
+ described_class::GLYPHS.each do |char,glyph|
964
+ it "should convert #{char.dump} into #{glyph.dump}" do
965
+ expect(subject.escape("#{text} #{char}")).to eq("#{text} #{glyph}")
966
+ end
967
+ end
968
+ end
969
+ end