kramdown-man 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +45 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +20 -0
- data/README.md +181 -0
- data/Rakefile +23 -0
- data/bin/kramdown-man +16 -0
- data/gemspec.yml +13 -0
- data/kramdown-man.gemspec +60 -0
- data/lib/kramdown/converter/man.rb +811 -0
- data/lib/kramdown/man.rb +5 -0
- data/lib/kramdown/man/task.rb +70 -0
- data/lib/kramdown/man/version.rb +6 -0
- data/man/kramdown-man.1 +183 -0
- data/man/kramdown-man.1.md +127 -0
- data/spec/kramdown/converter/man_spec.rb +562 -0
- data/spec/kramdown/document_spec.rb +19 -0
- data/spec/kramdown/man_spec.rb +8 -0
- data/spec/spec_helper.rb +2 -0
- metadata +97 -0
data/lib/kramdown/man.rb
ADDED
@@ -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
|
data/man/kramdown-man.1
ADDED
@@ -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
|