polytexnic 0.5.0

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.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.pull_requests/1371777257 +0 -0
  4. data/.pull_requests/1371927975 +0 -0
  5. data/.pull_requests/1372804345 +0 -0
  6. data/.pull_requests/1374784075 +0 -0
  7. data/.pull_requests/1375304853 +0 -0
  8. data/.pull_requests/1375408308 +0 -0
  9. data/.pull_requests/1375409462 +0 -0
  10. data/.pull_requests/1375410668 +0 -0
  11. data/.pull_requests/1375472132 +0 -0
  12. data/.pull_requests/1375485496 +0 -0
  13. data/.pull_requests/1375487548 +0 -0
  14. data/.pull_requests/1375492835 +0 -0
  15. data/.pull_requests/1375497765 +0 -0
  16. data/.pull_requests/1375559547 +0 -0
  17. data/.pull_requests/1375589063 +0 -0
  18. data/.pull_requests/1375841786 +0 -0
  19. data/.pull_requests/1376352634 +0 -0
  20. data/.pull_requests/1376353299 +0 -0
  21. data/.pull_requests/1376449284 +0 -0
  22. data/.pull_requests/1376452696 +0 -0
  23. data/.pull_requests/1376454166 +0 -0
  24. data/.pull_requests/1376532291 +0 -0
  25. data/.pull_requests/1376625487 +0 -0
  26. data/.pull_requests/1376690108 +0 -0
  27. data/.pull_requests/1376699046 +0 -0
  28. data/.pull_requests/1376707642 +0 -0
  29. data/.pull_requests/1377230284 +0 -0
  30. data/.pull_requests/1379118478 +0 -0
  31. data/.pull_requests/1379123150 +0 -0
  32. data/.pull_requests/1380221847 +0 -0
  33. data/.pull_requests/1380589654 +0 -0
  34. data/.pull_requests/1380673142 +0 -0
  35. data/.pull_requests/1380850800 +0 -0
  36. data/.pull_requests/1381001264 +0 -0
  37. data/.pull_requests/1381005204 +0 -0
  38. data/.pull_requests/1381103022 +0 -0
  39. data/.pull_requests/1381252832 +0 -0
  40. data/.pull_requests/1381276624 +0 -0
  41. data/.pull_requests/1381344234 +0 -0
  42. data/.pull_requests/1381385297 +0 -0
  43. data/.pull_requests/1381427498 +0 -0
  44. data/.pull_requests/1381429761 +0 -0
  45. data/.pull_requests/1381873684 +0 -0
  46. data/.pull_requests/1382045490 +0 -0
  47. data/.pull_requests/1382056384 +0 -0
  48. data/.pull_requests/1382405223 +0 -0
  49. data/.pull_requests/1382478400 +0 -0
  50. data/.pull_requests/1382479780 +0 -0
  51. data/.pull_requests/1382485483 +0 -0
  52. data/.pull_requests/1382569911 +0 -0
  53. data/.pull_requests/1382646199 +0 -0
  54. data/.pull_requests/1382649778 +0 -0
  55. data/.pull_requests/1382660987 +0 -0
  56. data/.pull_requests/1382743927 +0 -0
  57. data/.pull_requests/1382840347 +0 -0
  58. data/.pull_requests/1383077676 +0 -0
  59. data/.pull_requests/1383086948 +0 -0
  60. data/.pull_requests/1383161978 +0 -0
  61. data/.pull_requests/1383263695 +0 -0
  62. data/.pull_requests/1383274008 +0 -0
  63. data/.pull_requests/1383327328 +0 -0
  64. data/.rspec +2 -0
  65. data/.ruby-gemset +1 -0
  66. data/.ruby-version +1 -0
  67. data/Gemfile +15 -0
  68. data/Guardfile +15 -0
  69. data/LICENSE.txt +22 -0
  70. data/README.md +21 -0
  71. data/Rakefile +2 -0
  72. data/lib/polytexnic/literal.rb +299 -0
  73. data/lib/polytexnic/postprocessor.rb +28 -0
  74. data/lib/polytexnic/postprocessors/html.rb +1139 -0
  75. data/lib/polytexnic/postprocessors/latex.rb +18 -0
  76. data/lib/polytexnic/postprocessors/polytex.rb +44 -0
  77. data/lib/polytexnic/preprocessor.rb +23 -0
  78. data/lib/polytexnic/preprocessors/html.rb +349 -0
  79. data/lib/polytexnic/preprocessors/latex.rb +43 -0
  80. data/lib/polytexnic/preprocessors/polytex.rb +127 -0
  81. data/lib/polytexnic/utils.rb +176 -0
  82. data/lib/polytexnic/version.rb +3 -0
  83. data/lib/polytexnic.rb +92 -0
  84. data/notes/pandoc.md +41 -0
  85. data/polytexnic.gemspec +28 -0
  86. data/polytexnic_commands.sty +5 -0
  87. data/precompiled_binaries/tralics +0 -0
  88. data/spec/fixtures/code_listing.tex +14 -0
  89. data/spec/fixtures/figures.tex +8 -0
  90. data/spec/fixtures/inline_math.html +4 -0
  91. data/spec/fixtures/inline_math.tex +3 -0
  92. data/spec/fixtures/math_environments.html +50 -0
  93. data/spec/fixtures/math_environments.tex +56 -0
  94. data/spec/fixtures/section_xrefs.tex +9 -0
  95. data/spec/fixtures/sidebar.tex +10 -0
  96. data/spec/fixtures/tables.tex +8 -0
  97. data/spec/fixtures/verbatim_environments.html +11 -0
  98. data/spec/fixtures/verbatim_environments.tex +13 -0
  99. data/spec/integration_spec.rb +34 -0
  100. data/spec/markdown_to_polytex_spec.rb +192 -0
  101. data/spec/resemble_matcher_spec.rb +69 -0
  102. data/spec/spec_helper.rb +38 -0
  103. data/spec/support/resemble_matcher.rb +100 -0
  104. data/spec/to_html/asides_spec.rb +42 -0
  105. data/spec/to_html/chapters_and_sections_spec.rb +268 -0
  106. data/spec/to_html/characters_and_punctuation_spec.rb +138 -0
  107. data/spec/to_html/codelistings_spec.rb +70 -0
  108. data/spec/to_html/core_spec.rb +227 -0
  109. data/spec/to_html/eqref_spec.rb +32 -0
  110. data/spec/to_html/footnote_spec.rb +164 -0
  111. data/spec/to_html/graphics_and_figures_spec.rb +358 -0
  112. data/spec/to_html/lists_spec.rb +103 -0
  113. data/spec/to_html/literal_environments/code_spec.rb +141 -0
  114. data/spec/to_html/literal_environments/math_spec.rb +255 -0
  115. data/spec/to_html/literal_environments/unicode_spec.rb +12 -0
  116. data/spec/to_html/literal_environments/verbatim_spec.rb +168 -0
  117. data/spec/to_html/quotations_and_verse_spec.rb +86 -0
  118. data/spec/to_html/table_of_contents_spec.rb +93 -0
  119. data/spec/to_html/table_spec.rb +269 -0
  120. data/spec/to_html/text_formatting_spec.rb +50 -0
  121. data/spec/to_latex_spec.rb +197 -0
  122. data/tasks/bin/ruby_tests +41 -0
  123. data/tasks/run_tests_with_both_rubies.rake +5 -0
  124. data/tmp/.gitkeep +0 -0
  125. metadata +286 -0
