polytexnic 0.7.7 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.pull_requests/1387507486 +0 -0
- data/.pull_requests/1387590643 +0 -0
- data/.pull_requests/1387944167 +0 -0
- data/.pull_requests/1388090414 +0 -0
- data/.pull_requests/1388112504 +0 -0
- data/.pull_requests/1388430185 +0 -0
- data/.pull_requests/1388440664 +0 -0
- data/lib/polytexnic/postprocessors/html.rb +25 -4
- data/lib/polytexnic/preprocessors/polytex.rb +105 -35
- data/lib/polytexnic/utils.rb +4 -4
- data/lib/polytexnic/version.rb +1 -1
- data/lib/polytexnic.rb +8 -4
- data/spec/markdown_to_polytex_spec.rb +64 -7
- data/spec/to_html/chapters_and_sections_spec.rb +5 -5
- data/spec/to_html/graphics_and_figures_spec.rb +35 -21
- data/spec/to_html/literal_environments/math_spec.rb +10 -2
- data/spec/to_html/table_of_contents_spec.rb +10 -6
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f04fe1c74528b59323dcdceedb4f2ab42eed546e
|
4
|
+
data.tar.gz: 0f1971101aea1434ee769d1e788b2a68fdd658b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebb92b98f47b6ac972556c4b04e6a61f1501efa266899061487918005a8f513a162c6b589991d755c15a3f27429b928e90c8f67c8286e53200b6c0465019d665
|
7
|
+
data.tar.gz: 30c0bcb1dacaf9b90c3dd8294273288591158c04e9288edacdc6eb9d6390b1d4b4c5aa8a1f7d46543eaf72e1bb236a488e0930d1df69aeccf78650cc94d6d5db
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -212,6 +212,14 @@ module Polytexnic
|
|
212
212
|
node['class'] = 'inline_math'
|
213
213
|
clean_node node, ['textype', 'type']
|
214
214
|
end
|
215
|
+
|
216
|
+
# using \ensuremath
|
217
|
+
doc.xpath('//texmath[@textype="inline"]').each do |node|
|
218
|
+
node.name = 'span'
|
219
|
+
node.content = "\\( #{node.content} \\)"
|
220
|
+
node['class'] = 'inline_math'
|
221
|
+
clean_node node, ['textype', 'type']
|
222
|
+
end
|
215
223
|
end
|
216
224
|
|
217
225
|
# Handles frontmatter (if any).
|
@@ -531,6 +539,9 @@ module Polytexnic
|
|
531
539
|
heading = 'h2'
|
532
540
|
end
|
533
541
|
if node['rend'] == 'nonumber'
|
542
|
+
# Add an id for linking based on the text of the section.
|
543
|
+
text = node.children.first.text
|
544
|
+
node['id'] = text.downcase.gsub(' ', '_')
|
534
545
|
node['class'] += '-star'
|
535
546
|
end
|
536
547
|
clean_node node, %w{type rend}
|
@@ -885,8 +896,8 @@ module Polytexnic
|
|
885
896
|
# Processes a graphic, including the description.
|
886
897
|
def process_graphic(node, options={})
|
887
898
|
klass = options[:klass]
|
888
|
-
node.name = 'div'
|
889
899
|
raw_graphic = (node['rend'] == 'inline')
|
900
|
+
node.name = raw_graphic ? 'span' : 'div'
|
890
901
|
unless raw_graphic
|
891
902
|
if node['class']
|
892
903
|
node['class'] += " #{klass}"
|
@@ -901,7 +912,7 @@ module Polytexnic
|
|
901
912
|
filename = png_for_pdf(node['file'], node['extension'])
|
902
913
|
alt = File.basename(node['file'])
|
903
914
|
img = %(<img src="#{filename}" alt="#{alt}" />)
|
904
|
-
graphic = %(<
|
915
|
+
graphic = %(<span class="graphics">#{img}</span>)
|
905
916
|
graphic_node = Nokogiri::HTML.fragment(graphic)
|
906
917
|
if description_node = node.children.first
|
907
918
|
description_node.add_previous_sibling(graphic_node)
|
@@ -962,8 +973,10 @@ module Polytexnic
|
|
962
973
|
full_caption['class'] = 'caption'
|
963
974
|
n = node['data-number']
|
964
975
|
if description_node = node.at_css('head')
|
965
|
-
|
966
|
-
|
976
|
+
content = description_node.inner_html
|
977
|
+
separator = content.empty? ? '' : ':'
|
978
|
+
h = %(<span class="header">#{name} #{n}#{separator} </span>)
|
979
|
+
d = %(<span class="description">#{content}</span>)
|
967
980
|
description_node.remove
|
968
981
|
full_caption.inner_html = Nokogiri::HTML.fragment(h + d)
|
969
982
|
else
|
@@ -1126,6 +1139,14 @@ module Polytexnic
|
|
1126
1139
|
end
|
1127
1140
|
current_depth = 1
|
1128
1141
|
insert_li(html, node)
|
1142
|
+
when 'chapter-star'
|
1143
|
+
html << '<ul>' if current_depth == 0
|
1144
|
+
while current_depth > 1
|
1145
|
+
close_list(html)
|
1146
|
+
current_depth -= 1
|
1147
|
+
end
|
1148
|
+
current_depth = 1
|
1149
|
+
insert_li(html, node)
|
1129
1150
|
when 'section'
|
1130
1151
|
open_list(html) if current_depth == 1
|
1131
1152
|
while current_depth > 2
|
@@ -1,4 +1,65 @@
|
|
1
1
|
# encoding=utf-8
|
2
|
+
|
3
|
+
require 'kramdown'
|
4
|
+
require 'securerandom'
|
5
|
+
|
6
|
+
$cache = {}
|
7
|
+
$label_salt = SecureRandom.hex
|
8
|
+
|
9
|
+
module Kramdown
|
10
|
+
module Converter
|
11
|
+
class Latex < Base
|
12
|
+
|
13
|
+
# Converts `inline codespan`.
|
14
|
+
# This overrides kramdown's default to use `\kode` instead of `\tt`.
|
15
|
+
def convert_codespan(el, opts)
|
16
|
+
"\\kode{#{latex_link_target(el)}#{escape(el.value)}}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Overrides default convert_a.
|
20
|
+
# Unfortunately, kramdown is too aggressive in escaping characters
|
21
|
+
# in hrefs, converting
|
22
|
+
# [foo bar](http://example.com/foo%20bar)
|
23
|
+
# into
|
24
|
+
# \href{http://example.com/foo\%20bar}{foo bar}
|
25
|
+
# The '\%20' in the href then won't work properly.
|
26
|
+
def convert_a(el, opts)
|
27
|
+
url = el.attr['href']
|
28
|
+
if url =~ /^#/
|
29
|
+
"\\hyperlink{#{escape(url[1..-1])}}{#{inner(el, opts)}}"
|
30
|
+
else
|
31
|
+
"\\href{#{url}}{#{inner(el, opts)}}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :original_convert_standalone_image, :convert_standalone_image
|
36
|
+
|
37
|
+
# Uses figures for images only when label is present.
|
38
|
+
# This allows users to put raw (centered) images in their documents.
|
39
|
+
# The default behavior of kramdown is to wrap such images in a figure
|
40
|
+
# environment, which causes LaTeX to (a) treat them as floats and (b)
|
41
|
+
# include a caption. This may not be what the user wants, and it's also
|
42
|
+
# nonstandard Markdown. On the other hand, it is really nice to be
|
43
|
+
# able to include captions using the default image syntax, so as a
|
44
|
+
# compromise we use Markdown behavior by default and kramdown behavior
|
45
|
+
# if the alt text contains a '\label' element.
|
46
|
+
def convert_standalone_image(el, opts, img)
|
47
|
+
alt_text = el.children.first.attr['alt']
|
48
|
+
if has_label?(alt_text)
|
49
|
+
original_convert_standalone_image(el, opts, img)
|
50
|
+
else
|
51
|
+
img.gsub('\includegraphics', '\image') + "\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Detects if text has a label.
|
56
|
+
def has_label?(text)
|
57
|
+
text.include?($label_salt)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
2
63
|
module Polytexnic
|
3
64
|
module Preprocessor
|
4
65
|
module Polytex
|
@@ -23,16 +84,14 @@ module Polytexnic
|
|
23
84
|
# At this point, I fear that "Markdown" has become little more than a
|
24
85
|
# marketing term.</rant>
|
25
86
|
def to_polytex
|
26
|
-
require 'kramdown'
|
27
|
-
cache = {}
|
28
87
|
math_cache = {}
|
29
88
|
cleaned_markdown = cache_code_environments(@source)
|
30
89
|
puts cleaned_markdown if debug?
|
31
90
|
cleaned_markdown.tap do |markdown|
|
32
|
-
convert_code_inclusion(markdown
|
33
|
-
cache_latex_literal(markdown
|
34
|
-
cache_raw_latex(markdown
|
35
|
-
cache_image_locations(markdown
|
91
|
+
convert_code_inclusion(markdown)
|
92
|
+
cache_latex_literal(markdown)
|
93
|
+
cache_raw_latex(markdown)
|
94
|
+
cache_image_locations(markdown)
|
36
95
|
puts markdown if debug?
|
37
96
|
cache_math(markdown, math_cache)
|
38
97
|
end
|
@@ -44,25 +103,24 @@ module Polytexnic
|
|
44
103
|
puts kramdown.to_html if debug?
|
45
104
|
puts kramdown.to_latex if debug?
|
46
105
|
@source = kramdown.to_latex.tap do |polytex|
|
47
|
-
|
106
|
+
remove_kramdown_comments(polytex)
|
48
107
|
convert_includegraphics(polytex)
|
49
|
-
convert_tt(polytex)
|
50
108
|
restore_math(polytex, math_cache)
|
51
|
-
restore_hashed_content(polytex
|
109
|
+
restore_hashed_content(polytex)
|
52
110
|
end
|
53
111
|
end
|
54
112
|
|
55
113
|
# Adds support for <<(path/to/code) inclusion.
|
56
|
-
def convert_code_inclusion(text
|
114
|
+
def convert_code_inclusion(text)
|
57
115
|
text.gsub!(/^\s*(<<\(.*?\))/) do
|
58
116
|
key = digest($1)
|
59
|
-
cache[key] = "%= #{$1}" # reduce to a previously solved case
|
117
|
+
$cache[key] = "%= #{$1}" # reduce to a previously solved case
|
60
118
|
key
|
61
119
|
end
|
62
120
|
end
|
63
121
|
|
64
122
|
# Caches literal LaTeX environments.
|
65
|
-
def cache_latex_literal(markdown
|
123
|
+
def cache_latex_literal(markdown)
|
66
124
|
# Add tabular and tabularx support.
|
67
125
|
literal_types = Polytexnic::Literal.literal_types + %w[tabular tabularx]
|
68
126
|
literal_types.each do |literal|
|
@@ -71,15 +129,16 @@ module Polytexnic
|
|
71
129
|
\\end\{#{Regexp.escape(literal)}\})
|
72
130
|
/xm
|
73
131
|
markdown.gsub!(regex) do
|
74
|
-
|
75
|
-
|
132
|
+
content = $1
|
133
|
+
key = digest(content)
|
134
|
+
$cache[key] = content
|
76
135
|
key
|
77
136
|
end
|
78
137
|
end
|
79
138
|
end
|
80
139
|
|
81
140
|
# Caches raw LaTeX commands to be passed through the pipeline.
|
82
|
-
def cache_raw_latex(markdown
|
141
|
+
def cache_raw_latex(markdown)
|
83
142
|
command_regex = /(
|
84
143
|
^[ \t]*\\\w+.*\}[ \t]*$ # Command on line with arg
|
85
144
|
|
|
@@ -102,7 +161,9 @@ module Polytexnic
|
|
102
161
|
content = $1
|
103
162
|
puts content.inspect if debug?
|
104
163
|
key = digest(content)
|
105
|
-
|
164
|
+
# Used to speed up has_label? in convert_standalone_image.
|
165
|
+
key += $label_salt if content.include?('\label')
|
166
|
+
$cache[key] = content
|
106
167
|
|
107
168
|
if content =~ /\{table\}|\\caption\{/
|
108
169
|
# Pad tables & captions with newlines for kramdown compatibility.
|
@@ -116,18 +177,18 @@ module Polytexnic
|
|
116
177
|
# Caches the locations of images to be passed through the pipeline.
|
117
178
|
# This works around a Kramdown bug, which fails to convert images
|
118
179
|
# properly when their location includes a URL.
|
119
|
-
def cache_image_locations(text
|
180
|
+
def cache_image_locations(text)
|
120
181
|
# Matches '![Image caption](/path/to/image)'
|
121
182
|
text.gsub!(/^\s*(!\[.*?\])\((.*?)\)/) do
|
122
183
|
key = digest($2)
|
123
|
-
cache[key] = $2
|
184
|
+
$cache[key] = $2
|
124
185
|
"\n#{$1}(#{key})"
|
125
186
|
end
|
126
187
|
end
|
127
188
|
|
128
|
-
# Restores raw code from the cache
|
129
|
-
def restore_hashed_content(text
|
130
|
-
cache.each do |key, value|
|
189
|
+
# Restores raw code from the cache.
|
190
|
+
def restore_hashed_content(text)
|
191
|
+
$cache.each do |key, value|
|
131
192
|
# Because of the way backslashes get interpolated, we need to add
|
132
193
|
# some extra ones to cover all the cases of hashed LaTeX.
|
133
194
|
text.gsub!(key, value.gsub(/\\/, '\\\\\\'))
|
@@ -177,20 +238,29 @@ module Polytexnic
|
|
177
238
|
output.join("\n")
|
178
239
|
end
|
179
240
|
|
180
|
-
#
|
241
|
+
# Removes comments produced by kramdown.
|
242
|
+
# These have the special form of always being at the beginning of the
|
243
|
+
# line.
|
244
|
+
def remove_kramdown_comments(text)
|
245
|
+
text.gsub!(/^% (.*)$/, '')
|
246
|
+
end
|
247
|
+
|
248
|
+
# Converts \includegraphics to \image inside figures.
|
181
249
|
# The reason is that raw \includegraphics is almost always too wide
|
182
250
|
# in the PDF. Instead, we use the custom-defined \image command, which
|
183
251
|
# is specifically designed to fix this issue.
|
184
252
|
def convert_includegraphics(text)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
253
|
+
in_figure = false
|
254
|
+
newtext = text.split("\n").map do |line|
|
255
|
+
line.gsub!('\includegraphics', '\image') if in_figure
|
256
|
+
if line =~ /^\s*\\begin\{figure\}/
|
257
|
+
in_figure = true
|
258
|
+
elsif line =~ /^\s*\\end\{figure\}/
|
259
|
+
in_figure = false
|
260
|
+
end
|
261
|
+
line
|
262
|
+
end.join("\n")
|
263
|
+
text.replace(newtext)
|
194
264
|
end
|
195
265
|
|
196
266
|
# Caches math.
|
@@ -204,12 +274,12 @@ module Polytexnic
|
|
204
274
|
# I personally hate this notation and convention, so we also support
|
205
275
|
# LaTeX-style \( x \) and \[ x^2 - 2 = 0 \] notation.
|
206
276
|
def cache_math(text, cache)
|
207
|
-
text.gsub!(/(?:\{\$\$\}\n(.*?)\n\{\/\$\$\}|\\\[(.*?)\\\])/) do
|
277
|
+
text.gsub!(/(?:\{\$\$\}\n(.*?)\n\{\/\$\$\}|\\\[(.*?)\\\])/m) do
|
208
278
|
key = digest($1 || $2)
|
209
279
|
cache[[:block, key]] = $1 || $2
|
210
280
|
key
|
211
281
|
end
|
212
|
-
text.gsub!(/(?:\{\$\$\}(.*?)\{\/\$\$\}|\\\((.*?)\\\))/) do
|
282
|
+
text.gsub!(/(?:\{\$\$\}(.*?)\{\/\$\$\}|\\\((.*?)\\\))/m) do
|
213
283
|
key = digest($1 || $2)
|
214
284
|
cache[[:inline, key]] = $1 || $2
|
215
285
|
key
|
@@ -226,8 +296,8 @@ module Polytexnic
|
|
226
296
|
open = '\('
|
227
297
|
close = '\)'
|
228
298
|
when :block
|
229
|
-
open = '\['
|
230
|
-
close =
|
299
|
+
open = '\['
|
300
|
+
close = '\]'
|
231
301
|
end
|
232
302
|
text.gsub!(key, open + value + close)
|
233
303
|
end
|
data/lib/polytexnic/utils.rb
CHANGED
@@ -164,12 +164,12 @@ module Polytexnic
|
|
164
164
|
# We prepend rather than replace the styles because the Pygments output
|
165
165
|
# includes a required override of the default commandchars.
|
166
166
|
# Since the substitution is only important in the context of a PDF book,
|
167
|
-
# it only gets made if there's a style in 'softcover.sty'
|
168
|
-
# current directory
|
167
|
+
# it only gets made if there's a style in the 'softcover.sty' file.
|
169
168
|
def add_font_info(string)
|
170
|
-
|
169
|
+
softcover_sty = File.join('latex_styles', 'softcover.sty')
|
170
|
+
if File.exist?(softcover_sty)
|
171
171
|
regex = '{code}{Verbatim}{(.*)}'
|
172
|
-
styles = File.read(
|
172
|
+
styles = File.read(softcover_sty).scan(/#{regex}/).flatten.first
|
173
173
|
string.gsub!("\\begin{Verbatim}[",
|
174
174
|
"\\begin{Verbatim}[#{styles},")
|
175
175
|
end
|
data/lib/polytexnic/version.rb
CHANGED
data/lib/polytexnic.rb
CHANGED
@@ -14,13 +14,17 @@ module Polytexnic
|
|
14
14
|
'polytexnic_commands.sty'
|
15
15
|
end
|
16
16
|
|
17
|
+
# Returns style file (including absolute path) within the gem.
|
18
|
+
def self.core_style_file
|
19
|
+
File.join(File.dirname(__FILE__), '..', style_file)
|
20
|
+
end
|
21
|
+
|
17
22
|
# Writes the contents of the custom polytexnic style file.
|
18
23
|
# This is used by the `generate` method in the `softcover` gem.
|
19
|
-
# We put it here because `
|
24
|
+
# We put it here because `polytexnic_commands.sty` lives inside `polytexnic`
|
20
25
|
# so that core can support, e.g., '\PolyTeXnic'.
|
21
26
|
def self.write_polytexnic_style_file(dir)
|
22
|
-
|
23
|
-
File.write(File.join(dir, style_file), File.read(csf))
|
27
|
+
File.write(File.join(dir, style_file), File.read(self.core_style_file))
|
24
28
|
end
|
25
29
|
|
26
30
|
class Pipeline
|
@@ -45,7 +49,7 @@ module Polytexnic
|
|
45
49
|
@highlight_cache ||= {}
|
46
50
|
@math_label_cache = {}
|
47
51
|
@source_format = options[:source] || :polytex
|
48
|
-
@custom_commands = File.read(Polytexnic.
|
52
|
+
@custom_commands = File.read(Polytexnic.core_style_file) rescue ''
|
49
53
|
@custom_commands += "\n" + (options[:custom_commands] || '')
|
50
54
|
@source = source
|
51
55
|
if markdown?
|
@@ -45,6 +45,18 @@ Lorem ipsum
|
|
45
45
|
it { should include source }
|
46
46
|
end
|
47
47
|
|
48
|
+
context "links" do
|
49
|
+
context "with normal text" do
|
50
|
+
let(:source) { '[foo](http://example.com/)' }
|
51
|
+
it { should include '\href{http://example.com/}{foo}' }
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with a percent" do
|
55
|
+
let(:source) { '[foo bar](http://example.com/foo%20bar)' }
|
56
|
+
it { should include '\href{http://example.com/foo%20bar}{foo bar}' }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
48
60
|
describe "with math" do
|
49
61
|
|
50
62
|
context "inline math" do
|
@@ -65,7 +77,7 @@ x^2
|
|
65
77
|
EOS
|
66
78
|
end
|
67
79
|
|
68
|
-
it { should resemble '\[
|
80
|
+
it { should resemble '\[x^2\]' }
|
69
81
|
end
|
70
82
|
end
|
71
83
|
|
@@ -147,14 +159,39 @@ That is it. You can keep writing your text after the footnote content.
|
|
147
159
|
Polytexnic::Pipeline.new(markdown, source: :markdown).polytex
|
148
160
|
end
|
149
161
|
|
162
|
+
context "inline" do
|
163
|
+
let(:markdown) { 'Inline ![Caption](img.png) image' }
|
164
|
+
it { should include '\includegraphics{img.png}' }
|
165
|
+
it { should_not include '\image' }
|
166
|
+
end
|
167
|
+
|
168
|
+
context "with only a label" do
|
169
|
+
let(:markdown) do <<-'EOS'
|
170
|
+
![\label{fig:softcover_server}](images/figures/softcover_server.png)
|
171
|
+
EOS
|
172
|
+
end
|
173
|
+
it { should include '\caption' }
|
174
|
+
end
|
175
|
+
|
176
|
+
context "with alt text but no label" do
|
177
|
+
let(:markdown) do <<-'EOS'
|
178
|
+
![Running the Softcover server in a separate tab.](images/figures/softcover_server.png)
|
179
|
+
EOS
|
180
|
+
end
|
181
|
+
|
182
|
+
it { should_not include '\begin{figure}' }
|
183
|
+
it { should_not include '\caption' }
|
184
|
+
it { should include '\image' }
|
185
|
+
end
|
186
|
+
|
150
187
|
context "with a caption and a label" do
|
151
188
|
let(:markdown) do <<-'EOS'
|
152
189
|
![Running the Softcover server in a separate tab.\label{fig:softcover_server}](images/figures/softcover_server.png)
|
153
190
|
EOS
|
154
191
|
end
|
155
192
|
|
156
|
-
it { should
|
157
|
-
it { should
|
193
|
+
it { should include '\caption{Running the Softcover server in a separate tab.\label{fig:softcover_server}}' }
|
194
|
+
it { should include '\image' }
|
158
195
|
it { should_not include '\includegraphics' }
|
159
196
|
end
|
160
197
|
|
@@ -163,14 +200,14 @@ That is it. You can keep writing your text after the footnote content.
|
|
163
200
|
a screenshot from [Lowdown](http://lowdownapp.com/), a web
|
164
201
|
application that developers use for organizing user stories.
|
165
202
|
|
166
|
-
![Lowdown for user stories](https://tutorials.railsapps.org/assets/learn-rails-lowdown-partial.png)
|
203
|
+
![Lowdown for user stories\label{fig:lowdown}](https://tutorials.railsapps.org/assets/learn-rails-lowdown-partial.png)
|
167
204
|
|
168
205
|
Just like Rails provides a structure for building a web application,
|
169
206
|
user stories provide a structure for organizing your product plan.
|
170
207
|
EOS
|
171
208
|
end
|
172
209
|
|
173
|
-
it { should include '\caption{Lowdown for user stories
|
210
|
+
it { should include '\caption{Lowdown for user stories' }
|
174
211
|
it { should include '\image{https://tutorials.railsapps.org' }
|
175
212
|
end
|
176
213
|
|
@@ -215,11 +252,26 @@ Chapter~\ref{cha:one}
|
|
215
252
|
it { should include source }
|
216
253
|
end
|
217
254
|
|
255
|
+
context "an inline equation with a newline" do
|
256
|
+
let(:source) { '\( x' + "\n" + ' + y \) is a sum' }
|
257
|
+
it { should include source }
|
258
|
+
end
|
259
|
+
|
218
260
|
context "a centered equation" do
|
219
261
|
let(:source) { '\[ x^2 - 2 = 0 \] is an equation' }
|
220
262
|
it { should resemble source }
|
221
263
|
end
|
222
264
|
|
265
|
+
context "a centered equation with a newline" do
|
266
|
+
let(:source) do <<-'EOS'
|
267
|
+
\[
|
268
|
+
\left(\frac{p}{q}\right) \left(\frac{q}{p}\right) = (-1)^{[(p-1)/2][(q-1)/2]} \quad\text{($p$, $q$ distinct odd primes)}
|
269
|
+
\]
|
270
|
+
EOS
|
271
|
+
end
|
272
|
+
it { should include source.chomp }
|
273
|
+
end
|
274
|
+
|
223
275
|
context "an equation environment" do
|
224
276
|
let(:source) do <<-'EOS'
|
225
277
|
foo
|
@@ -274,7 +326,7 @@ def foo; "bar"; end
|
|
274
326
|
EOS
|
275
327
|
end
|
276
328
|
it { should include '%= foo:bar' }
|
277
|
-
it { should_not
|
329
|
+
it { should_not match /^\\begin\{code\}/ }
|
278
330
|
end
|
279
331
|
|
280
332
|
context "code inclusion inside codelisting" do
|
@@ -322,6 +374,11 @@ def foo; "bar"; end
|
|
322
374
|
it { should include '\kode{foo bar}' }
|
323
375
|
end
|
324
376
|
|
377
|
+
context "inline with a newline" do
|
378
|
+
let(:source) { "`foo\nbar`" }
|
379
|
+
it { should include "\\kode{foo\nbar}" }
|
380
|
+
end
|
381
|
+
|
325
382
|
context "without highlighting" do
|
326
383
|
let(:source) do <<-EOS
|
327
384
|
def foo
|
@@ -337,7 +394,7 @@ end
|
|
337
394
|
\end{verbatim}
|
338
395
|
EOS
|
339
396
|
end
|
340
|
-
it { should
|
397
|
+
it { should resemble output }
|
341
398
|
end
|
342
399
|
|
343
400
|
context "with highlighting" do
|
@@ -129,11 +129,11 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
129
129
|
|
130
130
|
describe '\chapter*' do
|
131
131
|
let(:polytex) do <<-'EOS'
|
132
|
-
\chapter*{
|
132
|
+
\chapter*{A preface}
|
133
133
|
Lorem ipsum
|
134
134
|
EOS
|
135
135
|
end
|
136
|
-
it { should resemble '<div class="chapter-star">' }
|
136
|
+
it { should resemble '<div class="chapter-star" id="a_preface">' }
|
137
137
|
end
|
138
138
|
|
139
139
|
describe '\section*, etc.' do
|
@@ -148,8 +148,8 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
148
148
|
EOS
|
149
149
|
end
|
150
150
|
let(:output) do <<-'EOS'
|
151
|
-
<div class="section-star">
|
152
|
-
<h2><a class="heading">Foo</a></h2>
|
151
|
+
<div class="section-star" id="foo">
|
152
|
+
<h2><a href="#foo" class="heading">Foo</a></h2>
|
153
153
|
<div class="subsection-star">
|
154
154
|
<h3><a class="heading">Bar</a></h3>
|
155
155
|
<p>Lorem ipsum</p>
|
@@ -273,7 +273,7 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
273
273
|
it do
|
274
274
|
should resemble <<-'EOS'
|
275
275
|
<div id="frontmatter" data-number="0">
|
276
|
-
<div class="chapter-star"><h1><a class="heading">Foo</a></h1>
|
276
|
+
<div class="chapter-star" id="foo"><h1><a href="#foo" class="heading">Foo</a></h1>
|
277
277
|
<p>Lorem ipsum.<sup id="cha-0_footnote-ref-1" class="footnote"><a href="#cha-0_footnote-1">1</a></sup></p>
|
278
278
|
</div></div>
|
279
279
|
<div id="cha-0_footnotes">
|
@@ -7,15 +7,15 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
7
7
|
|
8
8
|
describe "graphics" do
|
9
9
|
let(:polytex) do <<-'EOS'
|
10
|
-
\includegraphics{foo.png}
|
10
|
+
foo \includegraphics{foo.png} bar
|
11
11
|
EOS
|
12
12
|
end
|
13
13
|
|
14
14
|
it do
|
15
15
|
should resemble <<-'EOS'
|
16
|
-
<
|
17
|
-
<img src="foo.png" alt="foo"
|
18
|
-
</
|
16
|
+
foo <span><span class="graphics">
|
17
|
+
<img src="foo.png" alt="foo" /></span>
|
18
|
+
</span>
|
19
19
|
EOS
|
20
20
|
end
|
21
21
|
it { should_not resemble 'class="figure"' }
|
@@ -29,9 +29,9 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
29
29
|
|
30
30
|
it do
|
31
31
|
should resemble <<-'EOS'
|
32
|
-
<
|
32
|
+
<span class="graphics">
|
33
33
|
<img src="foo.png" alt="foo" />
|
34
|
-
</
|
34
|
+
</span>
|
35
35
|
EOS
|
36
36
|
end
|
37
37
|
end
|
@@ -116,9 +116,9 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
116
116
|
it do
|
117
117
|
should resemble <<-'EOS'
|
118
118
|
<div id="fig-foo" data-tralics-id="uid1" data-number="1" class="figure">
|
119
|
-
<
|
119
|
+
<span class="graphics">
|
120
120
|
<img src="images/foo.png" alt="foo" />
|
121
|
-
</
|
121
|
+
</span>
|
122
122
|
<div class="caption">
|
123
123
|
<span class="header">Figure 1</span>
|
124
124
|
</div>
|
@@ -151,18 +151,18 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
151
151
|
<span class="number">Chapter 1 </span>The chapter</a>
|
152
152
|
</h1>
|
153
153
|
<div id="uid1" data-tralics-id="uid1" data-number="1.1" class="figure">
|
154
|
-
<
|
154
|
+
<span class="graphics">
|
155
155
|
<img src="foo.png" alt="foo" />
|
156
|
-
</
|
156
|
+
</span>
|
157
157
|
<div class="caption">
|
158
158
|
<span class="header">Figure 1.1: </span>
|
159
159
|
<span class="description">This is a <em>caption</em> with <span class="inline_math">\( x \)</span>.</span>
|
160
160
|
</div>
|
161
161
|
</div>
|
162
162
|
<div id="uid2" data-tralics-id="uid2" data-number="1.2" class="figure">
|
163
|
-
<
|
163
|
+
<span class="graphics">
|
164
164
|
<img src="bar.png" alt="bar" />
|
165
|
-
</
|
165
|
+
</span>
|
166
166
|
<div class="caption">
|
167
167
|
<span class="header">Figure 1.2: </span>
|
168
168
|
<span class="description">This is another caption.</span>
|
@@ -173,7 +173,21 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
176
|
-
context "with
|
176
|
+
context "with a caption containing only a label" do
|
177
|
+
let(:polytex) do <<-'EOS'
|
178
|
+
\chapter{The chapter}
|
179
|
+
|
180
|
+
\begin{figure}
|
181
|
+
\includegraphics{foo.png}
|
182
|
+
\caption{\label{fig:foo}}
|
183
|
+
\end{figure}
|
184
|
+
EOS
|
185
|
+
end
|
186
|
+
it { should include 'Figure 1.1' }
|
187
|
+
it { should_not include 'Figure 1.1:' }
|
188
|
+
end
|
189
|
+
|
190
|
+
context "with labels and cross-references" do
|
177
191
|
let(:polytex) do <<-'EOS'
|
178
192
|
\chapter{The chapter}
|
179
193
|
\label{cha:lorem_ipsum}
|
@@ -210,18 +224,18 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
210
224
|
<span class="number">Chapter 1 </span>The chapter</a>
|
211
225
|
</h1>
|
212
226
|
<div id="fig-foo" data-tralics-id="uid1" data-number="1.1" class="figure">
|
213
|
-
<
|
227
|
+
<span class="graphics">
|
214
228
|
<img src="foo.png" alt="foo" />
|
215
|
-
</
|
229
|
+
</span>
|
216
230
|
<div class="caption">
|
217
231
|
<span class="header">Figure 1.1: </span>
|
218
232
|
<span class="description">This is a caption.</span>
|
219
233
|
</div>
|
220
234
|
</div>
|
221
235
|
<div id="fig-bar" data-tralics-id="uid2" data-number="1.2" class="figure">
|
222
|
-
<
|
236
|
+
<span class="graphics">
|
223
237
|
<img src="bar.png" alt="bar" />
|
224
|
-
</
|
238
|
+
</span>
|
225
239
|
<div class="caption">
|
226
240
|
<span class="header">Figure 1.2: </span>
|
227
241
|
<span class="description">This is another caption.</span>
|
@@ -237,9 +251,9 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
237
251
|
<span class="number">Chapter 2 </span>A second chapter</a>
|
238
252
|
</h1>
|
239
253
|
<div id="fig-baz" data-tralics-id="uid3" data-number="2.1" class="figure">
|
240
|
-
<
|
254
|
+
<span class="graphics">
|
241
255
|
<img src="baz.png" alt="baz" />
|
242
|
-
</
|
256
|
+
</span>
|
243
257
|
<div class="caption">
|
244
258
|
<span class="header">Figure 2.1: </span>
|
245
259
|
<span class="description">Yet another.</span>
|
@@ -275,9 +289,9 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
275
289
|
<span class="number">Chapter 1 </span>The chapter</a>
|
276
290
|
</h1>
|
277
291
|
<div class="center figure" id="fig-foo" data-tralics-id="uid1" data-number="1.1">
|
278
|
-
<
|
292
|
+
<span class="graphics">
|
279
293
|
<img src="foo.png" alt="foo" />
|
280
|
-
</
|
294
|
+
</span>
|
281
295
|
<div class="caption">
|
282
296
|
<span class="header">Figure 1.1: </span>
|
283
297
|
<span class="description">This is a caption.</span>
|
@@ -61,9 +61,9 @@ describe Polytexnic::Pipeline do
|
|
61
61
|
end
|
62
62
|
|
63
63
|
context "LaTeX inline" do
|
64
|
-
let(:equation) { "\\( #{math} \\)"}
|
64
|
+
let(:equation) { "\\( #{math} \\)" }
|
65
65
|
let(:polytex) { equation }
|
66
|
-
let(:contents) { "\\( #{result} \\)"}
|
66
|
+
let(:contents) { "\\( #{result} \\)" }
|
67
67
|
|
68
68
|
it { should resemble contents }
|
69
69
|
end
|
@@ -73,6 +73,14 @@ describe Polytexnic::Pipeline do
|
|
73
73
|
let(:contents) { "<p>foo <span class=\"inline_math\">\\( x \\)</span> bar" }
|
74
74
|
it { should include contents }
|
75
75
|
end
|
76
|
+
|
77
|
+
context 'using \ensuremath' do
|
78
|
+
let(:math) { 'x^2 + y' }
|
79
|
+
let(:equation) { "\\ensuremath{#{math}}" }
|
80
|
+
let(:polytex) { equation }
|
81
|
+
let(:contents) { "\\( #{math} \\)" }
|
82
|
+
it { should include contents }
|
83
|
+
end
|
76
84
|
end
|
77
85
|
|
78
86
|
describe "multiple occurrences of inline math on one line" do
|
@@ -8,6 +8,9 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
8
8
|
describe '\chapter' do
|
9
9
|
let(:polytex) do <<-'EOS'
|
10
10
|
\tableofcontents
|
11
|
+
|
12
|
+
\chapter*{A preface}
|
13
|
+
|
11
14
|
\chapter{Foo}
|
12
15
|
\label{cha:foo}
|
13
16
|
|
@@ -33,6 +36,7 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
33
36
|
<h1 class="contents">Contents</h1>
|
34
37
|
<div id="table_of_contents">
|
35
38
|
<ul>
|
39
|
+
<li class="chapter-star"><a href="#a_preface" class="heading hyperref">A preface</a></li>
|
36
40
|
<li class="chapter"><a href="#cha-foo" class="heading hyperref"><span class="number">Chapter 1 </span>Foo</a></li>
|
37
41
|
<li>
|
38
42
|
<ul>
|
@@ -61,28 +65,28 @@ describe 'Polytexnic::Pipeline#to_html' do
|
|
61
65
|
|
62
66
|
it { should_not be_empty }
|
63
67
|
|
64
|
-
it "should have a 'depth' attribute" do
|
68
|
+
it "should have a nil 'depth' attribute" do
|
65
69
|
expect(toc.first['depth']).to be_nil
|
66
70
|
end
|
67
71
|
|
68
72
|
it "should have a link to the first chapter" do
|
69
|
-
expect(toc.css('li>a')[
|
73
|
+
expect(toc.css('li>a')[1]['href']).to eq '#cha-foo'
|
70
74
|
end
|
71
75
|
|
72
76
|
it "should have a link to the first section" do
|
73
|
-
expect(toc.css('li>a')[
|
77
|
+
expect(toc.css('li>a')[2]['href']).to eq '#sec-bar'
|
74
78
|
end
|
75
79
|
|
76
80
|
it "should have a link to the first subsection" do
|
77
|
-
expect(toc.css('li>a')[
|
81
|
+
expect(toc.css('li>a')[3]['href']).to eq '#sec-baz'
|
78
82
|
end
|
79
83
|
|
80
84
|
it "should have a link to the second section" do
|
81
|
-
expect(toc.css('li>a')[
|
85
|
+
expect(toc.css('li>a')[4]['href']).to eq '#sec-quux'
|
82
86
|
end
|
83
87
|
|
84
88
|
it "should have a link to the second chapter" do
|
85
|
-
expect(toc.css('li>a')[
|
89
|
+
expect(toc.css('li>a')[5]['href']).to eq '#cha-lorem'
|
86
90
|
end
|
87
91
|
|
88
92
|
it "should have the right number of lists" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polytexnic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hartl
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -195,6 +195,13 @@ files:
|
|
195
195
|
- .pull_requests/1387316123
|
196
196
|
- .pull_requests/1387337421
|
197
197
|
- .pull_requests/1387418273
|
198
|
+
- .pull_requests/1387507486
|
199
|
+
- .pull_requests/1387590643
|
200
|
+
- .pull_requests/1387944167
|
201
|
+
- .pull_requests/1388090414
|
202
|
+
- .pull_requests/1388112504
|
203
|
+
- .pull_requests/1388430185
|
204
|
+
- .pull_requests/1388440664
|
198
205
|
- .rspec
|
199
206
|
- Gemfile
|
200
207
|
- Guardfile
|