gollum 2.1.10 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of gollum might be problematic. Click here for more details.
- data/README.md +1 -1
- data/gollum.gemspec +3 -3
- data/lib/gollum.rb +1 -1
- data/lib/gollum/frontend/app.rb +0 -6
- data/lib/gollum/frontend/public/gollum/javascript/editor/gollum.editor.js +14 -3
- data/lib/gollum/frontend/templates/page.mustache +7 -0
- data/lib/gollum/markup.rb +1 -17
- data/lib/gollum/tex.rb +7 -359
- data/test/test_markup.rb +2 -2
- metadata +67 -65
data/README.md
CHANGED
@@ -528,7 +528,7 @@ your changes merged back into core is as follows:
|
|
528
528
|
$ gem push gollum-X.Y.Z.gem
|
529
529
|
|
530
530
|
## BUILDING THE GEM FROM MASTER
|
531
|
-
$ gem uninstall -
|
531
|
+
$ gem uninstall -aIx gollum
|
532
532
|
$ git clone https://github.com/github/gollum.git
|
533
533
|
$ cd gollum
|
534
534
|
gollum$ rake build
|
data/gollum.gemspec
CHANGED
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.required_ruby_version = ">= 1.8.7"
|
6
6
|
|
7
7
|
s.name = 'gollum'
|
8
|
-
s.version = '2.
|
9
|
-
s.date = '2012-
|
8
|
+
s.version = '2.2.0'
|
9
|
+
s.date = '2012-09-01'
|
10
10
|
s.rubyforge_project = 'gollum'
|
11
11
|
|
12
12
|
s.summary = "A simple, Git-powered wiki."
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_dependency('github-markup', [">= 0.7.0", "< 1.0.0"])
|
28
28
|
s.add_dependency('github-markdown')
|
29
29
|
s.add_dependency('pygments.rb', "~> 0.2.0")
|
30
|
-
s.add_dependency('
|
30
|
+
s.add_dependency('escape_utils', "0.2.4")
|
31
31
|
s.add_dependency('sinatra', "~> 1.0")
|
32
32
|
s.add_dependency('mustache', [">= 0.11.2", "< 1.0.0"])
|
33
33
|
s.add_dependency('sanitize', "~> 2.0.0")
|
data/lib/gollum.rb
CHANGED
@@ -23,7 +23,7 @@ require File.expand_path('../gollum/web_sequence_diagram', __FILE__)
|
|
23
23
|
require File.expand_path('../gollum/frontend/uri_encode_component', __FILE__)
|
24
24
|
|
25
25
|
module Gollum
|
26
|
-
VERSION = '2.
|
26
|
+
VERSION = '2.2.0'
|
27
27
|
|
28
28
|
def self.assets_path
|
29
29
|
::File.expand_path('gollum/frontend/public', ::File.dirname(__FILE__))
|
data/lib/gollum/frontend/app.rb
CHANGED
@@ -282,12 +282,6 @@ module Precious
|
|
282
282
|
mustache :compare
|
283
283
|
end
|
284
284
|
|
285
|
-
get '/_tex.png' do
|
286
|
-
content_type 'image/png'
|
287
|
-
formula = Base64.decode64(params[:data])
|
288
|
-
Gollum::Tex.render_formula(formula)
|
289
|
-
end
|
290
|
-
|
291
285
|
get %r{^/(javascript|css|images)} do
|
292
286
|
halt 404
|
293
287
|
end
|
@@ -196,7 +196,9 @@
|
|
196
196
|
LanguageDefinition.getHookFunctionFor("activate")();
|
197
197
|
}
|
198
198
|
|
199
|
-
function hotkey( cmd ) {
|
199
|
+
function hotkey( e, cmd ) {
|
200
|
+
e.preventDefault();
|
201
|
+
|
200
202
|
var def = LanguageDefinition.getDefinitionFor( cmd );
|
201
203
|
if ( typeof def == 'object' ) {
|
202
204
|
FunctionBar.executeAction( def );
|
@@ -205,8 +207,17 @@
|
|
205
207
|
return false;
|
206
208
|
}
|
207
209
|
|
208
|
-
Mousetrap.bind(['command+
|
209
|
-
Mousetrap.bind(['command+
|
210
|
+
Mousetrap.bind(['command+1', 'ctrl+1'], function( e ){ hotkey( e, 'function-h1' ); });
|
211
|
+
Mousetrap.bind(['command+2', 'ctrl+2'], function( e ){ hotkey( e, 'function-h2' ); });
|
212
|
+
Mousetrap.bind(['command+3', 'ctrl+3'], function( e ){ hotkey( e, 'function-h3' ); });
|
213
|
+
Mousetrap.bind(['command+b', 'ctrl+b'], function( e ){ hotkey( e, 'function-bold' ); });
|
214
|
+
Mousetrap.bind(['command+i', 'ctrl+i'], function( e ){ hotkey( e, 'function-italic' ); });
|
215
|
+
Mousetrap.bind(['command+s', 'ctrl+s'], function( e ){
|
216
|
+
e.preventDefault();
|
217
|
+
$("#gollum-editor-submit").trigger("click");
|
218
|
+
return false;
|
219
|
+
});
|
220
|
+
|
210
221
|
} );
|
211
222
|
} else {
|
212
223
|
LanguageDefinition._ACTIVE_LANG = name;
|
data/lib/gollum/markup.rb
CHANGED
@@ -155,23 +155,7 @@ module Gollum
|
|
155
155
|
def process_tex(data)
|
156
156
|
@texmap.each do |id, spec|
|
157
157
|
type, tex = *spec
|
158
|
-
|
159
|
-
# Obtain the formula with parameters
|
160
|
-
out = nil
|
161
|
-
begin
|
162
|
-
width, height, align, base64 = Gollum::Tex.render_formula(tex, true)
|
163
|
-
|
164
|
-
# TODO: Should we load the binary inside the html?
|
165
|
-
#out = %{<img width="#{width}" height="#{height}" style="vertical-align: #{align}px;" src="data:image/png;base64,\n#{base64}" alt="#{CGI.escapeHTML(tex)}" />}
|
166
|
-
|
167
|
-
# Use the alignment values from the formula rendering but still use the call to '_tex.png'. Although it will call render_formula()
|
168
|
-
# again, it will use the already cached formula and it might have some advantages from the point of view of browser caching (really not sure here).
|
169
|
-
out = %{<img width="#{width}" height="#{height}" style="vertical-align: #{align}px;" src="#{::File.join(@wiki.base_path, '_tex.png')}?type=#{type}&data=#{Base64.encode64(tex).chomp}" alt="#{CGI.escapeHTML(tex)}" />}
|
170
|
-
rescue # In case of error
|
171
|
-
out = CGI.escapeHTML(tex)
|
172
|
-
end
|
173
|
-
|
174
|
-
data.gsub!(id, out)
|
158
|
+
data.gsub!(id, Gollum::Tex.to_html(tex, type))
|
175
159
|
end
|
176
160
|
data
|
177
161
|
end
|
data/lib/gollum/tex.rb
CHANGED
@@ -1,366 +1,14 @@
|
|
1
|
-
require '
|
2
|
-
require 'shellwords'
|
3
|
-
require 'tmpdir'
|
4
|
-
require 'posix/spawn'
|
5
|
-
require 'base64'
|
1
|
+
require 'escape_utils'
|
6
2
|
|
7
3
|
module Gollum
|
8
4
|
module Tex
|
9
|
-
|
5
|
+
TEX_URL = "http://www.mathtran.org/cgi-bin/toy/"
|
6
|
+
TEX_SIZES = { :inline => 2, :block => 4 }
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
\\pagestyle{empty}
|
16
|
-
\\setlength{\\topskip}{0pt}
|
17
|
-
\\setlength{\\parindent}{0pt}
|
18
|
-
\\setlength{\\abovedisplayskip}{0pt}
|
19
|
-
\\setlength{\\belowdisplayskip}{0pt}
|
20
|
-
|
21
|
-
\\usepackage{geometry}
|
22
|
-
|
23
|
-
\\usepackage{amsfonts}
|
24
|
-
\\usepackage{amsmath}
|
25
|
-
|
26
|
-
\\newsavebox{\\snippetbox}
|
27
|
-
\\newlength{\\snippetwidth}
|
28
|
-
\\newlength{\\snippetheight}
|
29
|
-
\\newlength{\\snippetdepth}
|
30
|
-
\\newlength{\\pagewidth}
|
31
|
-
\\newlength{\\pageheight}
|
32
|
-
\\newlength{\\pagemargin}
|
33
|
-
|
34
|
-
\\begin{lrbox}{\\snippetbox}%
|
35
|
-
\$%s\$
|
36
|
-
\\end{lrbox}
|
37
|
-
|
38
|
-
\\settowidth{\\snippetwidth}{\\usebox{\\snippetbox}}
|
39
|
-
\\settoheight{\\snippetheight}{\\usebox{\\snippetbox}}
|
40
|
-
\\settodepth{\\snippetdepth}{\\usebox{\\snippetbox}}
|
41
|
-
|
42
|
-
\\setlength\\pagemargin{4pt}
|
43
|
-
|
44
|
-
\\setlength\\pagewidth\\snippetwidth
|
45
|
-
\\addtolength\\pagewidth\\pagemargin
|
46
|
-
\\addtolength\\pagewidth\\pagemargin
|
47
|
-
|
48
|
-
\\setlength\\pageheight\\snippetheight
|
49
|
-
\\addtolength{\\pageheight}{\\snippetdepth}
|
50
|
-
\\addtolength\\pageheight\\pagemargin
|
51
|
-
\\addtolength\\pageheight\\pagemargin
|
52
|
-
|
53
|
-
\\newwrite\\foo
|
54
|
-
\\immediate\\openout\\foo=\\jobname.dimensions
|
55
|
-
\\immediate\\write\\foo{snippetdepth = \\the\\snippetdepth}
|
56
|
-
\\immediate\\write\\foo{snippetheight = \\the\\snippetheight}
|
57
|
-
\\immediate\\write\\foo{snippetwidth = \\the\\snippetwidth}
|
58
|
-
\\immediate\\write\\foo{pagewidth = \\the\\pagewidth}
|
59
|
-
\\immediate\\write\\foo{pageheight = \\the\\pageheight}
|
60
|
-
\\immediate\\write\\foo{pagemargin = \\the\\pagemargin}
|
61
|
-
\\closeout\\foo
|
62
|
-
|
63
|
-
\\geometry{paperwidth=\\pagewidth,paperheight=\\pageheight,margin=\\pagemargin}
|
64
|
-
|
65
|
-
\\begin{document}%
|
66
|
-
\\usebox{\\snippetbox}%
|
67
|
-
\\end{document}
|
68
|
-
EOS
|
69
|
-
|
70
|
-
class << self
|
71
|
-
attr_accessor :latex_path
|
72
|
-
end
|
73
|
-
|
74
|
-
self.latex_path = 'pdflatex'
|
75
|
-
|
76
|
-
def self.check_dependencies!
|
77
|
-
return if @dependencies_available
|
78
|
-
|
79
|
-
if `which pdflatex` == ""
|
80
|
-
raise Error, "`pdflatex` command not found"
|
81
|
-
end
|
82
|
-
|
83
|
-
if `which gs` == ""
|
84
|
-
raise Error, "`gs` command not found"
|
85
|
-
end
|
86
|
-
|
87
|
-
if `which pnmcrop` == ""
|
88
|
-
raise Error, "`pnmcrop` command not found"
|
89
|
-
end
|
90
|
-
|
91
|
-
if `which pnmpad` == ""
|
92
|
-
raise Error, "`pnmpad` command not found"
|
93
|
-
end
|
94
|
-
|
95
|
-
if `which pnmscale` == ""
|
96
|
-
raise Error, "`pnmscale` command not found"
|
97
|
-
end
|
98
|
-
|
99
|
-
if `which ppmtopgm` == ""
|
100
|
-
raise Error, "`ppmtopgm` command not found"
|
101
|
-
end
|
102
|
-
|
103
|
-
if `which pnmgamma` == ""
|
104
|
-
raise Error, "`pnmgamma` command not found"
|
105
|
-
end
|
106
|
-
|
107
|
-
if `which pnmtopng` == ""
|
108
|
-
raise Error, "`pnmtopng` command not found"
|
109
|
-
end
|
110
|
-
|
111
|
-
@dependencies_available = true
|
8
|
+
def self.to_html(tex, type = :inline)
|
9
|
+
tex_uri = EscapeUtils.escape_uri(tex)
|
10
|
+
tex_alt = EscapeUtils.escape_html(tex)
|
11
|
+
%{<img src="#{TEX_URL}?D=#{TEX_SIZES[type]};tex=#{tex}" alt="#{tex_alt}">}
|
112
12
|
end
|
113
|
-
|
114
|
-
# Render the formula and calculate the correct alignment
|
115
|
-
# for the image in the html.
|
116
|
-
#
|
117
|
-
# This is a ruby implementation of the Perl version described
|
118
|
-
# at http://tex.stackexchange.com/questions/44486/pixel-perfect-vertical-alignment-of-image-rendered-tex-snippets
|
119
|
-
#
|
120
|
-
# The main caveat is that rendering takes quite a bit of processing power,
|
121
|
-
# which can make the page load slowly if it has to render each time.
|
122
|
-
# For this reason, the method caches the rendered formula in `/tmp` for reduced
|
123
|
-
# loading time in subsequent loads.
|
124
|
-
#
|
125
|
-
# @param formula the tex formula to render
|
126
|
-
# @param with_properties, if true it returns an array with a base64
|
127
|
-
# string with the image, and the alignment values for the image.
|
128
|
-
# Otherwise it returns the binary image.
|
129
|
-
def self.render_formula(formula, with_properties=false)
|
130
|
-
check_dependencies!
|
131
|
-
|
132
|
-
render_antialias_bits = 4
|
133
|
-
render_oversample = 4
|
134
|
-
display_oversample = 4
|
135
|
-
gamma = 0.3
|
136
|
-
if !with_properties
|
137
|
-
display_oversample = 1
|
138
|
-
gamma = 0.5
|
139
|
-
end
|
140
|
-
|
141
|
-
oversample = render_oversample * display_oversample
|
142
|
-
render_dpi = 96*1.2 * 72.27/72 * oversample # This is 1850.112 dpi.
|
143
|
-
|
144
|
-
|
145
|
-
# Cache rendered formula and returned cached version if it exists
|
146
|
-
|
147
|
-
# First look for the .cache directory in the home folder
|
148
|
-
cache_dir = ::File.expand_path("~/.cache")
|
149
|
-
if not ::File.exists?(cache_dir) or not ::File.directory?(cache_dir)
|
150
|
-
::Dir.mkdir(cache_dir)
|
151
|
-
end
|
152
|
-
|
153
|
-
# Check that the gollum directory exists inside the cache dir
|
154
|
-
cache_dir = ::File.join(cache_dir, "gollum")
|
155
|
-
if not ::File.exists?(cache_dir) or not ::File.directory?(cache_dir)
|
156
|
-
::Dir.mkdir(cache_dir)
|
157
|
-
end
|
158
|
-
|
159
|
-
# Check for the formula in the cache dir
|
160
|
-
hash = Digest::SHA1.hexdigest(formula)
|
161
|
-
cache_file = ::File.join(cache_dir, "tex-#{hash}")
|
162
|
-
|
163
|
-
if ::File.exists?(cache_file)
|
164
|
-
width, height, align, base64 = ::File.open(cache_file, 'rb') { |io| io.read }.split(",")
|
165
|
-
|
166
|
-
if with_properties
|
167
|
-
return width, height, align, base64
|
168
|
-
else
|
169
|
-
return Base64.decode64(base64)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
Dir.mktmpdir('tex') do |path|
|
174
|
-
file = ::File.join(path, "formula")
|
175
|
-
|
176
|
-
# --- Write TeX source and compile to PDF.Write snippet into template
|
177
|
-
::File.open(file + ".tex", 'w') { |f| f.write(Template % formula) }
|
178
|
-
|
179
|
-
result = sh_chdir path, "pdflatex",
|
180
|
-
"-halt-on-error",
|
181
|
-
"-output-directory=#{path}",
|
182
|
-
"-output-format=pdf",
|
183
|
-
"#{file}.tex",
|
184
|
-
">#{file}.err 2>&1"
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# --- Convert PDF to PNM using Ghostscript.
|
189
|
-
sh "gs",
|
190
|
-
"-q -dNOPAUSE -dBATCH",
|
191
|
-
"-dTextAlphaBits=#{render_antialias_bits}",
|
192
|
-
"-dGraphicsAlphaBits=#{render_antialias_bits}",
|
193
|
-
"-r#{render_dpi}",
|
194
|
-
"-sDEVICE=pnmraw",
|
195
|
-
"-sOutputFile=#{file}.pnm",
|
196
|
-
"#{file}.pdf"
|
197
|
-
|
198
|
-
|
199
|
-
img_width, img_height = pnm_width_height(file + ".pnm")
|
200
|
-
|
201
|
-
|
202
|
-
# --- Read dimensions file written by TeX during processing.
|
203
|
-
#
|
204
|
-
# Example of file contents:
|
205
|
-
# snippetdepth = 6.50009pt
|
206
|
-
# snippetheight = 13.53899pt
|
207
|
-
# snippetwidth = 145.4777pt
|
208
|
-
# pagewidth = 153.4777pt
|
209
|
-
# pageheight = 28.03908pt
|
210
|
-
# pagemargin = 4.0pt
|
211
|
-
dimensions = {}
|
212
|
-
::File.open(file + ".dimensions").readlines.each_with_index do |line, i|
|
213
|
-
if line =~ /^(\S+)\s+=\s+(-?[0-9\.]+)pt$/
|
214
|
-
dimensions[$1] = Float($2) / 72.27 * render_dpi
|
215
|
-
else
|
216
|
-
raise Error, "#{file}.dimensions: invalid line: #{i}"
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# --- Crop bottom, then measure how much was cropped.
|
221
|
-
sh "pnmcrop -white -bottom #{file}.pnm >#{file}.bottomcrop.pnm"
|
222
|
-
#raise Error, "`pnmcrop` command failed: #{result}" unless ::File.exist?(file + ".bottomcrop.pnm")
|
223
|
-
|
224
|
-
img_width_bottomcrop, img_height_bottomcrop = pnm_width_height("#{file}.bottomcrop.pnm")
|
225
|
-
bottomcrop = img_height - img_height_bottomcrop
|
226
|
-
|
227
|
-
# --- Crop top and sides, then measure how much was cropped from the top.
|
228
|
-
sh "pnmcrop -white #{file}.bottomcrop.pnm > #{file}.crop.pnm"
|
229
|
-
#raise Error, "`pnmcrop` command failed: #{result}" unless ::File.exist?(file + ".crop.pnm")
|
230
|
-
|
231
|
-
cropped_img_width, cropped_img_height = pnm_width_height("#{file}.crop.pnm")
|
232
|
-
topcrop = img_height_bottomcrop - cropped_img_height
|
233
|
-
|
234
|
-
# --- Pad image with specific values on all four sides, in preparation for
|
235
|
-
# downsampling.
|
236
|
-
|
237
|
-
# Calculate bottom padding.
|
238
|
-
snippet_depth = Integer(dimensions["snippetdepth"] + dimensions["pagemargin"] + 0.5) - bottomcrop
|
239
|
-
padded_snippet_depth = round_up(snippet_depth, oversample)
|
240
|
-
increase_snippet_depth = padded_snippet_depth - snippet_depth
|
241
|
-
bottom_padding = increase_snippet_depth
|
242
|
-
|
243
|
-
# --- Next calculate top padding, which depends on bottom padding.
|
244
|
-
|
245
|
-
padded_img_height = round_up(cropped_img_height + bottom_padding,
|
246
|
-
oversample)
|
247
|
-
top_padding = padded_img_height - (cropped_img_height + bottom_padding)
|
248
|
-
|
249
|
-
|
250
|
-
# --- Calculate left and right side padding. Distribute padding evenly.
|
251
|
-
|
252
|
-
padded_img_width = round_up(cropped_img_width, oversample)
|
253
|
-
left_padding = Integer((padded_img_width - cropped_img_width) / 2.0)
|
254
|
-
right_padding = (padded_img_width - cropped_img_width) - left_padding
|
255
|
-
|
256
|
-
|
257
|
-
# --- Pad the final image.
|
258
|
-
result = sh "pnmpad",
|
259
|
-
"-white",
|
260
|
-
"-bottom=#{bottom_padding}",
|
261
|
-
"-top=#{top_padding}",
|
262
|
-
"-left=#{left_padding}",
|
263
|
-
"-right=#{right_padding}",
|
264
|
-
"#{file}.crop.pnm",
|
265
|
-
">#{file}.pad.pnm"
|
266
|
-
|
267
|
-
# --- Sanity check of final size.
|
268
|
-
final_pnm_width, final_pnm_height = pnm_width_height(file + ".pad.pnm")
|
269
|
-
raise Error, "#{final_pnm_width} is not a multiple of #{oversample}" unless final_pnm_width % oversample == 0
|
270
|
-
|
271
|
-
raise "#{final_pnm_height} is not a multiple of #{oversample}" unless final_pnm_height % oversample == 0
|
272
|
-
|
273
|
-
# --- Convert PNM to PNG.
|
274
|
-
|
275
|
-
final_png_width = final_pnm_width / render_oversample
|
276
|
-
final_png_height = final_pnm_height / render_oversample
|
277
|
-
|
278
|
-
result = sh "cat #{file}.pad.pnm",
|
279
|
-
"| ppmtopgm",
|
280
|
-
"| pnmscale -reduce #{render_oversample}",
|
281
|
-
"| pnmgamma #{gamma}",
|
282
|
-
"| pnmtopng -compression 9",
|
283
|
-
"> #{file}.png"
|
284
|
-
|
285
|
-
raise Error, "Conversion to png failed: #{result}" unless ::File.exist?(file + ".png")
|
286
|
-
|
287
|
-
# Calculate html properties
|
288
|
-
html_img_width = final_png_width / display_oversample
|
289
|
-
html_img_height = final_png_height / display_oversample
|
290
|
-
html_img_vertical_align = sprintf("%.0f", -padded_snippet_depth / oversample)
|
291
|
-
png_data_base64 = Base64.encode64(::File.open("#{file}.png") { |io| io.read }).chomp
|
292
|
-
|
293
|
-
::File.open(cache_file, 'w') { |f| f.write(%{#{html_img_width},#{html_img_height},#{html_img_vertical_align},#{png_data_base64}}) }
|
294
|
-
if with_properties
|
295
|
-
return html_img_width, html_img_height, html_img_vertical_align, png_data_base64
|
296
|
-
else
|
297
|
-
::File.read(file + ".png")
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
private
|
303
|
-
def self.sh_chdir(path, *args)
|
304
|
-
origcommand = args * " "
|
305
|
-
return if origcommand == ""
|
306
|
-
|
307
|
-
command = origcommand
|
308
|
-
command.gsub! /(["\\])/, "\\$1"
|
309
|
-
command = %{/bin/sh -c "(#{command}) 2>&1"}
|
310
|
-
|
311
|
-
pid = spawn command, :chdir => path
|
312
|
-
|
313
|
-
result = Process::waitpid(pid)
|
314
|
-
exit_value = Integer($? >> 8), signal_num = Integer($? & 127), dumped_core = Integer($? & 128)
|
315
|
-
raise Error, "Failed #{result}: #{origcommand}. Exit value = #{exit_value}. Signal Num = #{signal_num}. Dumped core = #{dumped_core}" unless $?.success?
|
316
|
-
|
317
|
-
return result
|
318
|
-
end
|
319
|
-
|
320
|
-
def self.sh(*args)
|
321
|
-
origcommand = args * " "
|
322
|
-
return if origcommand == ""
|
323
|
-
|
324
|
-
command = origcommand
|
325
|
-
command.gsub! /(["\\])/, "\\$1"
|
326
|
-
command = %{/bin/sh -c "(#{command}) 2>&1"}
|
327
|
-
|
328
|
-
pid = spawn command
|
329
|
-
#pid = spawn *args
|
330
|
-
result = Process::waitpid(pid)
|
331
|
-
exit_value = $? >> 8, signal_num = $? & 127, dumped_core = $? & 128
|
332
|
-
raise Error, "Failed #{result}: #{origcommand}. Exit value = #{exit_value}. Signal Num = #{signal_num}. Dumped core = #{dumped_core}" unless $?.success?
|
333
|
-
|
334
|
-
return result
|
335
|
-
end
|
336
|
-
|
337
|
-
def self.round_up(num, mod)
|
338
|
-
num + (num % mod == 0 ? 0 : (mod - (num % mod)))
|
339
|
-
end
|
340
|
-
|
341
|
-
def self.pnm_width_height(filename)
|
342
|
-
raise Error, "#{filename} is not a .pnm file" if filename !~ /\.pnm$/
|
343
|
-
|
344
|
-
width = nil, height = nil
|
345
|
-
::File.open(filename) do |file|
|
346
|
-
# Read first line
|
347
|
-
line = file.gets
|
348
|
-
begin
|
349
|
-
line = file.gets # Read next line, skipping comments
|
350
|
-
end while line && line =~ /^#/
|
351
|
-
|
352
|
-
if line =~ /^(\d+)\s+(\d+)$/
|
353
|
-
width = Integer($1)
|
354
|
-
height = Integer($2)
|
355
|
-
else
|
356
|
-
raise Error, "#{filename}: couldn't read image size"
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
raise Error, "#{filename}: couldn't read image size" unless width && height
|
361
|
-
|
362
|
-
return width, height
|
363
|
-
end
|
364
|
-
|
365
13
|
end
|
366
14
|
end
|
data/test/test_markup.rb
CHANGED
@@ -670,13 +670,13 @@ end
|
|
670
670
|
|
671
671
|
test "TeX block syntax" do
|
672
672
|
content = 'a \[ a^2 \] b'
|
673
|
-
output = "<p>a<
|
673
|
+
output = "<p>a<imgsrc=\"http://www.mathtran.org/cgi-bin/toy/?D=4;tex=a^2\"alt=\"a^2\">b</p>"
|
674
674
|
compare(content, output, 'md')
|
675
675
|
end
|
676
676
|
|
677
677
|
test "TeX inline syntax" do
|
678
678
|
content = 'a \( a^2 \) b'
|
679
|
-
output = "<p>a<
|
679
|
+
output = "<p>a<imgsrc=\"http://www.mathtran.org/cgi-bin/toy/?D=2;tex=a^2\"alt=\"a^2\">b</p>"
|
680
680
|
compare(content, output, 'md')
|
681
681
|
end
|
682
682
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gollum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 2.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 2.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tom Preston-Werner
|
@@ -16,11 +16,10 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-
|
19
|
+
date: 2012-09-01 00:00:00 +02:00
|
20
|
+
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: grit
|
23
|
-
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
@@ -32,11 +31,11 @@ dependencies:
|
|
32
31
|
- 5
|
33
32
|
- 0
|
34
33
|
version: 2.5.0
|
35
|
-
type: :runtime
|
36
34
|
version_requirements: *id001
|
37
|
-
|
38
|
-
name: github-markup
|
35
|
+
name: grit
|
39
36
|
prerelease: false
|
37
|
+
type: :runtime
|
38
|
+
- !ruby/object:Gem::Dependency
|
40
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
40
|
none: false
|
42
41
|
requirements:
|
@@ -56,11 +55,11 @@ dependencies:
|
|
56
55
|
- 0
|
57
56
|
- 0
|
58
57
|
version: 1.0.0
|
59
|
-
type: :runtime
|
60
58
|
version_requirements: *id002
|
61
|
-
|
62
|
-
name: github-markdown
|
59
|
+
name: github-markup
|
63
60
|
prerelease: false
|
61
|
+
type: :runtime
|
62
|
+
- !ruby/object:Gem::Dependency
|
64
63
|
requirement: &id003 !ruby/object:Gem::Requirement
|
65
64
|
none: false
|
66
65
|
requirements:
|
@@ -70,11 +69,11 @@ dependencies:
|
|
70
69
|
segments:
|
71
70
|
- 0
|
72
71
|
version: "0"
|
73
|
-
type: :runtime
|
74
72
|
version_requirements: *id003
|
75
|
-
|
76
|
-
name: pygments.rb
|
73
|
+
name: github-markdown
|
77
74
|
prerelease: false
|
75
|
+
type: :runtime
|
76
|
+
- !ruby/object:Gem::Dependency
|
78
77
|
requirement: &id004 !ruby/object:Gem::Requirement
|
79
78
|
none: false
|
80
79
|
requirements:
|
@@ -86,27 +85,27 @@ dependencies:
|
|
86
85
|
- 2
|
87
86
|
- 0
|
88
87
|
version: 0.2.0
|
89
|
-
type: :runtime
|
90
88
|
version_requirements: *id004
|
91
|
-
|
92
|
-
name: posix-spawn
|
89
|
+
name: pygments.rb
|
93
90
|
prerelease: false
|
91
|
+
type: :runtime
|
92
|
+
- !ruby/object:Gem::Dependency
|
94
93
|
requirement: &id005 !ruby/object:Gem::Requirement
|
95
94
|
none: false
|
96
95
|
requirements:
|
97
|
-
- -
|
96
|
+
- - "="
|
98
97
|
- !ruby/object:Gem::Version
|
99
|
-
hash:
|
98
|
+
hash: 31
|
100
99
|
segments:
|
101
100
|
- 0
|
102
|
-
-
|
103
|
-
-
|
104
|
-
version: 0.
|
105
|
-
type: :runtime
|
101
|
+
- 2
|
102
|
+
- 4
|
103
|
+
version: 0.2.4
|
106
104
|
version_requirements: *id005
|
107
|
-
|
108
|
-
name: sinatra
|
105
|
+
name: escape_utils
|
109
106
|
prerelease: false
|
107
|
+
type: :runtime
|
108
|
+
- !ruby/object:Gem::Dependency
|
110
109
|
requirement: &id006 !ruby/object:Gem::Requirement
|
111
110
|
none: false
|
112
111
|
requirements:
|
@@ -117,11 +116,11 @@ dependencies:
|
|
117
116
|
- 1
|
118
117
|
- 0
|
119
118
|
version: "1.0"
|
120
|
-
type: :runtime
|
121
119
|
version_requirements: *id006
|
122
|
-
|
123
|
-
name: mustache
|
120
|
+
name: sinatra
|
124
121
|
prerelease: false
|
122
|
+
type: :runtime
|
123
|
+
- !ruby/object:Gem::Dependency
|
125
124
|
requirement: &id007 !ruby/object:Gem::Requirement
|
126
125
|
none: false
|
127
126
|
requirements:
|
@@ -141,11 +140,11 @@ dependencies:
|
|
141
140
|
- 0
|
142
141
|
- 0
|
143
142
|
version: 1.0.0
|
144
|
-
type: :runtime
|
145
143
|
version_requirements: *id007
|
146
|
-
|
147
|
-
name: sanitize
|
144
|
+
name: mustache
|
148
145
|
prerelease: false
|
146
|
+
type: :runtime
|
147
|
+
- !ruby/object:Gem::Dependency
|
149
148
|
requirement: &id008 !ruby/object:Gem::Requirement
|
150
149
|
none: false
|
151
150
|
requirements:
|
@@ -157,11 +156,11 @@ dependencies:
|
|
157
156
|
- 0
|
158
157
|
- 0
|
159
158
|
version: 2.0.0
|
160
|
-
type: :runtime
|
161
159
|
version_requirements: *id008
|
162
|
-
|
163
|
-
name: nokogiri
|
160
|
+
name: sanitize
|
164
161
|
prerelease: false
|
162
|
+
type: :runtime
|
163
|
+
- !ruby/object:Gem::Dependency
|
165
164
|
requirement: &id009 !ruby/object:Gem::Requirement
|
166
165
|
none: false
|
167
166
|
requirements:
|
@@ -172,11 +171,11 @@ dependencies:
|
|
172
171
|
- 1
|
173
172
|
- 4
|
174
173
|
version: "1.4"
|
175
|
-
type: :runtime
|
176
174
|
version_requirements: *id009
|
177
|
-
|
178
|
-
name: useragent
|
175
|
+
name: nokogiri
|
179
176
|
prerelease: false
|
177
|
+
type: :runtime
|
178
|
+
- !ruby/object:Gem::Dependency
|
180
179
|
requirement: &id010 !ruby/object:Gem::Requirement
|
181
180
|
none: false
|
182
181
|
requirements:
|
@@ -188,11 +187,11 @@ dependencies:
|
|
188
187
|
- 4
|
189
188
|
- 9
|
190
189
|
version: 0.4.9
|
191
|
-
type: :runtime
|
192
190
|
version_requirements: *id010
|
193
|
-
|
194
|
-
name: stringex
|
191
|
+
name: useragent
|
195
192
|
prerelease: false
|
193
|
+
type: :runtime
|
194
|
+
- !ruby/object:Gem::Dependency
|
196
195
|
requirement: &id011 !ruby/object:Gem::Requirement
|
197
196
|
none: false
|
198
197
|
requirements:
|
@@ -204,11 +203,11 @@ dependencies:
|
|
204
203
|
- 4
|
205
204
|
- 0
|
206
205
|
version: 1.4.0
|
207
|
-
type: :runtime
|
208
206
|
version_requirements: *id011
|
209
|
-
|
210
|
-
name: RedCloth
|
207
|
+
name: stringex
|
211
208
|
prerelease: false
|
209
|
+
type: :runtime
|
210
|
+
- !ruby/object:Gem::Dependency
|
212
211
|
requirement: &id012 !ruby/object:Gem::Requirement
|
213
212
|
none: false
|
214
213
|
requirements:
|
@@ -218,11 +217,11 @@ dependencies:
|
|
218
217
|
segments:
|
219
218
|
- 0
|
220
219
|
version: "0"
|
221
|
-
type: :development
|
222
220
|
version_requirements: *id012
|
223
|
-
|
224
|
-
name: mocha
|
221
|
+
name: RedCloth
|
225
222
|
prerelease: false
|
223
|
+
type: :development
|
224
|
+
- !ruby/object:Gem::Dependency
|
226
225
|
requirement: &id013 !ruby/object:Gem::Requirement
|
227
226
|
none: false
|
228
227
|
requirements:
|
@@ -232,11 +231,11 @@ dependencies:
|
|
232
231
|
segments:
|
233
232
|
- 0
|
234
233
|
version: "0"
|
235
|
-
type: :development
|
236
234
|
version_requirements: *id013
|
237
|
-
|
238
|
-
name: org-ruby
|
235
|
+
name: mocha
|
239
236
|
prerelease: false
|
237
|
+
type: :development
|
238
|
+
- !ruby/object:Gem::Dependency
|
240
239
|
requirement: &id014 !ruby/object:Gem::Requirement
|
241
240
|
none: false
|
242
241
|
requirements:
|
@@ -248,11 +247,11 @@ dependencies:
|
|
248
247
|
- 7
|
249
248
|
- 0
|
250
249
|
version: 0.7.0
|
251
|
-
type: :development
|
252
250
|
version_requirements: *id014
|
253
|
-
-
|
254
|
-
name: shoulda
|
251
|
+
name: org-ruby
|
255
252
|
prerelease: false
|
253
|
+
type: :development
|
254
|
+
- !ruby/object:Gem::Dependency
|
256
255
|
requirement: &id015 !ruby/object:Gem::Requirement
|
257
256
|
none: false
|
258
257
|
requirements:
|
@@ -262,11 +261,11 @@ dependencies:
|
|
262
261
|
segments:
|
263
262
|
- 0
|
264
263
|
version: "0"
|
265
|
-
type: :development
|
266
264
|
version_requirements: *id015
|
267
|
-
|
268
|
-
name: rack-test
|
265
|
+
name: shoulda
|
269
266
|
prerelease: false
|
267
|
+
type: :development
|
268
|
+
- !ruby/object:Gem::Dependency
|
270
269
|
requirement: &id016 !ruby/object:Gem::Requirement
|
271
270
|
none: false
|
272
271
|
requirements:
|
@@ -276,11 +275,11 @@ dependencies:
|
|
276
275
|
segments:
|
277
276
|
- 0
|
278
277
|
version: "0"
|
279
|
-
type: :development
|
280
278
|
version_requirements: *id016
|
281
|
-
|
282
|
-
name: wikicloth
|
279
|
+
name: rack-test
|
283
280
|
prerelease: false
|
281
|
+
type: :development
|
282
|
+
- !ruby/object:Gem::Dependency
|
284
283
|
requirement: &id017 !ruby/object:Gem::Requirement
|
285
284
|
none: false
|
286
285
|
requirements:
|
@@ -292,11 +291,11 @@ dependencies:
|
|
292
291
|
- 8
|
293
292
|
- 0
|
294
293
|
version: 0.8.0
|
295
|
-
type: :development
|
296
294
|
version_requirements: *id017
|
297
|
-
|
298
|
-
name: rake
|
295
|
+
name: wikicloth
|
299
296
|
prerelease: false
|
297
|
+
type: :development
|
298
|
+
- !ruby/object:Gem::Dependency
|
300
299
|
requirement: &id018 !ruby/object:Gem::Requirement
|
301
300
|
none: false
|
302
301
|
requirements:
|
@@ -308,8 +307,10 @@ dependencies:
|
|
308
307
|
- 9
|
309
308
|
- 2
|
310
309
|
version: 0.9.2
|
311
|
-
type: :development
|
312
310
|
version_requirements: *id018
|
311
|
+
name: rake
|
312
|
+
prerelease: false
|
313
|
+
type: :development
|
313
314
|
description: A simple, Git-powered wiki with a sweet API and local frontend.
|
314
315
|
email: tom@github.com
|
315
316
|
executables:
|
@@ -887,6 +888,7 @@ files:
|
|
887
888
|
- test/test_pages_view.rb
|
888
889
|
- test/test_unicode.rb
|
889
890
|
- test/test_wiki.rb
|
891
|
+
has_rdoc: true
|
890
892
|
homepage: http://github.com/github/gollum
|
891
893
|
licenses: []
|
892
894
|
|
@@ -918,7 +920,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
918
920
|
requirements: []
|
919
921
|
|
920
922
|
rubyforge_project: gollum
|
921
|
-
rubygems_version: 1.
|
923
|
+
rubygems_version: 1.6.2
|
922
924
|
signing_key:
|
923
925
|
specification_version: 2
|
924
926
|
summary: A simple, Git-powered wiki.
|