kramdown-man 0.1.9 → 1.0.0

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,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