@@ -0,0 +1,192 @@
1
+ # encoding=utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Polytexnic::Pipeline do
5
+
6
+ before(:all) do
7
+ FileUtils.rm('.highlight_cache') if File.exist?('.highlight_cache')
8
+ end
9
+
10
+ describe '#to_polytex' do
11
+ subject(:processed_text) do
12
+ Polytexnic::Pipeline.new(source, source: :markdown).polytex
13
+ end
14
+
15
+ context "for vanilla Markdown" do
16
+ let(:source) { '*foo* **bar**' }
17
+ it { should include '\emph{foo} \textbf{bar}' }
18
+ it { should_not include '\begin{document}' }
19
+ end
20
+
21
+ context "for multiline Markdown" do
22
+ let(:source) do <<-EOS
23
+ # A chapter
24
+
25
+ Hello, *world*!
26
+
27
+ ## A section
28
+
29
+ Lorem ipsum
30
+ EOS
31
+ end
32
+ it { should include '\chapter{A chapter}' }
33
+ it { should include '\section{A section}' }
34
+ it { should_not include '\hypertarget' }
35
+ end
36
+
37
+ describe "with math" do
38
+ subject do
39
+ Polytexnic::Pipeline.new(markdown, source: :markdown).polytex
40
+ end
41
+
42
+ context "inline math" do
43
+ let(:markdown) do <<-'EOS'
44
+ This is inline math: {$$} x^2 {/$$}.
45
+ EOS
46
+ end
47
+
48
+ it { should include '\( x^2 \)' }
49
+ end
50
+
51
+ context "block math" do
52
+ let(:markdown) do <<-'EOS'
53
+ This is block math:
54
+ {$$}
55
+ x^2
56
+ {/$$}.
57
+ EOS
58
+ end
59
+
60
+ it { should resemble '\[ x^2 \]' }
61
+ end
62
+ end
63
+
64
+ describe "footnotes" do
65
+ subject do
66
+ Polytexnic::Pipeline.new(markdown, source: :markdown).polytex
67
+ end
68
+
69
+ context "first chapter with footnotes" do
70
+ let(:markdown) do <<-'EOS'
71
+ To add a footnote, you insert a footnote tag like this.[^foo]
72
+
73
+ Then you add the footnote content later in the text, using the same tag,
74
+ with a colon and a space:[^foo2]
75
+
76
+ [^foo]: This is the footnote content.
77
+
78
+ That is it. You can keep writing your text after the footnote content.
79
+
80
+ [^foo2]: This is the footnote text. We are now going to add a second line
81
+ after typing in four spaces.
82
+ EOS
83
+ end
84
+
85
+ it { should include '\footnote{This is the footnote content.}' }
86
+ it { should include 'after typing in four spaces.}' }
87
+ end
88
+ end
89
+
90
+ describe "source code" do
91
+ context "without highlighting" do
92
+ let(:source) do <<-EOS
93
+ def foo
94
+ "bar"
95
+ end
96
+ EOS
97
+ end
98
+ let(:output) do <<-'EOS'
99
+ \begin{verbatim}
100
+ def foo
101
+ "bar"
102
+ end
103
+ \end{verbatim}
104
+ EOS
105
+ end
106
+ it { should eq output }
107
+ end
108
+
109
+ context "with highlighting" do
110
+ let(:source) do <<-EOS
111
+ {lang="ruby"}
112
+ def foo
113
+ "bar"
114
+ end
115
+ lorem
116
+ EOS
117
+ end
118
+ let(:output) do <<-'EOS'
119
+ %= lang:ruby
120
+ \begin{code}
121
+ def foo
122
+ "bar"
123
+ end
124
+ \end{code}
125
+ lorem
126
+ EOS
127
+ end
128
+ it { should resemble output }
129
+ end
130
+
131
+ describe "code inclusion" do
132
+ let(:source) { '<<(/path/to/code)' }
133
+ it { should resemble '%= <<(/path/to/code)' }
134
+
135
+ context "with an alternate lang" do
136
+ let(:source) { '<<(/path/to/code.md, lang: text)' }
137
+ it { should resemble '%= <<(/path/to/code.md, lang: text)' }
138
+ end
139
+ end
140
+
141
+ describe "GitHub-flavored code fencing" do
142
+
143
+ context "without highlighting" do
144
+ let(:source) do <<-EOS
145
+ ```
146
+ def foo
147
+ "bar"
148
+ end
149
+ ```
150
+ lorem
151
+ EOS
152
+ end
153
+
154
+ let(:output) do <<-'EOS'
155
+ \begin{verbatim}
156
+ def foo
157
+ "bar"
158
+ end
159
+ \end{verbatim}
160
+ lorem
161
+ EOS
162
+ end
163
+ it { should resemble output }
164
+ end
165
+
166
+ context "with highlighting" do
167
+ let(:source) do <<-EOS
168
+ ```ruby
169
+ def foo
170
+ "bar"
171
+ end
172
+ ```
173
+ lorem
174
+ EOS
175
+ end
176
+
177
+ let(:output) do <<-'EOS'
178
+ %= lang:ruby
179
+ \begin{code}
180
+ def foo
181
+ "bar"
182
+ end
183
+ \end{code}
184
+ lorem
185
+ EOS
186
+ end
187
+ it { should resemble output }
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,69 @@
1
+ # encoding=utf-8
2
+ require 'spec_helper'
3
+
4
+ describe String do
5
+ let(:string) { "foo\t bar\n\nbaz quux\nderp" }
6
+ let(:compressed_string) { "foo bar baz quux derp" }
7
+ subject { string }
8
+
9
+ it { should respond_to(:compress) }
10
+
11
+ describe '#compress' do
12
+ subject { string.compress }
13
+ it { should eq compressed_string }
14
+ end
15
+ end
16
+
17
+ describe "custom 'resemble' matcher" do
18
+
19
+ it "should pass if two strings agree up to whitespace" do
20
+ expect("foo bar").to resemble " foo \t\tbar "
21
+ end
22
+
23
+ it "should work for regexes" do
24
+ expect("foo 628_tau bar").to resemble /foo \d+\w* bar/
25
+ end
26
+
27
+ it "should work if the actual string contains the right substring" do
28
+ expect("baz quux foo bar derp").to resemble " foo \t\tbar "
29
+ end
30
+
31
+ it "should work with backslashes" do
32
+ expect('\emph{foo bar}').to resemble '\emph{foo bar}'
33
+ end
34
+
35
+ let(:nbsp) { ' ' }
36
+
37
+ it "should work with Unicode nonbreak spaces" do
38
+ expect('foo' + nbsp + nbsp + 'bar').to resemble 'foo bar'
39
+ end
40
+
41
+ it "should work with a mix of characters and codes" do
42
+ expect('“foo bar&#8221;').to resemble '&#8220;foo bar”'
43
+ end
44
+
45
+ it "should work with multiline strings" do
46
+ foo = <<-'EOS'
47
+ <ul>
48
+ <li>alpha</li>
49
+ <li>bravo</li>
50
+ <li>charlie</li>
51
+ </ul>
52
+ EOS
53
+ bar = <<-'EOS'
54
+ <ul>
55
+ <li>alpha</li>
56
+ <li>bravo</li>
57
+ <li>charlie</li>
58
+ </ul>
59
+ EOS
60
+
61
+ expect(foo).to resemble bar
62
+ end
63
+
64
+ it "should handle HTML fragments identical up to whitespace" do
65
+ foo = "<em> foobar\n</em>"
66
+ bar = "<em>foobar</em>"
67
+ expect(foo).to resemble bar
68
+ end
69
+ end
@@ -0,0 +1,38 @@
1
+ require 'simplecov'
2
+ require 'json'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start
10
+
11
+ require 'polytexnic'
12
+
13
+ # Load support files.
14
+ Dir.glob(File.join(File.dirname(__FILE__), "./support/**/*.rb")).each do |f|
15
+ require_relative(f)
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ config.treat_symbols_as_metadata_keys_with_true_values = true
20
+ config.run_all_when_everything_filtered = true
21
+ config.filter_run :focus
22
+
23
+ Polytexnic::Utils.set_test_mode!
24
+ config.before do
25
+ Polytexnic::Utils.set_test_mode!
26
+ end
27
+
28
+ # Disallow the old-style 'object.should' syntax.
29
+ config.expect_with :rspec do |c|
30
+ c.syntax = :expect
31
+ end
32
+
33
+ # Run specs in random order to surface order dependencies. If you find an
34
+ # order dependency and want to debug it, you can fix the order by providing
35
+ # the seed, which is printed after each run.
36
+ # --seed 1234
37
+ config.order = 'random'
38
+ end
@@ -0,0 +1,100 @@
1
+ # encoding=utf-8
2
+ require 'polytexnic'
3
+
4
+ RSpec::Matchers.define :resemble do |expected|
5
+ match do |actual|
6
+ if expected.is_a?(String)
7
+ regex = %r{#{Regexp.escape(expected.robust)}}
8
+ elsif expected.is_a?(Regexp)
9
+ regex = %r{#{expected.to_s.robust}}
10
+ end
11
+
12
+ failure_message_for_should do |actual|
13
+ debug_output(expected, actual)
14
+ "expected #{actual} to resemble #{expected}"
15
+ end
16
+
17
+ failure_message_for_should_not do |actual|
18
+ debug_output(expected, actual)
19
+ "expected #{actual} not to resemble #{expected}"
20
+ end
21
+
22
+ expect(actual.robust).to match_regex(regex)
23
+ end
24
+ end
25
+
26
+ def debug_output(expected, actual)
27
+ print_output expected, actual if Polytexnic::Utils.debug?
28
+ end
29
+
30
+ # Prints the robust versions of the two strings
31
+ # The output is hugely useful in visually diffing, e.g., HTML output.
32
+ def print_output(expected, actual)
33
+ puts "expect: " + expected.robust
34
+ puts "actual: " + actual.robust
35
+ end
36
+
37
+ class String
38
+
39
+ # Prepares a string for robust comparison.
40
+ def robust
41
+ apply_character_equivalences.compress.remove_tag_whitespace
42
+ end
43
+
44
+ # Applies UTF-8 character code equivalences.
45
+ # For example, '&#133;' and '…' are the same character (horizontal ellipsis),
46
+ # and depending on the version of Ruby and other factors the string might
47
+ # contain either or both.
48
+ # We want to be robust to the differences, to gsub them out.
49
+ # For clarity, we standardize on the characters that look literally correct,
50
+ # e.g., '…'.
51
+ # Rather than be exhaustive, we of course only check the ones actually
52
+ # used in the tests. Browsers, etc., display them the same.
53
+ def apply_character_equivalences
54
+ equivalences = [ ['&#8216;', '‘'],
55
+ ['&#8217;', '’'],
56
+ ['&#8220;', '“'],
57
+ ['&#8221;', '”'],
58
+ ['&#160;', ' '], # nonbreaking space
59
+ ['&thinsp;',' '], # thin space
60
+ ['&#133;', '…'],
61
+ ['&#8230;', '…'],
62
+ ['&#8617', '↩']
63
+ ]
64
+ tap do
65
+ equivalences.each do |code, character|
66
+ gsub!(code, character)
67
+ end
68
+ end
69
+ end
70
+
71
+ def remove_tag_whitespace
72
+ gsub(/\s*</, '<').gsub(/>\s*/, '>')
73
+ end
74
+
75
+ # Compress whitespace
76
+ # Eliminates repeating whitespace (spaces, tabs, or Unicode nbsp),
77
+ # converting everthing to ordinary spaces, while stripping leading
78
+ # and trailing whitespace.
79
+ # >> "foo\t bar\n\nbaz quux\nderp".compress
80
+ # => "foo bar baz quux derp"
81
+ #
82
+ # Spaces surround each line are stripped entirely, so that
83
+ # <ul>
84
+ # <li>alpha</li>
85
+ # <li>bravo</li>
86
+ # <li>charlie</li>
87
+ # </ul>
88
+ # becomes
89
+ # <ul>
90
+ # <li>alpha</li>
91
+ # <li>bravo</li>
92
+ # <li>charlie</li>
93
+ # </ul>
94
+ def compress
95
+ unicode_nbsp = ' '
96
+ result = gsub(unicode_nbsp, ' ')
97
+ stripped_result = result.split("\n").map(&:strip).join("\n")
98
+ stripped_result.gsub("\n", ' ').gsub(/[ \t]{2,}/, ' ')
99
+ end
100
+ end
@@ -0,0 +1,42 @@
1
+ # encoding=utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'Polytexnic::Pipeline#to_html' do
5
+
6
+ subject(:processed_text) { Polytexnic::Pipeline.new(polytex).to_html }
7
+
8
+ describe "code listings" do
9
+ let(:polytex) do <<-'EOS'
10
+ \chapter{Foo bar}
11
+
12
+ \begin{aside}
13
+ \heading{Lorem ipsum.}
14
+ \label{aside:lorem}
15
+
16
+ lorem ipsum
17
+
18
+ dolor sit amet
19
+
20
+ \end{aside}
21
+
22
+ Box~\ref{aside:lorem}
23
+ EOS
24
+ end
25
+
26
+ it do
27
+ should resemble <<-'EOS'
28
+ <div id="cid1" data-tralics-id="cid1" class="chapter" data-number="1"><h1><a href="#cid1" class="heading"><span class="number">Chapter 1 </span>Foo bar</a></h1>
29
+ <div class="aside" id="aside-lorem" data-tralics-id="uid1" data-number="1.1">
30
+ <div class="heading">
31
+ <span class="number">Box 1.1.</span>
32
+ <span class="description">Lorem ipsum.</span>
33
+ </div>
34
+ <p>lorem ipsum</p>
35
+ <p>dolor sit amet</p>
36
+ </div>
37
+ <p><a href="#aside-lorem" class="hyperref">Box <span class="ref">1.1</span></a></p>
38
+ </div>
39
+ EOS
40
+ end
41
+ end
42
+ end