any2pdf 1.1.2 → 1.2.1
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.
- checksums.yaml +4 -4
- data/any2pdf.gemspec +1 -1
- data/bin/any2pdf +23 -222
- data/data/pandoc-template.html +8 -0
- data/lib/any2pdf.rb +4 -0
- data/lib/any2pdf/html2pdf.rb +137 -0
- data/lib/any2pdf/md2html.rb +65 -0
- data/lib/any2pdf/metadata.rb +41 -0
- data/lib/any2pdf/style.rb +21 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88abea5eeb8466229a5540bf50f94c2c261fd9da
|
4
|
+
data.tar.gz: c362c3cb62dc9d186bfbfe3500c38695b5bef39b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f64c048509335cbf727aa1fac4d2c9a685e8da289188bfbbdd2ec1a7f3e10a9c2b9a080b23851d8a1c0fac689273455b0a3d7b87c930b3952e53c76155432e46
|
7
|
+
data.tar.gz: d4488d1ec52a0a7d2920c8af780bd7fb57dddb2eabb68cb19ffd76761abdb2c7c144eacb0fc86c02d3f72cbc616db31048c727f35b6a3617d5ac87d279060a98
|
data/any2pdf.gemspec
CHANGED
data/bin/any2pdf
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'pdfkit'
|
4
3
|
require 'trollop'
|
5
|
-
require 'nokogiri'
|
6
|
-
require 'css_parser'
|
7
|
-
require 'uri'
|
8
|
-
require 'erb'
|
9
4
|
require 'zlog'
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
require 'any2pdf'
|
10
7
|
|
11
8
|
opts = Trollop::options do
|
12
9
|
banner "usage: any2pdf <file>"
|
@@ -16,6 +13,7 @@ opts = Trollop::options do
|
|
16
13
|
opt :stylesheet, "stylesheet to load", :default => ""
|
17
14
|
opt :input, "input file", :default => ""
|
18
15
|
opt :landscape, "if you want landscape instead of portrait"
|
16
|
+
opt :gitinfo, "if you want to add the current commit ID, date, and tag"
|
19
17
|
opt :view_cmd, "command used for viewing", :default => "v %s"
|
20
18
|
opt :view, "what to view (pdf|html|none)", :default => "none"
|
21
19
|
opt :renderer, "what engine to use for pdf creation (pdfkit|xelatex)", default: "pdfkit", type: :string
|
@@ -23,6 +21,7 @@ opts = Trollop::options do
|
|
23
21
|
opt :toc_level, "which depth if headings to include in ToC", :default => 2, :type => :int
|
24
22
|
opt :numbering, "whether to add numbering to all headings"
|
25
23
|
opt :embed, "when active embed js/css files instad of just linking to them"
|
24
|
+
opt :clean, "clean up when done"
|
26
25
|
end
|
27
26
|
|
28
27
|
Zlog.init_stdout loglevel: :warn if not opts[:verbose] and not opts[:debug]
|
@@ -37,228 +36,25 @@ Trollop::die :toc_level, "must not be higher than 6" if opts[:toc_level] > 6
|
|
37
36
|
mdfile = ARGV.first
|
38
37
|
Trollop::die :input, "must be supplied" if mdfile.nil?
|
39
38
|
Trollop::die :input, "#{mdfile} must exist" if not File::exists?(mdfile)
|
39
|
+
htmlfile = mdfile.sub(/.md$/,".html")
|
40
|
+
tmpmdfile = ".~" + mdfile
|
40
41
|
|
41
|
-
|
42
|
-
path = File::expand_path(f)
|
43
|
-
return path if File::exists?(path)
|
44
|
-
return nil
|
45
|
-
end
|
46
|
-
|
47
|
-
def get_style( stylename, type = "css" )
|
48
|
-
rel_path = File.expand_path('../Gemfile/../data', File.dirname(__FILE__))
|
49
|
-
|
50
|
-
if not stylename.nil? and not stylename.empty?
|
51
|
-
a =
|
52
|
-
get_existing(stylename) ||
|
53
|
-
get_existing("#{rel_path}/#{stylename}.#{type}") ||
|
54
|
-
get_existing("#{rel_path}/#{stylename}")
|
55
|
-
return a if not a.nil?
|
56
|
-
Log.warn "couldn't find stylesheet #{stylename}. Trying default.\n"
|
57
|
-
end
|
58
|
-
|
59
|
-
# try default, if the user supplied crap...
|
60
|
-
a = get_existing("#{rel_path}/default.#{type}")
|
61
|
-
return a if not a.nil?
|
62
|
-
Log.error "Couldn't find internal stylesheet in #{rel_path}/default.#{type}. Something is seriously wrong! try reinstalling?\n"
|
63
|
-
""
|
64
|
-
end
|
65
|
-
|
66
|
-
def embed_html( raw, source )
|
67
|
-
begin
|
68
|
-
require 'websnap'
|
69
|
-
w = WebSnap.new( nil, nil )
|
70
|
-
|
71
|
-
# parse raw html contents
|
72
|
-
Log.info "embedding html via websnap"
|
73
|
-
h = Nokogiri::HTML(raw)
|
74
|
-
|
75
|
-
# embed all parts into the html
|
76
|
-
w.spiderHtmlElements( 'file://'+File::expand_path(source), h )
|
77
|
-
|
78
|
-
# return the resulting html as string
|
79
|
-
h.to_s
|
80
|
-
rescue LoadError
|
81
|
-
return raw
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def md2html(file, opts, stylefile)
|
86
|
-
return nil if not file.end_with?(".md")
|
87
|
-
htmlfile = file.sub(/.md$/,".html")
|
88
|
-
htmlfile_raw = htmlfile+".raw.html"
|
89
|
-
|
90
|
-
rel_path = File.expand_path('../Gemfile/../data', File.dirname(__FILE__))
|
91
|
-
|
92
|
-
# prep-work for including style and script
|
93
|
-
style_e = lambda{|f,o| "<style type=\"text/css\" #{o}>\n#{File::read(f)}\n</style>" }
|
94
|
-
style_l = lambda{|f,o| "<link rel=\"stylesheet\" href=\"#{f}\" #{o} />" }
|
95
|
-
script_e = lambda{|f,o| "<script #{o}>\n#{File::read(f)}\n</script>" }
|
96
|
-
script_l = lambda{|f,o| "<script src=\"#{f}\" #{o} ></script>"}
|
97
|
-
style = opts[:embed] ? style_e : style_l
|
98
|
-
script = opts[:embed] ? script_e : script_l
|
99
|
-
|
100
|
-
# get all fields in the heading
|
101
|
-
raw_heading = [
|
102
|
-
# start with stylesheets
|
103
|
-
style.( rel_path+"/boilerplate.css", ''),
|
104
|
-
style.( File::expand_path(stylefile), '' ),
|
105
|
-
style.( rel_path+"/print.css", 'media="print"'),
|
106
|
-
script.( rel_path+"/jquery-1.9.0.min.js", '' ),
|
107
|
-
( opts[:toc] ? script.( rel_path+"/toc_generator.js", '' ) : '' )
|
108
|
-
].join("\n\n")
|
109
|
-
|
110
|
-
# create the html
|
111
|
-
`pandoc "#{file}" -o "#{htmlfile_raw}" --template #{rel_path}/pandoc-template.html --toc`
|
112
|
-
raw_html = File::read htmlfile_raw
|
113
|
-
File.delete htmlfile_raw
|
114
|
-
|
115
|
-
# additional options
|
116
|
-
toc_level = opts[:toc_level]
|
117
|
-
number_headings = (opts[:numbering] == true)
|
118
|
-
|
119
|
-
# actually create the result file
|
120
|
-
renderer = ERB.new(File::read(rel_path + "/template.html.erb"))
|
121
|
-
html = embed_html( renderer.result(binding), file )
|
122
|
-
|
123
|
-
# save the html to file
|
124
|
-
File::write htmlfile, html
|
125
|
-
htmlfile
|
126
|
-
end
|
127
|
-
|
128
|
-
def get_style_options style_file
|
129
|
-
return {} unless File::file? style_file
|
130
|
-
|
131
|
-
declarations = []
|
132
|
-
|
133
|
-
css = CssParser::Parser.new
|
134
|
-
css.load_file! style_file
|
135
|
-
css.each_rule_set do |rule|
|
136
|
-
if rule.selectors.include? '#pdf'
|
137
|
-
rule.each_declaration do |id, params|
|
138
|
-
declarations.push [id, params]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# check all rules
|
144
|
-
opts = {}
|
145
|
-
declarations.each do |field,value|
|
146
|
-
if field == 'margin'
|
147
|
-
vals = value.split(' ');
|
148
|
-
if vals.length == 4
|
149
|
-
opts[:margin_top] = vals[0]
|
150
|
-
opts[:margin_right] = vals[1]
|
151
|
-
opts[:margin_bottom] = vals[2]
|
152
|
-
opts[:margin_left] = vals[3]
|
153
|
-
end
|
154
|
-
if vals.length == 2
|
155
|
-
opts[:margin_top] = vals[0]
|
156
|
-
opts[:margin_right] = vals[1]
|
157
|
-
opts[:margin_bottom] = vals[0]
|
158
|
-
opts[:margin_left] = vals[1]
|
159
|
-
end
|
160
|
-
if vals.length == 1
|
161
|
-
opts[:margin_top] = vals[0]
|
162
|
-
opts[:margin_right] = vals[0]
|
163
|
-
opts[:margin_bottom] = vals[0]
|
164
|
-
opts[:margin_left] = vals[0]
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
42
|
+
any2pdf = Any2Pdf.new
|
169
43
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
def pdfkit_html2pdf( file, outfile, opts )
|
174
|
-
styles = []
|
175
|
-
styles << opts.stylesheet
|
176
|
-
|
177
|
-
style_opts = get_style_options opts.stylesheet
|
178
|
-
|
179
|
-
# find css files
|
180
|
-
dom = Nokogiri::parse( File::open(file).read() )
|
181
|
-
dom.css("link").each do |e|
|
182
|
-
styles << e.attr("href")
|
183
|
-
end
|
184
|
-
|
185
|
-
# update the html links to make sure that local links (relative) work
|
186
|
-
( dom.css("@src") + dom.css("@href") ).
|
187
|
-
find_all{|src| (src.value =~ URI::regexp) == nil }.
|
188
|
-
each{|src| src.value = File::expand_path(src.value) }
|
189
|
-
|
190
|
-
options = {
|
191
|
-
footer_right: "[page]/[topage]",
|
192
|
-
orientation: (( opts[:landscape] ) ? "landscape" : "portrait" ),
|
193
|
-
page_size: 'A4',
|
194
|
-
}.merge(style_opts)
|
195
|
-
html = dom.to_s
|
196
|
-
kit = PDFKit.new(html, options)
|
197
|
-
|
198
|
-
styles.compact.each do |style|
|
199
|
-
kit.stylesheets << style if File::exists?(style)
|
200
|
-
end
|
201
|
-
|
202
|
-
kit.to_file(outfile)
|
203
|
-
end
|
204
|
-
|
205
|
-
def xelatex_html2pdf( file, outfile, opts )
|
206
|
-
puts outfile
|
207
|
-
texfile = "#{outfile}".sub(/[.]pdf$/, '.tex')
|
208
|
-
|
209
|
-
cmd = "pandoc \"#{file}\" --listings -o \"#{texfile}\""
|
210
|
-
Log.debug "convert html to tex: #{cmd}"
|
211
|
-
`#{cmd}`
|
212
|
-
|
213
|
-
verb_opts = "mathescape,
|
214
|
-
linenos,
|
215
|
-
numbersep=5pt,
|
216
|
-
frame=single,
|
217
|
-
framesep=1mm,
|
218
|
-
bgcolor=colorcode_bg".gsub("\n",'')
|
44
|
+
# Metadata
|
45
|
+
mdfile = any2pdf.fill_in_metadata(mdfile, tmpmdfile) if opts[:gitinfo]
|
219
46
|
|
220
|
-
|
221
|
-
|
222
|
-
# \begin{lstlisting}[language=bash]
|
223
|
-
# convert it to minted
|
224
|
-
gsub(/\\begin{lstlisting}\[language=([^\]]*)\]/){'\begin{minted}['+verb_opts+']{'+$1+'}'}.
|
225
|
-
gsub(/\\begin{lstlisting}/, '\begin{minted}['+verb_opts+']{bash}').
|
226
|
-
gsub(/\\lstinline(.)(.*?)\1/){ '\colorbox{colorcode_bg}{\lstinline'+$1+$2+$1+'}' }.
|
227
|
-
gsub(/\\end{lstlisting}/, '\end{minted}')
|
228
|
-
|
229
|
-
tex_style = get_style( opts[:stylesheet], 'tex' )
|
230
|
-
File::write texfile, File::read(tex_style).sub(/CONTENT/, tex)
|
231
|
-
|
232
|
-
cmd = "xelatex -shell-escape \"#{texfile}\""
|
233
|
-
Log.debug "convert tex to pdf: #{cmd}"
|
234
|
-
`#{cmd}`
|
235
|
-
end
|
236
|
-
|
237
|
-
def html2pdf(file, opts)
|
238
|
-
Log.debug "running html2pdf on '#{file}'"
|
239
|
-
return nil if not file.end_with?(".html")
|
240
|
-
pdffile = file.sub(/.html$/,".pdf")
|
241
|
-
pdffile = opts.output if not opts.output.nil? and not opts.output.empty?
|
242
|
-
Log.debug "output pdf will be '#{pdffile}'"
|
243
|
-
|
244
|
-
case opts[:renderer]
|
245
|
-
when 'pdfkit'
|
246
|
-
pdfkit_html2pdf file, pdffile, opts
|
247
|
-
when 'xelatex'
|
248
|
-
xelatex_html2pdf file, pdffile, opts
|
249
|
-
else
|
250
|
-
Log.abort "Can't find renderer '#{opts[:renderer]}'. Please use a supported renderer!"
|
251
|
-
end
|
252
|
-
|
253
|
-
pdffile
|
254
|
-
end
|
255
|
-
|
256
|
-
style = get_style( opts[:stylesheet] )
|
47
|
+
# Stylesheet
|
48
|
+
style = any2pdf.get_style( opts[:stylesheet] )
|
257
49
|
Log.info "using stylesheet: #{style}\n"
|
258
|
-
|
259
|
-
|
50
|
+
|
51
|
+
# HTML
|
52
|
+
htmlfile = any2pdf.md2html(mdfile, htmlfile, opts, style)
|
53
|
+
Log.warn "ww input was not an md-file, trying to convert it to pdf as html..." if htmlfile.nil?
|
260
54
|
Log.ok "htmlfile: #{htmlfile}\n" if not htmlfile.nil?
|
261
|
-
|
55
|
+
|
56
|
+
# PDF
|
57
|
+
pdffile = any2pdf.html2pdf(mdfile, opts) || any2pdf.html2pdf(htmlfile, opts)
|
262
58
|
Log.abort "couldn't convert file from html to pdf..." if pdffile.nil?
|
263
59
|
Log.ok "output: #{pdffile}\n" if not pdffile.nil?
|
264
60
|
|
@@ -277,3 +73,8 @@ if not cmd.empty?
|
|
277
73
|
Log.info "view with: '#{cmd}'"
|
278
74
|
system cmd
|
279
75
|
end
|
76
|
+
|
77
|
+
if opts[:clean]
|
78
|
+
File::delete( tmpmdfile ) if File::file? tmpmdfile
|
79
|
+
File::delete( htmlfile ) if File::file? htmlfile
|
80
|
+
end
|
data/data/pandoc-template.html
CHANGED
@@ -14,6 +14,14 @@ $if(title)$
|
|
14
14
|
$if(date)$
|
15
15
|
<h3 class="date fixed-heading">$date$</h3>
|
16
16
|
$endif$
|
17
|
+
$if(git_commit)$
|
18
|
+
<h3 class="git-info fixed-heading">
|
19
|
+
$if(git_tag)$<span class="git-tag">$git_tag$</span>$endif$$if(git_commit)$<span class="git-commit">$git_commit$</span>$endif$$if(git_date)$<span class="git-date">$git_date$</span>$endif$
|
20
|
+
</h3>
|
21
|
+
$endif$
|
22
|
+
$if(copyright)$
|
23
|
+
<h5 class="copyright">$copyright$</h5>
|
24
|
+
$endif$
|
17
25
|
</header>
|
18
26
|
$endif$
|
19
27
|
|
data/lib/any2pdf.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'css_parser'
|
4
|
+
require 'pdfkit'
|
5
|
+
|
6
|
+
class Any2Pdf
|
7
|
+
def pdfkit_html2pdf( file, outfile, opts )
|
8
|
+
styles = []
|
9
|
+
styles << opts.stylesheet
|
10
|
+
|
11
|
+
style_opts = get_style_options opts.stylesheet
|
12
|
+
|
13
|
+
# find css files
|
14
|
+
dom = Nokogiri::parse( File::open(file).read() )
|
15
|
+
dom.css("link").each do |e|
|
16
|
+
styles << e.attr("href")
|
17
|
+
end
|
18
|
+
|
19
|
+
# update the html links to make sure that local links (relative) work
|
20
|
+
( dom.css("@src") + dom.css("@href") ).
|
21
|
+
find_all{|src| (src.value =~ URI::regexp) == nil }.
|
22
|
+
each{|src| src.value = File::expand_path(src.value) }
|
23
|
+
|
24
|
+
options = {
|
25
|
+
footer_right: "[page]/[topage]",
|
26
|
+
orientation: (( opts[:landscape] ) ? "landscape" : "portrait" ),
|
27
|
+
page_size: 'A4',
|
28
|
+
}.merge(style_opts)
|
29
|
+
html = dom.to_s
|
30
|
+
kit = PDFKit.new(html, options)
|
31
|
+
|
32
|
+
styles.compact.each do |style|
|
33
|
+
kit.stylesheets << style if File::exists?(style)
|
34
|
+
end
|
35
|
+
|
36
|
+
kit.to_file(outfile)
|
37
|
+
end
|
38
|
+
|
39
|
+
def xelatex_html2pdf( file, outfile, opts )
|
40
|
+
puts outfile
|
41
|
+
texfile = "#{outfile}".sub(/[.]pdf$/, '.tex')
|
42
|
+
|
43
|
+
cmd = "pandoc \"#{file}\" --listings -o \"#{texfile}\""
|
44
|
+
Log.debug "convert html to tex: #{cmd}"
|
45
|
+
`#{cmd}`
|
46
|
+
|
47
|
+
verb_opts = "mathescape,
|
48
|
+
linenos,
|
49
|
+
numbersep=5pt,
|
50
|
+
frame=single,
|
51
|
+
framesep=1mm,
|
52
|
+
bgcolor=colorcode_bg".gsub("\n",'')
|
53
|
+
|
54
|
+
tex = File::read(texfile).
|
55
|
+
# all verbatim stuff is in lstlistings like this:
|
56
|
+
# \begin{lstlisting}[language=bash]
|
57
|
+
# convert it to minted
|
58
|
+
gsub(/\\begin{lstlisting}\[language=([^\]]*)\]/){'\begin{minted}['+verb_opts+']{'+$1+'}'}.
|
59
|
+
gsub(/\\begin{lstlisting}/, '\begin{minted}['+verb_opts+']{bash}').
|
60
|
+
gsub(/\\lstinline(.)(.*?)\1/){ '\colorbox{colorcode_bg}{\lstinline'+$1+$2+$1+'}' }.
|
61
|
+
gsub(/\\end{lstlisting}/, '\end{minted}')
|
62
|
+
|
63
|
+
tex_style = get_style( opts[:stylesheet], 'tex' )
|
64
|
+
File::write texfile, File::read(tex_style).sub(/CONTENT/, tex)
|
65
|
+
|
66
|
+
cmd = "xelatex -shell-escape \"#{texfile}\""
|
67
|
+
Log.debug "convert tex to pdf: #{cmd}"
|
68
|
+
`#{cmd}`
|
69
|
+
end
|
70
|
+
|
71
|
+
def html2pdf(file, opts)
|
72
|
+
Log.debug "running html2pdf on '#{file}'"
|
73
|
+
return nil if not file.end_with?(".html")
|
74
|
+
pdffile = file.sub(/.html$/,".pdf")
|
75
|
+
pdffile = opts.output if not opts.output.nil? and not opts.output.empty?
|
76
|
+
Log.debug "output pdf will be '#{pdffile}'"
|
77
|
+
|
78
|
+
case opts[:renderer]
|
79
|
+
when 'pdfkit'
|
80
|
+
pdfkit_html2pdf file, pdffile, opts
|
81
|
+
when 'xelatex'
|
82
|
+
xelatex_html2pdf file, pdffile, opts
|
83
|
+
else
|
84
|
+
Log.abort "Can't find renderer '#{opts[:renderer]}'. Please use a supported renderer!"
|
85
|
+
end
|
86
|
+
|
87
|
+
pdffile
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def get_style_options style_file
|
93
|
+
return {} unless File::file? style_file
|
94
|
+
|
95
|
+
declarations = []
|
96
|
+
|
97
|
+
css = CssParser::Parser.new
|
98
|
+
css.load_file! style_file
|
99
|
+
css.each_rule_set do |rule|
|
100
|
+
if rule.selectors.include? '#pdf'
|
101
|
+
rule.each_declaration do |id, params|
|
102
|
+
declarations.push [id, params]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# check all rules
|
108
|
+
opts = {}
|
109
|
+
declarations.each do |field,value|
|
110
|
+
if field == 'margin'
|
111
|
+
vals = value.split(' ');
|
112
|
+
if vals.length == 4
|
113
|
+
opts[:margin_top] = vals[0]
|
114
|
+
opts[:margin_right] = vals[1]
|
115
|
+
opts[:margin_bottom] = vals[2]
|
116
|
+
opts[:margin_left] = vals[3]
|
117
|
+
end
|
118
|
+
if vals.length == 2
|
119
|
+
opts[:margin_top] = vals[0]
|
120
|
+
opts[:margin_right] = vals[1]
|
121
|
+
opts[:margin_bottom] = vals[0]
|
122
|
+
opts[:margin_left] = vals[1]
|
123
|
+
end
|
124
|
+
if vals.length == 1
|
125
|
+
opts[:margin_top] = vals[0]
|
126
|
+
opts[:margin_right] = vals[0]
|
127
|
+
opts[:margin_bottom] = vals[0]
|
128
|
+
opts[:margin_left] = vals[0]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
opts
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
class Any2Pdf
|
4
|
+
def embed_html( raw, source )
|
5
|
+
begin
|
6
|
+
require 'websnap'
|
7
|
+
w = WebSnap.new( nil, nil )
|
8
|
+
|
9
|
+
# parse raw html contents
|
10
|
+
Log.info "embedding html via websnap"
|
11
|
+
h = Nokogiri::HTML(raw)
|
12
|
+
|
13
|
+
# embed all parts into the html
|
14
|
+
w.spiderHtmlElements( 'file://'+File::expand_path(source), h )
|
15
|
+
|
16
|
+
# return the resulting html as string
|
17
|
+
h.to_s
|
18
|
+
rescue LoadError
|
19
|
+
return raw
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def md2html(file, outfile, opts, stylefile)
|
24
|
+
return nil if not file.end_with?(".md")
|
25
|
+
outfile_raw = outfile+".raw.html"
|
26
|
+
|
27
|
+
rel_path = File.expand_path('../../data', File.dirname(__FILE__))
|
28
|
+
|
29
|
+
# prep-work for including style and script
|
30
|
+
style_e = lambda{|f,o| "<style type=\"text/css\" #{o}>\n#{File::read(f)}\n</style>" }
|
31
|
+
style_l = lambda{|f,o| "<link rel=\"stylesheet\" href=\"#{f}\" #{o} />" }
|
32
|
+
script_e = lambda{|f,o| "<script #{o}>\n#{File::read(f)}\n</script>" }
|
33
|
+
script_l = lambda{|f,o| "<script src=\"#{f}\" #{o} ></script>"}
|
34
|
+
style = opts[:embed] ? style_e : style_l
|
35
|
+
script = opts[:embed] ? script_e : script_l
|
36
|
+
|
37
|
+
# get all fields in the heading
|
38
|
+
raw_heading = [
|
39
|
+
# start with stylesheets
|
40
|
+
style.( rel_path+"/boilerplate.css", ''),
|
41
|
+
style.( File::expand_path(stylefile), '' ),
|
42
|
+
style.( rel_path+"/print.css", 'media="print"'),
|
43
|
+
script.( rel_path+"/jquery-1.9.0.min.js", '' ),
|
44
|
+
( opts[:toc] ? script.( rel_path+"/toc_generator.js", '' ) : '' )
|
45
|
+
].join("\n\n")
|
46
|
+
|
47
|
+
# create the html
|
48
|
+
`pandoc "#{file}" -o "#{outfile_raw}" --template #{rel_path}/pandoc-template.html --toc`
|
49
|
+
raw_html = File::read outfile_raw
|
50
|
+
File.delete outfile_raw
|
51
|
+
|
52
|
+
# additional options
|
53
|
+
toc_level = opts[:toc_level]
|
54
|
+
number_headings = (opts[:numbering] == true)
|
55
|
+
|
56
|
+
# actually create the result file
|
57
|
+
renderer = ERB.new(File::read(rel_path + "/template.html.erb"))
|
58
|
+
html = embed_html( renderer.result(binding), file )
|
59
|
+
|
60
|
+
# save the html to file
|
61
|
+
File::write outfile, html
|
62
|
+
outfile
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Any2Pdf
|
2
|
+
|
3
|
+
def fill_in_metadata( path, tmpfile )
|
4
|
+
tag = `git describe --tags --abbrev=0`.chomp
|
5
|
+
gitlog = `git log -1 --pretty=format:'%h %ct'`
|
6
|
+
commit, date = gitlog.split(" ")
|
7
|
+
if commit == "" || date == nil
|
8
|
+
Log.warn "Can't find git info for latest commit. Ignoring."
|
9
|
+
return path
|
10
|
+
end
|
11
|
+
Log.info "Adding git metadata: #{tag} #{commit} #{date}"
|
12
|
+
|
13
|
+
time = Time.at( date.to_i )
|
14
|
+
timestamp = "%04d-%02d-%02d" % [ time.year, time.month, time.day ]
|
15
|
+
|
16
|
+
content = File::read(path)
|
17
|
+
info = ["---",
|
18
|
+
"git_commit: #{commit}",
|
19
|
+
"git_date: #{timestamp}",
|
20
|
+
(tag == "" ) ? nil : "git_tag: #{tag}"
|
21
|
+
].compact.join("\n") + "\n"
|
22
|
+
|
23
|
+
if content.start_with?("---\n")
|
24
|
+
nu = content.sub("---\n",info)
|
25
|
+
else
|
26
|
+
nu = info + "---\n" + content
|
27
|
+
end
|
28
|
+
|
29
|
+
File::write( tmpfile, nu )
|
30
|
+
tmpfile
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def get_existing( f )
|
36
|
+
path = File::expand_path(f)
|
37
|
+
return path if File::exists?(path)
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Any2Pdf
|
2
|
+
def get_style( stylename, type = "css" )
|
3
|
+
rel_path = File.expand_path('../../data', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
if not stylename.nil? and not stylename.empty?
|
6
|
+
a =
|
7
|
+
get_existing(stylename) ||
|
8
|
+
get_existing("#{rel_path}/#{stylename}.#{type}") ||
|
9
|
+
get_existing("#{rel_path}/#{stylename}")
|
10
|
+
return a if not a.nil?
|
11
|
+
Log.warn "couldn't find stylesheet #{stylename}. Trying default.\n"
|
12
|
+
end
|
13
|
+
|
14
|
+
# try default, if the user supplied crap...
|
15
|
+
a = get_existing("#{rel_path}/default.#{type}")
|
16
|
+
return a if not a.nil?
|
17
|
+
Log.error "Couldn't find internal stylesheet in #{rel_path}/default.#{type}. Something is seriously wrong! try reinstalling?\n"
|
18
|
+
""
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: any2pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pdfkit
|
@@ -104,6 +104,11 @@ files:
|
|
104
104
|
- data/telekom.css
|
105
105
|
- data/template.html.erb
|
106
106
|
- data/toc_generator.js
|
107
|
+
- lib/any2pdf.rb
|
108
|
+
- lib/any2pdf/html2pdf.rb
|
109
|
+
- lib/any2pdf/md2html.rb
|
110
|
+
- lib/any2pdf/metadata.rb
|
111
|
+
- lib/any2pdf/style.rb
|
107
112
|
homepage:
|
108
113
|
licenses: []
|
109
114
|
metadata: {}
|