gimli 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gimli +1 -1
- data/lib/gimli/config.rb +0 -2
- data/lib/gimli/converter.rb +1 -1
- data/lib/gimli/markup.rb +6 -273
- data/lib/gimli/markup/code.rb +40 -0
- data/lib/gimli/markup/code_block.rb +28 -0
- data/lib/gimli/markup/renderer.rb +57 -0
- data/lib/gimli/markup/yaml_frontmatter_remover.rb +17 -0
- data/lib/gimli/markupfile.rb +1 -1
- data/lib/gimli/version.rb +1 -3
- data/lib/gimli/wkhtmltopdf.rb +1 -3
- data/spec/fixtures/integration/markdown.md +48 -0
- data/spec/fixtures/integration/style.css +3 -0
- data/spec/fixtures/integration/textile.textile +47 -0
- data/spec/gimli/markup/code_block_spec.rb +21 -0
- data/spec/gimli/markup/code_spec.rb +45 -0
- data/spec/gimli/{markup_spec.rb → markup/renderer_spec.rb} +3 -4
- data/spec/gimli/markup/yaml_frontmatter_remover_spec.rb +21 -0
- data/spec/gimli/markup_file_spec.rb +45 -0
- data/spec/gimli/wkhtmltopdf_spec.rb +18 -4
- data/spec/integration_spec.rb +41 -0
- metadata +28 -17
- data/spec/gimli/file_spec.rb +0 -28
data/bin/gimli
CHANGED
data/lib/gimli/config.rb
CHANGED
data/lib/gimli/converter.rb
CHANGED
@@ -29,7 +29,7 @@ module Gimli
|
|
29
29
|
def convert!
|
30
30
|
merged_contents = []
|
31
31
|
@files.each do |file|
|
32
|
-
markup = Markup.new file, @remove_front_matter
|
32
|
+
markup = Markup::Renderer.new file, @remove_front_matter
|
33
33
|
html = convert_image_urls markup.render, file.filename
|
34
34
|
if @merge
|
35
35
|
html = "<div class=\"page-break\"></div>#{html}" unless merged_contents.empty?
|
data/lib/gimli/markup.rb
CHANGED
@@ -16,280 +16,13 @@ require 'digest/sha1'
|
|
16
16
|
|
17
17
|
require 'github/markup'
|
18
18
|
require 'nokogiri'
|
19
|
-
require 'coderay'
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# Initialize a new Markup object.
|
26
|
-
#
|
27
|
-
# @param [Gimli::File] file The Gimli::File to process
|
28
|
-
# @param [Boolean] do_remove_yaml_front_matter Should we remove the front matter?
|
29
|
-
# @return [Gimli::Markup]
|
30
|
-
def initialize(file, do_remove_yaml_front_matter = false)
|
31
|
-
@filename = file.filename
|
32
|
-
@name = file.name
|
33
|
-
@data = file.data
|
34
|
-
@format = file.format
|
35
|
-
@tagmap = {}
|
36
|
-
@codemap = {}
|
37
|
-
@premap = {}
|
38
|
-
@do_remove_yaml_front_matter = do_remove_yaml_front_matter
|
39
|
-
end
|
40
|
-
|
41
|
-
# Render the content with Gollum wiki syntax on top of the file's own
|
42
|
-
# markup language.
|
43
|
-
#
|
44
|
-
# @return [String] The formatted data
|
45
|
-
def render
|
46
|
-
data = @data.dup
|
47
|
-
data = remove_yaml_front_matter(data) if @do_remove_yaml_front_matter
|
48
|
-
data = extract_code(data)
|
49
|
-
data = extract_tags(data)
|
50
|
-
begin
|
51
|
-
data = data.force_encoding('utf-8') if data.respond_to? :force_encoding
|
52
|
-
data = GitHub::Markup.render(@filename, data)
|
53
|
-
if data.nil?
|
54
|
-
raise "There was an error converting #{@name} to HTML."
|
55
|
-
end
|
56
|
-
rescue Object => e
|
57
|
-
data = %{<p class="gimli-error">#{e.message}</p>}
|
58
|
-
end
|
59
|
-
data = process_tags(data)
|
60
|
-
data = process_code(data)
|
61
|
-
|
62
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(data, 'UTF-8')
|
63
|
-
yield doc if block_given?
|
64
|
-
data = doc_to_html(doc)
|
65
|
-
|
66
|
-
data.gsub!(/<p><\/p>/, '')
|
67
|
-
data
|
68
|
-
end
|
69
|
-
|
70
|
-
def doc_to_html(doc)
|
71
|
-
doc.to_xhtml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XHTML, :encoding => 'UTF-8')
|
72
|
-
end
|
73
|
-
|
74
|
-
# Removes YAML Front Matter
|
75
|
-
# Useful if you want to PDF your Jekyll site.
|
76
|
-
#
|
77
|
-
# @param [String] data - The raw string data.
|
78
|
-
# @return [String] Returns the string data with frontmatter removed
|
79
|
-
def remove_yaml_front_matter(data)
|
80
|
-
data.gsub(/^(---\s*\n.*?\n?)^(---\s*$\n?)/m, '')
|
81
|
-
end
|
82
|
-
|
83
|
-
# Extract all tags into the tagmap and replace with placeholders.
|
84
|
-
#
|
85
|
-
# @param [String] data - The raw string data.
|
86
|
-
# @return [String] Returns the placeholder's string data.
|
87
|
-
def extract_tags(data)
|
88
|
-
data.gsub!(/(.?)\[\[(.+?)\]\]([^\[]?)/m) do
|
89
|
-
if $1 == "'" && $3 != "'"
|
90
|
-
"[[#{$2}]]#{$3}"
|
91
|
-
elsif $2.include?('][')
|
92
|
-
if $2[0..4] == 'file:'
|
93
|
-
pre = $1
|
94
|
-
post = $3
|
95
|
-
parts = $2.split('][')
|
96
|
-
parts[0][0..4] = ""
|
97
|
-
link = "#{parts[1]}|#{parts[0].sub(/\.org/,'')}"
|
98
|
-
id = Digest::SHA1.hexdigest(link)
|
99
|
-
@tagmap[id] = link
|
100
|
-
"#{pre}#{id}#{post}"
|
101
|
-
else
|
102
|
-
$&
|
103
|
-
end
|
104
|
-
else
|
105
|
-
id = Digest::SHA1.hexdigest($2)
|
106
|
-
@tagmap[id] = $2
|
107
|
-
"#{$1}#{id}#{$3}"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
data
|
111
|
-
end
|
112
|
-
|
113
|
-
# Process all tags from the tagmap and replace the placeholders with the
|
114
|
-
# final markup.
|
115
|
-
#
|
116
|
-
# @param [String] data - The data (with placeholders)
|
117
|
-
# @return [String] Returns the marked up String data.
|
118
|
-
def process_tags(data)
|
119
|
-
@tagmap.each do |id, tag|
|
120
|
-
data.gsub!(id, process_tag(tag))
|
121
|
-
end
|
122
|
-
data
|
123
|
-
end
|
124
|
-
|
125
|
-
# Process a single tag into its final HTML form.
|
126
|
-
#
|
127
|
-
# @param [String] tag The String tag contents (the stuff inside the double brackets).
|
128
|
-
# @return [String] Returns the String HTML version of the tag.
|
129
|
-
def process_tag(tag)
|
130
|
-
if html = process_image_tag(tag)
|
131
|
-
html
|
132
|
-
elsif html = process_file_link_tag(tag)
|
133
|
-
html
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Attempt to process the tag as an image tag.
|
138
|
-
#
|
139
|
-
# @param [String] tag The String tag contents (the stuff inside the double brackets).
|
140
|
-
# @return [String|nil] Returns the String HTML if the tag is a valid image tag or nil if it is not.
|
141
|
-
def process_image_tag(tag)
|
142
|
-
parts = tag.split('|')
|
143
|
-
return if parts.size.zero?
|
144
|
-
|
145
|
-
name = parts[0].strip
|
146
|
-
path = name
|
147
|
-
|
148
|
-
if path
|
149
|
-
opts = parse_image_tag_options(tag)
|
150
|
-
|
151
|
-
containered = false
|
152
|
-
|
153
|
-
classes = [] # applied to whatever the outermost container is
|
154
|
-
attrs = [] # applied to the image
|
155
|
-
|
156
|
-
align = opts['align']
|
157
|
-
if opts['float']
|
158
|
-
containered = true
|
159
|
-
align ||= 'left'
|
160
|
-
if %w{left right}.include?(align)
|
161
|
-
classes << "float-#{align}"
|
162
|
-
end
|
163
|
-
elsif %w{top texttop middle absmiddle bottom absbottom baseline}.include?(align)
|
164
|
-
attrs << %{align="#{align}"}
|
165
|
-
elsif align
|
166
|
-
if %w{left center right}.include?(align)
|
167
|
-
containered = true
|
168
|
-
classes << "align-#{align}"
|
169
|
-
end
|
170
|
-
end
|
20
|
+
require 'gimli/markup/yaml_frontmatter_remover'
|
21
|
+
require 'gimli/markup/code'
|
22
|
+
require 'gimli/markup/code_block'
|
23
|
+
require 'gimli/markup/renderer'
|
171
24
|
|
172
|
-
|
173
|
-
|
174
|
-
attrs << %{width="#{width}"}
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
if height = opts['height']
|
179
|
-
if height =~ /^\d+(\.\d+)?(em|px)$/
|
180
|
-
attrs << %{height="#{height}"}
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
if alt = opts['alt']
|
185
|
-
attrs << %{alt="#{alt}"}
|
186
|
-
end
|
187
|
-
|
188
|
-
attr_string = attrs.size > 0 ? attrs.join(' ') + ' ' : ''
|
189
|
-
|
190
|
-
if opts['frame'] || containered
|
191
|
-
classes << 'frame' if opts['frame']
|
192
|
-
%{<span class="#{classes.join(' ')}">} +
|
193
|
-
%{<span>} +
|
194
|
-
%{<img src="#{path}" #{attr_string}/>} +
|
195
|
-
(alt ? %{<span>#{alt}</span>} : '') +
|
196
|
-
%{</span>} +
|
197
|
-
%{</span>}
|
198
|
-
else
|
199
|
-
%{<img src="#{path}" #{attr_string}/>}
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
# Parse any options present on the image tag and extract them into a
|
205
|
-
# Hash of option names and values.
|
206
|
-
#
|
207
|
-
# @param [String] tag The String tag contents (the stuff inside the double brackets).
|
208
|
-
# @return [Hash]
|
209
|
-
# Returns the options Hash:
|
210
|
-
# key - The String option name.
|
211
|
-
# val - The String option value or true if it is a binary option.
|
212
|
-
def parse_image_tag_options(tag)
|
213
|
-
tag.split('|')[1..-1].inject({}) do |memo, attr|
|
214
|
-
parts = attr.split('=').map { |x| x.strip }
|
215
|
-
memo[parts[0]] = (parts.size == 1 ? true : parts[1])
|
216
|
-
memo
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# Extract all code blocks into the codemap and replace with placeholders.
|
221
|
-
#
|
222
|
-
# @param [String] data The raw String data.
|
223
|
-
# @return [String] Returns the placeholder'd String data.
|
224
|
-
def extract_code(data)
|
225
|
-
data.gsub!(/^``` ?([^\r\n]+)?\r?\n(.+?)\r?\n```\r?$/m) do
|
226
|
-
id = Digest::SHA1.hexdigest($2)
|
227
|
-
cached = check_cache(:code, id)
|
228
|
-
@codemap[id] = cached ?
|
229
|
-
{ :output => cached } :
|
230
|
-
{ :lang => $1, :code => $2 }
|
231
|
-
id
|
232
|
-
end
|
233
|
-
data
|
234
|
-
end
|
235
|
-
|
236
|
-
# Process all code from the codemap and replace the placeholders with the
|
237
|
-
# final HTML.
|
238
|
-
#
|
239
|
-
# @param [String] data The String data (with placeholders).
|
240
|
-
# @return [String] Returns the marked up String data.
|
241
|
-
def process_code(data)
|
242
|
-
return data if data.nil? || data.size.zero? || @codemap.size.zero?
|
243
|
-
blocks = []
|
244
|
-
@codemap.each do |id, spec|
|
245
|
-
next if spec[:output] # cached
|
246
|
-
|
247
|
-
code = spec[:code]
|
248
|
-
if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ }
|
249
|
-
code.gsub!(/^( |\t)/m, '')
|
250
|
-
end
|
251
|
-
|
252
|
-
if RUBY_VERSION =~ /1\.8\../
|
253
|
-
require 'iconv'
|
254
|
-
code = Iconv.conv('ISO-8859-1//IGNORE', 'utf-8', code)
|
255
|
-
else
|
256
|
-
code = code.encode('ISO-8859-1', 'utf-8')
|
257
|
-
end
|
258
|
-
|
259
|
-
blocks << [spec[:lang], code]
|
260
|
-
end
|
261
|
-
|
262
|
-
@codemap.each do |id, spec|
|
263
|
-
body = spec[:output] || begin
|
264
|
-
if spec[:lang]
|
265
|
-
CodeRay.scan(spec[:code], spec[:lang]).html(:line_numbers => :table)
|
266
|
-
else
|
267
|
-
CodeRay.scan(spec[:code], :text).div
|
268
|
-
end
|
269
|
-
end
|
270
|
-
body = body.force_encoding('utf-8') if body.respond_to? :force_encoding
|
271
|
-
data.gsub!(id, body)
|
272
|
-
end
|
273
|
-
|
274
|
-
data
|
275
|
-
end
|
276
|
-
|
277
|
-
# Hook for getting the formatted value of extracted tag data.
|
278
|
-
#
|
279
|
-
# @param [Symbol] type Symbol value identifying what type of data is being extracted.
|
280
|
-
# @param [String] id String SHA1 hash of original extracted tag data.
|
281
|
-
# @return [String] Returns the String cached formatted data, or nil.
|
282
|
-
def check_cache(type, id)
|
283
|
-
end
|
284
|
-
|
285
|
-
# Hook for caching the formatted value of extracted tag data.
|
286
|
-
#
|
287
|
-
# @param [Symbol] type Symbol value identifying what type of data is being extracted.
|
288
|
-
# @param [String] id String SHA1 hash of original extracted tag data.
|
289
|
-
# @param [String] data The String formatted value to be cached.
|
290
|
-
# @return [nil]
|
291
|
-
def update_cache(type, id, data)
|
292
|
-
end
|
25
|
+
module Gimli
|
26
|
+
module Markup
|
293
27
|
end
|
294
28
|
end
|
295
|
-
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Gimli
|
4
|
+
|
5
|
+
module Markup
|
6
|
+
|
7
|
+
# Class that knows how to extract code blocks and render them with syntax highlightning
|
8
|
+
class Code
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@code_blocks = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Extract all code blocks into the codemap and replace with placeholders.
|
15
|
+
#
|
16
|
+
# @return [String] Returns the placeholder'd String data.
|
17
|
+
def extract(data)
|
18
|
+
data.gsub!(/^``` ?([^\r\n]+)?\r?\n(.+?)\r?\n```\r?$/m) do
|
19
|
+
id = Digest::SHA1.hexdigest($2)
|
20
|
+
@code_blocks << CodeBlock.new(id, $1, $2)
|
21
|
+
id
|
22
|
+
end
|
23
|
+
data
|
24
|
+
end
|
25
|
+
|
26
|
+
# Process all code from the codemap and replace the placeholders with the
|
27
|
+
# final HTML.
|
28
|
+
#
|
29
|
+
# @return [String] Returns the marked up String data.
|
30
|
+
def process(data)
|
31
|
+
return data if data.nil? || data.size.zero? || @code_blocks.size.zero?
|
32
|
+
@code_blocks.each do |block|
|
33
|
+
data.gsub!(block.id, block.highlighted)
|
34
|
+
end
|
35
|
+
data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'coderay'
|
4
|
+
|
5
|
+
module Gimli
|
6
|
+
|
7
|
+
module Markup
|
8
|
+
|
9
|
+
# Class that contains data for a code block
|
10
|
+
class CodeBlock
|
11
|
+
attr_reader :id, :language, :code
|
12
|
+
|
13
|
+
def initialize(id, language, code)
|
14
|
+
@id, @language, @code = id, language, code
|
15
|
+
end
|
16
|
+
|
17
|
+
def highlighted
|
18
|
+
if @language
|
19
|
+
CodeRay.scan(@code, @language).html(:line_numbers => :table)
|
20
|
+
else
|
21
|
+
CodeRay.scan(@code, :text).div
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Gimli
|
4
|
+
|
5
|
+
module Markup
|
6
|
+
|
7
|
+
# Contains functionality to render html from a markup file
|
8
|
+
class Renderer
|
9
|
+
# Initialize a new Markup object.
|
10
|
+
#
|
11
|
+
# @param [Gimli::File] file The Gimli::File to process
|
12
|
+
# @param [Boolean] do_remove_yaml_front_matter Should we remove the front matter?
|
13
|
+
# @return [Gimli::Markup]
|
14
|
+
def initialize(file, do_remove_yaml_front_matter = false)
|
15
|
+
@filename = file.filename
|
16
|
+
@name = file.name
|
17
|
+
@data = file.data
|
18
|
+
@do_remove_yaml_front_matter = do_remove_yaml_front_matter
|
19
|
+
end
|
20
|
+
|
21
|
+
# Render the content with Gollum wiki syntax on top of the file's own
|
22
|
+
# markup language.
|
23
|
+
#
|
24
|
+
# @return [String] The formatted data
|
25
|
+
def render
|
26
|
+
data = @data.dup
|
27
|
+
@code = Code.new
|
28
|
+
@yaml_frontmatter_remover = YamlFrontmatterRemover.new
|
29
|
+
data = @yaml_frontmatter_remover.process(data) if @do_remove_yaml_front_matter
|
30
|
+
data = @code.extract(data)
|
31
|
+
begin
|
32
|
+
data = data.force_encoding('utf-8') if data.respond_to? :force_encoding
|
33
|
+
data = GitHub::Markup.render(@filename, data)
|
34
|
+
if data.nil?
|
35
|
+
raise "There was an error converting #{@name} to HTML."
|
36
|
+
end
|
37
|
+
rescue Object => e
|
38
|
+
data = %{<p class="gimli-error">#{e.message}</p>}
|
39
|
+
end
|
40
|
+
data = @code.process(data)
|
41
|
+
|
42
|
+
doc = Nokogiri::HTML::DocumentFragment.parse(data, 'UTF-8')
|
43
|
+
yield doc if block_given?
|
44
|
+
data = doc_to_html(doc)
|
45
|
+
|
46
|
+
data.gsub!(/<p><\/p>/, '')
|
47
|
+
data
|
48
|
+
end
|
49
|
+
|
50
|
+
def doc_to_html(doc)
|
51
|
+
doc.to_xhtml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XHTML, :encoding => 'UTF-8')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Gimli
|
4
|
+
|
5
|
+
module Markup
|
6
|
+
|
7
|
+
# Class that knows how to remove yaml front matter
|
8
|
+
class YamlFrontmatterRemover
|
9
|
+
|
10
|
+
# Removes YAML Front Matter
|
11
|
+
# Useful if you want to PDF your Jekyll site.
|
12
|
+
def process(data)
|
13
|
+
data.gsub /^(---\s*\n.*?\n?)^(---\s*$\n?)/m, ''
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/gimli/markupfile.rb
CHANGED
data/lib/gimli/version.rb
CHANGED
data/lib/gimli/wkhtmltopdf.rb
CHANGED
@@ -16,7 +16,7 @@ module Gimli
|
|
16
16
|
args = command(filename)
|
17
17
|
invoke = args.join(' ')
|
18
18
|
|
19
|
-
|
19
|
+
IO.popen(invoke, "wb+") do |pdf|
|
20
20
|
pdf.puts(html)
|
21
21
|
pdf.close_write
|
22
22
|
pdf.gets(nil)
|
@@ -35,7 +35,5 @@ module Gimli
|
|
35
35
|
def bin
|
36
36
|
@bin ||= "\"#{(`which wkhtmltopdf`).chomp}\""
|
37
37
|
end
|
38
|
-
|
39
38
|
end
|
40
|
-
|
41
39
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Test file
|
2
|
+
|
3
|
+
* A
|
4
|
+
* Simple
|
5
|
+
* List
|
6
|
+
|
7
|
+
***
|
8
|
+
|
9
|
+
1. A
|
10
|
+
2. Numbered
|
11
|
+
3. List
|
12
|
+
|
13
|
+
## Tests
|
14
|
+
|
15
|
+
### Link
|
16
|
+
|
17
|
+
* http://google.com
|
18
|
+
* <http://google.com>
|
19
|
+
* [an example](http://example.com/ "Title")
|
20
|
+
* [Google][]
|
21
|
+
|
22
|
+
### Image
|
23
|
+
|
24
|
+
![Alt text](https://www.google.se/images/srpr/logo3w.png)
|
25
|
+
|
26
|
+
### Blockquote
|
27
|
+
|
28
|
+
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
29
|
+
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
30
|
+
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
31
|
+
>
|
32
|
+
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
33
|
+
> id sem consectetuer libero luctus adipiscing.
|
34
|
+
|
35
|
+
### Code
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
puts 'Hello world!'
|
39
|
+
(1..10).each do |number|
|
40
|
+
p number
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
## Subheading
|
45
|
+
|
46
|
+
**Lorem** ipsum __dolor__ sit *amet*, _consectetur_ adipiscing elit. Phasellus aliquet hendrerit velit eu bibendum. Phasellus et metus at velit vulputate posuere ac a turpis. Vivamus lobortis lectus at augue pretium vel dictum enim mollis. Fusce quis urna eget urna porta vulputate. Mauris eget sapien quis orci auctor adipiscing ac vitae magna. Nulla mauris quam, convallis porta tincidunt quis, imperdiet vitae magna. Maecenas orci odio, ullamcorper et ullamcorper nec, commodo ut lacus. Morbi tortor nulla, facilisis id laoreet non, imperdiet scelerisque sapien. Cras posuere arcu mauris. Nullam ac arcu tellus, a pharetra tellus. Nulla ac odio felis, nec porttitor nisi. Mauris fringilla adipiscing urna, vel ullamcorper felis congue et. Sed sollicitudin tempor odio, vel dignissim diam facilisis et. Nam rhoncus lacinia commodo.
|
47
|
+
|
48
|
+
[Google]: http://google.com/
|
@@ -0,0 +1,47 @@
|
|
1
|
+
h1. Test file
|
2
|
+
|
3
|
+
* A
|
4
|
+
* Simple
|
5
|
+
* List
|
6
|
+
|
7
|
+
***
|
8
|
+
|
9
|
+
# A
|
10
|
+
# Numbered
|
11
|
+
# List
|
12
|
+
|
13
|
+
h2. Tests
|
14
|
+
|
15
|
+
h3. Link
|
16
|
+
|
17
|
+
* http://google.com
|
18
|
+
* "an example":http://example.com/
|
19
|
+
* Google[1]
|
20
|
+
|
21
|
+
h3. Image
|
22
|
+
|
23
|
+
!https://www.google.se/images/srpr/logo3w.png!
|
24
|
+
|
25
|
+
h3. Blockquote
|
26
|
+
|
27
|
+
bq. This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
28
|
+
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
29
|
+
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
30
|
+
|
31
|
+
bq. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
32
|
+
id sem consectetuer libero luctus adipiscing.
|
33
|
+
|
34
|
+
h3. Code
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
puts 'Hello world!'
|
38
|
+
(1..10).each do |number|
|
39
|
+
p number
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
## Subheading
|
44
|
+
|
45
|
+
*Lorem* ipsum -dolor- sit ~amet~, _consectetur_ adipiscing elit. Phasellus aliquet hendrerit velit eu bibendum. Phasellus et metus at velit vulputate posuere ac a turpis. Vivamus lobortis lectus at augue pretium vel dictum enim mollis. Fusce quis urna eget urna porta vulputate. Mauris eget sapien quis orci auctor adipiscing ac vitae magna. Nulla mauris quam, convallis porta tincidunt quis, imperdiet vitae magna. Maecenas orci odio, ullamcorper et ullamcorper nec, commodo ut lacus. Morbi tortor nulla, facilisis id laoreet non, imperdiet scelerisque sapien. Cras posuere arcu mauris. Nullam ac arcu tellus, a pharetra tellus. Nulla ac odio felis, nec porttitor nisi. Mauris fringilla adipiscing urna, vel ullamcorper felis congue et. Sed sollicitudin tempor odio, vel dignissim diam facilisis et. Nam rhoncus lacinia commodo.
|
46
|
+
|
47
|
+
http://google.com/[1]
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
require './lib/gimli'
|
6
|
+
require './lib/gimli/markup'
|
7
|
+
|
8
|
+
describe Gimli::Markup::CodeBlock do
|
9
|
+
|
10
|
+
it 'should highlight code if language is supplied' do
|
11
|
+
code_block = Gimli::Markup::CodeBlock.new('1', 'ruby', 'puts "hi"')
|
12
|
+
code_block.highlighted.should include('class="CodeRay"')
|
13
|
+
code_block.highlighted.should include('class="delimiter"')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should highlight code if no language is supplied' do
|
17
|
+
code_block = Gimli::Markup::CodeBlock.new('1', nil, 'puts "hi"')
|
18
|
+
code_block.highlighted.should include('class="CodeRay"')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
require './lib/gimli'
|
6
|
+
require './lib/gimli/markup'
|
7
|
+
|
8
|
+
describe Gimli::Markup::Code do
|
9
|
+
|
10
|
+
before do
|
11
|
+
@code = Gimli::Markup::Code.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should extract code block with language' do
|
15
|
+
language = 'ruby'
|
16
|
+
code = "\tputs 'hi'"
|
17
|
+
markup = "```#{language}\n#{code}\n```"
|
18
|
+
@code.extract(markup)
|
19
|
+
code_block = @code.instance_variable_get("@code_blocks").first
|
20
|
+
code_block.id.should eq Digest::SHA1.hexdigest(code)
|
21
|
+
code_block.language.should eq language
|
22
|
+
code_block.code.should eq code
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should extract code block without language' do
|
26
|
+
code = "\tputs 'hi'"
|
27
|
+
markup = "```\n#{code}\n```"
|
28
|
+
@code.extract(markup)
|
29
|
+
code_block = @code.instance_variable_get("@code_blocks").first
|
30
|
+
code_block.id.should eq Digest::SHA1.hexdigest(code)
|
31
|
+
code_block.language.should be nil
|
32
|
+
code_block.code.should eq code
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should process markup and give back code from id' do
|
36
|
+
language = 'ruby'
|
37
|
+
code = "\tputs 'hi'"
|
38
|
+
id = Digest::SHA1.hexdigest(code)
|
39
|
+
markup = "```#{language}\n#{code}\n```"
|
40
|
+
markup = @code.extract(markup)
|
41
|
+
code_block = @code.instance_variable_get("@code_blocks").first
|
42
|
+
@code.process(markup).should eq code_block.highlighted
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -4,16 +4,15 @@ require './spec/spec_helper'
|
|
4
4
|
|
5
5
|
require './lib/gimli'
|
6
6
|
|
7
|
-
describe Gimli::Markup do
|
7
|
+
describe Gimli::Markup::Renderer do
|
8
8
|
|
9
9
|
it "should remove yaml front matter if asked to" do
|
10
10
|
output = "<p>This should be at the top of the file</p>"
|
11
11
|
|
12
|
-
file = Gimli::MarkupFile.new File.expand_path('
|
13
|
-
markup = Gimli::Markup.new file, true
|
12
|
+
file = Gimli::MarkupFile.new File.expand_path('../../../fixtures/yaml_front_matter.textile', __FILE__)
|
13
|
+
markup = Gimli::Markup::Renderer.new file, true
|
14
14
|
|
15
15
|
markup.render.should == output
|
16
16
|
end
|
17
|
-
|
18
17
|
end
|
19
18
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
require './lib/gimli'
|
6
|
+
require './lib/gimli/markup'
|
7
|
+
|
8
|
+
describe Gimli::Markup::YamlFrontmatterRemover do
|
9
|
+
|
10
|
+
it 'should remove front matter' do
|
11
|
+
data = "---\nlayout: test\n---\n\n\nReal data"
|
12
|
+
expected = 'Real data'
|
13
|
+
Gimli::Markup::YamlFrontmatterRemover.new.process(data).should == expected
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should not modify string if no front matter exists' do
|
17
|
+
data = 'Should not be modified'
|
18
|
+
Gimli::Markup::YamlFrontmatterRemover.new.process(data).should == data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
require './lib/gimli'
|
6
|
+
|
7
|
+
describe Gimli::MarkupFile do
|
8
|
+
|
9
|
+
before do
|
10
|
+
@file = Gimli::MarkupFile.new 'fake'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should recognize valid format' do
|
14
|
+
@file.valid_format?('textile').should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should recognize invalid format' do
|
18
|
+
@file.valid_format?('abc123').should be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should recognize nil as invalid format' do
|
22
|
+
@file.valid_format?(nil).should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should give the name as the filename without the extension' do
|
26
|
+
file = Gimli::MarkupFile.new 'test.txt'
|
27
|
+
file.name.should == File.basename(file.filename, File.extname(file.filename))
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should know which formats that are valid' do
|
31
|
+
@file.load_format(:md).should eq :markdown
|
32
|
+
@file.load_format(:textile).should eq :textile
|
33
|
+
@file.load_format(:rdoc).should eq :rdoc
|
34
|
+
@file.load_format(:org).should eq :org
|
35
|
+
@file.load_format(:creole).should eq :creole
|
36
|
+
@file.load_format(:rst).should eq :rest
|
37
|
+
@file.load_format(:asciidoc).should eq :asciidoc
|
38
|
+
@file.load_format(:pod).should eq :pod
|
39
|
+
@file.load_format('1').should eq :roff
|
40
|
+
@file.load_format(:mediawiki).should eq :mediawiki
|
41
|
+
@file.load_format('fake').should be nil
|
42
|
+
@file.load_format(nil).should be nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -6,16 +6,30 @@ require './lib/gimli'
|
|
6
6
|
|
7
7
|
describe Gimli::Wkhtmltopdf do
|
8
8
|
|
9
|
+
before do
|
10
|
+
@wkhtmltopdf = Gimli::Wkhtmltopdf.new
|
11
|
+
end
|
12
|
+
|
9
13
|
it 'should assemble correct command' do
|
10
|
-
wkhtmltopdf
|
11
|
-
|
12
|
-
args
|
13
|
-
args.size.should == 4
|
14
|
+
mock(@wkhtmltopdf).bin { '"wkhtmltopdf"' }
|
15
|
+
args = @wkhtmltopdf.command('test.pdf')
|
16
|
+
args.size.should eq 4
|
14
17
|
args.should include '"wkhtmltopdf"'
|
15
18
|
args.should include '--quiet'
|
16
19
|
args.should include '-'
|
17
20
|
args.should include '"test.pdf"'
|
18
21
|
end
|
19
22
|
|
23
|
+
it 'should use which to find wkhtmltopdf first time' do
|
24
|
+
mock(@wkhtmltopdf).__double_definition_create__.call(:`, "which wkhtmltopdf") { '~/wkhtmltopdf' }
|
25
|
+
@wkhtmltopdf.bin.should eq '"~/wkhtmltopdf"'
|
26
|
+
@wkhtmltopdf.bin.should eq '"~/wkhtmltopdf"' # Should be cached
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should generate a pdf' do
|
30
|
+
mock(@wkhtmltopdf).__double_definition_create__.call(:`, "which wkhtmltopdf") { '~/wkhtmltopdf' }
|
31
|
+
mock(IO).popen("\"~/wkhtmltopdf\" --quiet - \"\"", "wb+") { true }
|
32
|
+
@wkhtmltopdf.output_pdf('', '')
|
33
|
+
end
|
20
34
|
end
|
21
35
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
require './lib/gimli'
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
describe 'Integration' do
|
10
|
+
|
11
|
+
it 'should generate files from fixtures' do
|
12
|
+
config = Gimli.configure do |c|
|
13
|
+
c.file = 'spec/fixtures/integration/'
|
14
|
+
c.output_dir = 'spec/tmp'
|
15
|
+
end
|
16
|
+
|
17
|
+
Gimli.process! config
|
18
|
+
|
19
|
+
::File.exists?('spec/tmp/markdown.pdf').should be true
|
20
|
+
::File.exists?('spec/tmp/textile.pdf').should be true
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should generate files from fixtures with aditional parameters' do
|
24
|
+
config = Gimli.configure do |c|
|
25
|
+
c.file = 'spec/fixtures/integration/'
|
26
|
+
c.output_dir = 'spec/tmp/merged'
|
27
|
+
c.merge = true
|
28
|
+
c.stylesheet = 'spec/fixtures/integration/style.css'
|
29
|
+
c.output_filename = 'merged'
|
30
|
+
end
|
31
|
+
|
32
|
+
Gimli.process! config
|
33
|
+
|
34
|
+
::File.exists?('spec/tmp/merged/merged.pdf').should be true
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
::FileUtils.rm_rf 'spec/tmp'
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gimli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: github-markup
|
@@ -246,26 +246,37 @@ extra_rdoc_files:
|
|
246
246
|
- LICENSE
|
247
247
|
files:
|
248
248
|
- bin/gimli
|
249
|
-
- lib/gimli/
|
250
|
-
- lib/gimli/markupfile.rb
|
249
|
+
- lib/gimli/config.rb
|
251
250
|
- lib/gimli/converter.rb
|
252
|
-
- lib/gimli/
|
251
|
+
- lib/gimli/markup/code.rb
|
252
|
+
- lib/gimli/markup/code_block.rb
|
253
|
+
- lib/gimli/markup/renderer.rb
|
254
|
+
- lib/gimli/markup/yaml_frontmatter_remover.rb
|
255
|
+
- lib/gimli/markup.rb
|
256
|
+
- lib/gimli/markupfile.rb
|
257
|
+
- lib/gimli/path.rb
|
253
258
|
- lib/gimli/setup.rb
|
254
|
-
- lib/gimli/config.rb
|
255
259
|
- lib/gimli/version.rb
|
256
|
-
- lib/gimli/
|
260
|
+
- lib/gimli/wkhtmltopdf.rb
|
257
261
|
- lib/gimli.rb
|
258
|
-
- spec/
|
259
|
-
- spec/
|
260
|
-
- spec/gimli/markup_spec.rb
|
261
|
-
- spec/gimli/file_spec.rb
|
262
|
-
- spec/gimli/wkhtmltopdf_spec.rb
|
262
|
+
- spec/fixtures/code_block.textile
|
263
|
+
- spec/fixtures/code_block_with_utf8.textile
|
263
264
|
- spec/fixtures/code_with_utf8.textile
|
264
|
-
- spec/fixtures/
|
265
|
+
- spec/fixtures/integration/markdown.md
|
266
|
+
- spec/fixtures/integration/style.css
|
267
|
+
- spec/fixtures/integration/textile.textile
|
265
268
|
- spec/fixtures/recursion/level1.textile
|
266
|
-
- spec/fixtures/
|
269
|
+
- spec/fixtures/recursion/level2/level2.markdown
|
267
270
|
- spec/fixtures/yaml_front_matter.textile
|
268
|
-
- spec/
|
271
|
+
- spec/gimli/converter_spec.rb
|
272
|
+
- spec/gimli/markup/code_block_spec.rb
|
273
|
+
- spec/gimli/markup/code_spec.rb
|
274
|
+
- spec/gimli/markup/renderer_spec.rb
|
275
|
+
- spec/gimli/markup/yaml_frontmatter_remover_spec.rb
|
276
|
+
- spec/gimli/markup_file_spec.rb
|
277
|
+
- spec/gimli/path_spec.rb
|
278
|
+
- spec/gimli/wkhtmltopdf_spec.rb
|
279
|
+
- spec/integration_spec.rb
|
269
280
|
- spec/spec_helper.rb
|
270
281
|
- config/style.css
|
271
282
|
- LICENSE
|
@@ -285,7 +296,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
285
296
|
version: '0'
|
286
297
|
segments:
|
287
298
|
- 0
|
288
|
-
hash:
|
299
|
+
hash: -3276508745148089455
|
289
300
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
290
301
|
none: false
|
291
302
|
requirements:
|
@@ -294,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
294
305
|
version: '0'
|
295
306
|
segments:
|
296
307
|
- 0
|
297
|
-
hash:
|
308
|
+
hash: -3276508745148089455
|
298
309
|
requirements: []
|
299
310
|
rubyforge_project: gimli
|
300
311
|
rubygems_version: 1.8.24
|
data/spec/gimli/file_spec.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require './spec/spec_helper'
|
4
|
-
|
5
|
-
require './lib/gimli'
|
6
|
-
|
7
|
-
describe Gimli::MarkupFile do
|
8
|
-
it 'should recognize valid format' do
|
9
|
-
file = Gimli::MarkupFile.new 'fake'
|
10
|
-
file.valid_format?('textile').should be_true
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should recognize invalid format' do
|
14
|
-
file = Gimli::MarkupFile.new 'fake'
|
15
|
-
file.valid_format?('abc123').should be_false
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should recognize nil as invalid format' do
|
19
|
-
file = Gimli::MarkupFile.new 'fake'
|
20
|
-
file.valid_format?(nil).should be_false
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should give the name as the filename without the extension' do
|
24
|
-
file = Gimli::MarkupFile.new 'test.txt'
|
25
|
-
file.name.should == File.basename(file.filename, File.extname(file.filename))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|