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,176 @@
1
+ require 'securerandom'
2
+
3
+ module Polytexnic
4
+ module Utils
5
+ extend self
6
+
7
+ # Returns the executable for the Tralics LaTeX-to-XML converter.
8
+ def tralics
9
+ File.join(File.dirname(__FILE__), '..', '..',
10
+ 'precompiled_binaries', 'tralics')
11
+ end
12
+
13
+ # Returns a salted hash digest of the string.
14
+ def digest(string, options = {})
15
+ salt = options[:salt] || SecureRandom.base64
16
+ Digest::SHA1.hexdigest("#{salt}--#{string}")
17
+ end
18
+
19
+ # Returns a digest for passing things through the pipeline.
20
+ def pipeline_digest(element)
21
+ value = digest("#{Time.now.to_s}::#{element}")
22
+ @literal_cache[element.to_s] ||= value
23
+ end
24
+
25
+ # Returns a digest for use in labels.
26
+ # I like to use labels of the form cha:foo_bar, but for some reason
27
+ # Tralics removes the underscore in this case.
28
+ def underscore_digest
29
+ pipeline_digest('_')
30
+ end
31
+
32
+ # Escapes backslashes.
33
+ # Interpolated backslashes need extra escaping.
34
+ # We only escape '\\' by itself, i.e., a backslash followed by spaces
35
+ # or the end of line.
36
+ def escape_backslashes(string)
37
+ string.gsub(/\\(\s+|$)/) { '\\\\' + $1.to_s }
38
+ end
39
+
40
+ # Caches URLs for \href commands.
41
+ def cache_hrefs(doc, latex=false)
42
+ doc.tap do |text|
43
+ text.gsub!(/\\href{(.*?)}/) do
44
+ key = digest($1)
45
+ literal_cache[key] = $1
46
+ "\\href{#{key}}"
47
+ end
48
+ end
49
+ end
50
+
51
+ # Returns a Tralics pseudo-LaTeX XML element.
52
+ # The use of the 'skip' flag is a hack to be able to use xmlelement
53
+ # even when generating, e.g., LaTeX, where we simply want to yield the
54
+ # block.
55
+ def xmlelement(name, skip = false)
56
+ output = (skip ? "" : "\\begin{xmlelement}{#{name}}")
57
+ output << yield if block_given?
58
+ output << (skip ? "" : "\\end{xmlelement}")
59
+ end
60
+
61
+ # Returns some commands for Tralics.
62
+ # For various reasons, we don't actually want to include these in
63
+ # the style file that gets passed to LaTeX. For example,
64
+ # the commands with 'xmlelt' aren't even valid LaTeX; they're actually
65
+ # pseudo-LaTeX that has special meaning to the Tralics processor.
66
+ def tralics_commands
67
+ <<-'EOS'
68
+ % Commands specific to Tralics
69
+ \def\hyperref[#1]#2{\xmlelt{a}{\XMLaddatt{target}{#1}#2}}
70
+ \newcommand{\heading}[1]{\xmlelt{heading}{#1}}
71
+ \newcommand{\codecaption}[1]{\xmlelt{heading}{#1}}
72
+ \newcommand{\sout}[1]{\xmlelt{sout}{#1}}
73
+ \newcommand{\kode}[1]{\xmlelt{kode}{#1}}
74
+ \newcommand{\filepath}[1]{\xmlelt{filepath}{#1}}
75
+ \newcommand{\image}[1]{\xmlelt{image}{#1}}
76
+ \newcommand{\imagebox}[1]{\xmlelt{imagebox}{#1}}
77
+
78
+ % Code listings
79
+ \usepackage{amsthm}
80
+ \theoremstyle{definition}
81
+ \newtheorem{codelisting}{Listing}[chapter]
82
+ \newtheorem{aside}{Box}[chapter]
83
+ EOS
84
+ end
85
+
86
+ # Highlights source code.
87
+ def highlight_source_code(document)
88
+ if document.is_a?(String) # LaTeX
89
+ substitutions = {}
90
+ document.tap do
91
+ code_cache.each do |key, (content, language, in_codelisting)|
92
+ code = highlight(key, content, language, 'latex')
93
+ output = code.split("\n")
94
+ horrible_backslash_kludge(add_font_info(output.first))
95
+ code = output.join("\n")
96
+ substitutions[key] = in_codelisting ? code : framed(code)
97
+ end
98
+ document.gsub!(Regexp.union(substitutions.keys), substitutions)
99
+ end
100
+ else # HTML
101
+ document.css('div.code').each do |code_block|
102
+ key = code_block.content
103
+ next unless (value = code_cache[key])
104
+ content, language = value
105
+ code_block.inner_html = highlight(key, content, language, 'html')
106
+ end
107
+ end
108
+ end
109
+
110
+ # Puts a frame around code.
111
+ def framed(code)
112
+ "\\begin{framed_shaded}\n#{code}\n\\end{framed_shaded}"
113
+ end
114
+
115
+ # Highlights a code sample.
116
+ def highlight(key, content, language, formatter)
117
+ highlight_cache[key] ||= Pygments.highlight(content,
118
+ lexer: language,
119
+ formatter: formatter)
120
+ end
121
+
122
+ # Adds some verbatim font info (including size).
123
+ # We prepend rather than replace the styles because the Pygments output
124
+ # includes a required override of the default commandchars.
125
+ # Since the substitution is only important in the context of a PDF book,
126
+ # it only gets made if there's a style in 'softcover.sty' in the
127
+ # current directory
128
+ def add_font_info(string)
129
+ if File.exist?('softcover.sty')
130
+ regex = '{code}{Verbatim}{(.*)}'
131
+ styles = File.read('softcover.sty').scan(/#{regex}/).flatten.first
132
+ string.gsub!("\\begin{Verbatim}[",
133
+ "\\begin{Verbatim}[#{styles},")
134
+ end
135
+ string
136
+ end
137
+
138
+ # Does something horrible with backslashes.
139
+ # OK, so the deal is that code highlighted for LaTeX contains the line
140
+ # \begin{Verbatim}[commandchars=\\\{\}]
141
+ # Oh crap, there are backslashes in there. This means we have no chance
142
+ # of getting things to work after interpolating, gsubbing, and so on,
143
+ # because in Ruby '\\foo' is the same as '\\\\foo', '\}' is '}', etc.
144
+ # I thought I escaped (heh) this problem with the `escape_backslashes`
145
+ # method, but here the problem is extremely specific. In particular,
146
+ # \\\{\} is really \\ and \{ and \}, but Ruby doensn't know WTF to do
147
+ # with it, and thinks that it's "\\{}", which is the same as '\{}'.
148
+ # The solution is to replace '\\\\' with some number of backslashes.
149
+ # How many? I literally had to just keep adding backslashes until
150
+ # the output was correct when running `poly build:pdf`.
151
+ def horrible_backslash_kludge(string)
152
+ string.gsub!(/commandchars=\\\\/, 'commandchars=\\\\\\\\')
153
+ end
154
+
155
+ # Returns true if we are debugging, false otherwise.
156
+ # Manually change to `true` on an as-needed basis.
157
+ def debug?
158
+ false
159
+ end
160
+
161
+ # Returns true if we are profiling the code, false otherwise.
162
+ # Manually change to `true` on an as-needed basis.
163
+ def profiling?
164
+ return false if test?
165
+ false
166
+ end
167
+
168
+ def set_test_mode!
169
+ @@test_mode = true
170
+ end
171
+
172
+ def test?
173
+ defined?(@@test_mode) && @@test_mode
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,3 @@
1
+ module Polytexnic
2
+ VERSION = "0.5.0"
3
+ end
data/lib/polytexnic.rb ADDED
@@ -0,0 +1,92 @@
1
+ # encoding=utf-8
2
+ require "polytexnic/utils"
3
+ require "polytexnic/version"
4
+ require "polytexnic/postprocessor"
5
+ require "polytexnic/preprocessor"
6
+ require 'tempfile'
7
+ require 'nokogiri'
8
+ require 'digest/sha1'
9
+ require 'pygments'
10
+ require 'msgpack'
11
+
12
+ module Polytexnic
13
+
14
+ def self.style_file
15
+ 'polytexnic_commands.sty'
16
+ end
17
+
18
+ # Writes the contents of the custom polytexnic style file.
19
+ # This is used by the `generate` method in the `softcover` gem.
20
+ # We put it here because `custom.sty` lives inside `polytexnic`
21
+ # so that core can support, e.g., '\PolyTeXnic'.
22
+ def self.write_polytexnic_style_file(dir)
23
+ csf = File.join(File.dirname(__FILE__), '..', style_file)
24
+ File.write(File.join(dir, style_file), File.read(csf))
25
+ end
26
+
27
+ class Pipeline
28
+ include Polytexnic::Preprocessor
29
+ include Polytexnic::Postprocessor
30
+ include Polytexnic::Utils
31
+
32
+ attr_accessor :literal_cache, :code_cache, :polytex, :xml, :html,
33
+ :math_label_cache, :highlight_cache, :maketitle_elements,
34
+ :custom_commands
35
+
36
+ def initialize(source, options = {})
37
+ @literal_cache = {}
38
+ @code_cache = {}
39
+ @maketitle_elements = {}
40
+ @highlight_cache_filename = '.highlight_cache'
41
+ if File.exist?(@highlight_cache_filename)
42
+ content = File.read(@highlight_cache_filename)
43
+ @highlight_cache = MessagePack.unpack(content) unless content.empty?
44
+ end
45
+ @highlight_cache ||= {}
46
+ @math_label_cache = {}
47
+ @source_format = options[:source] || :polytex
48
+ @custom_commands = File.read(Polytexnic.style_file) rescue ''
49
+ @custom_commands += "\n" + (options[:custom_commands] || '')
50
+ @source = source
51
+ if markdown?
52
+ preprocess(:polytex)
53
+ postprocess(:polytex)
54
+ end
55
+ @polytex = @source
56
+ end
57
+
58
+ def to_html
59
+ if profiling?
60
+ require 'ruby-prof'
61
+ RubyProf.start
62
+ end
63
+
64
+ preprocess(:html)
65
+ postprocess(:html)
66
+ puts @html if debug?
67
+
68
+ if profiling?
69
+ result = RubyProf.stop
70
+ printer = RubyProf::GraphPrinter.new(result)
71
+ printer.print(STDOUT, {})
72
+ end
73
+ @html.strip
74
+ end
75
+
76
+ def to_latex
77
+ preprocess(:latex)
78
+ postprocess(:latex)
79
+ @latex
80
+ end
81
+
82
+ private
83
+
84
+ def markdown?
85
+ @source_format == :markdown || @source_format == :md
86
+ end
87
+
88
+ def polytex?
89
+ @source_format == :polytex
90
+ end
91
+ end
92
+ end
data/notes/pandoc.md ADDED
@@ -0,0 +1,41 @@
1
+
2
+ ## Math
3
+
4
+ ### Inline math
5
+
6
+ pandoc -s spec/fixtures/inline_math.tex --mathjax -o tmp/inline_math.html
7
+
8
+ ### Math environments
9
+
10
+ pandoc -s spec/fixtures/math_environments --mathjax -o tmp/math_environments.html
11
+
12
+ Pandoc handles equation environments wrong; it converts
13
+
14
+ \begin{equation}
15
+ \varphi^2 = \varphi + 1.
16
+ \end{equation}
17
+
18
+ into the non-equivalent
19
+
20
+ \[
21
+ \varphi^2 = \varphi + 1.
22
+ \]
23
+
24
+
25
+ ## Verbatim environments
26
+
27
+ Pandoc does well with inline verbatim text like `\verb+$x$+`, but it doesn't handle nested verbatim environments properly. In particular, it chokes on
28
+
29
+ \begin{verbatim}
30
+ \begin{verbatim}
31
+ This is verbatim text.
32
+ \end{verbatim}
33
+ \end{verbatim}
34
+
35
+ ## Tables
36
+
37
+ Pandoc doesn't handle tables at all.
38
+
39
+ ## Sections with cross-references
40
+
41
+ Pandoc doesn't handle cross-references.
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'polytexnic/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "polytexnic"
8
+ gem.version = Polytexnic::VERSION
9
+ gem.authors = ["Michael Hartl", "Nick Merwin"]
10
+ gem.email = ["michael@softcover.io"]
11
+ gem.description = %q{Core translation engine for the polytexnic gem}
12
+ gem.summary = %q{Convert from PolyTeX & Markdown to HTML & LaTeX}
13
+ gem.homepage = "https://polytexnic.org/"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency 'nokogiri', '~> 1.5.0'
22
+ gem.add_dependency 'pygments.rb', '~> 0.4.2'
23
+ gem.add_dependency 'msgpack', '~> 0.4.2'
24
+ gem.add_dependency 'kramdown'
25
+
26
+ gem.add_development_dependency 'rspec'
27
+ gem.add_development_dependency 'simplecov'
28
+ end
@@ -0,0 +1,5 @@
1
+ % Don't edit this file; it is overwritten every time the PDF gets built.
2
+
3
+ % Add some custom commands needed by PolyTeXnic.
4
+ \newcommand{\PolyTeX}{Poly\-\TeX}
5
+ \newcommand{\PolyTeXnic}{Poly\-{\TeX}\-nic}
Binary file
@@ -0,0 +1,14 @@
1
+ We can include code listings, as seen in Listing~\ref{code:foo}.
2
+
3
+ \begin{codelisting}
4
+ \label{code:foo}
5
+ Defining a foo function.
6
+ %= ruby
7
+ \begin{code}
8
+ def foo
9
+ "bar"
10
+ end
11
+ \end{code}
12
+ \end{codelisting}
13
+
14
+ Including the type of source code (in this case, Ruby) should result in syntax highlighting. (The type is put in a comment so that the markup is still valid \LaTeX.)
@@ -0,0 +1,8 @@
1
+ We include here a figure (Figure~\ref{fig:editor_shell}).
2
+
3
+ \begin{figure}
4
+ \begin{center}
5
+ \includegraphics{images/figures/editor_shell.png}
6
+ \end{center}
7
+ \caption{The caption includes a label for use in cross-references.\label{fig:editor_shell}}
8
+ \end{figure}
@@ -0,0 +1,4 @@
1
+
2
+ <p>This is some inline math: <span class="inline_math">\( \int_\Omega d\omega = \int_{\partial\Omega} \omega \)</span> (the general form of Stokes’s Theorem).<span class="intersentencespace"></span> Here’s some more: <span class="inline_math">\( \varphi^2 = \varphi + 1 \)</span>.</p>
3
+ <p>Our main strategy for producing HTML is to pass it through as-is and let MathJax handle the rendering.
4
+ </p>
@@ -0,0 +1,3 @@
1
+ This is some inline math: $\int_\Omega d\omega = \int_{\partial\Omega} \omega$ (the general form of Stokes's Theorem). Here's some more: \( \varphi^2 = \varphi + 1 \).
2
+
3
+ Our main strategy for producing HTML is to pass it through as-is and let MathJax handle the rendering.
@@ -0,0 +1,50 @@
1
+ <p>This is an equation environment:</p>
2
+ <div class="equation">\[
3
+ \int_\Omega d\omega = \int_{\partial\Omega} \omega \qquad\mbox{Stokes's Theorem}
4
+ \]
5
+ </div><p class="noindent">This should be a centered equation with no numbering.</p>
6
+ <p>We also want to support equation environments:</p>
7
+ <div id="uid1" data-tralics-id="uid1" data-number="1" class="equation">\begin{equation}
8
+ \int_\Omega d\omega = \int_{\partial\Omega} \omega \qquad\mbox{Stokes's Theorem}
9
+ \end{equation}
10
+ </div><p class="noindent">We’ll probably have to handle numbering and cross-references in a post-processing step.</p>
11
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
12
+ tempor incididunt ut labore et dolore magna aliqua.<span class="intersentencespace"></span> Ut enim ad minim veniam,
13
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
14
+ consequat.<span class="intersentencespace"></span> Duis aute irure dolor in reprehenderit in voluptate velit esse
15
+ cillum dolore eu fugiat nulla pariatur.<span class="intersentencespace"></span> Excepteur sint occaecat cupidatat non
16
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
17
+ <p>Of course, inline math like <span class="inline_math">\( \Omega &gt; 0 \)</span> and <span class="inline_math">\( x^2 - 2 \equiv 0 \)</span> should also work fine.</p>
18
+ <div id="uid2" data-tralics-id="uid2" data-number="2" class="equation">\begin{align}
19
+ x^2 + y^2 &amp;= 1
20
+ \\ y &amp;= \sqrt{1 - x^2}.
21
+ \end{align}
22
+ </div><p class="noindent">Maxwell’s Equations:</p>
23
+ <div id="uid3" data-tralics-id="uid3" data-number="3" class="equation">\begin{equation}
24
+ \begin{aligned}
25
+ \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
26
+ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
27
+ \nabla \cdot \vec{\mathbf{B}} &amp; = 0
28
+ \end{aligned}
29
+ \end{equation}
30
+ </div><div id="uid4" data-tralics-id="uid4" data-number="4" class="equation">\begin{equation*}
31
+ \left.\begin{aligned}
32
+ dE &amp;= \rho \\
33
+ d*E &amp;= -\dot{B} \\
34
+ dB &amp;= 0 \\
35
+ d*B &amp;= J + \dot{E}
36
+ \end{aligned}
37
+ \right\}
38
+ \qquad \text{Maxwell's equations}
39
+ \end{equation*}
40
+ </div><p class="noindent">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
41
+ tempor incididunt ut labore et dolore magna aliqua.<span class="intersentencespace"></span> Ut enim ad minim veniam,
42
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
43
+ consequat.<span class="intersentencespace"></span> Duis aute irure dolor in reprehenderit in voluptate velit esse
44
+ cillum dolore eu fugiat nulla pariatur.<span class="intersentencespace"></span> Excepteur sint occaecat cupidatat non
45
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<span class="intersentencespace"></span></p>
46
+ <div id="uid5" data-tralics-id="uid5" data-number="5" class="equation">\begin{multline}
47
+ a+b+c+d+e+f\\
48
+ +i+j+k+l+m+n
49
+ \end{multline}
50
+ </div>
@@ -0,0 +1,56 @@
1
+ This is an equation environment:
2
+ \[
3
+ \int_\Omega d\omega = \int_{\partial\Omega} \omega \qquad\mbox{Stokes's Theorem}
4
+ \]
5
+ This should be a centered equation with no numbering.
6
+
7
+ We also want to support equation environments:
8
+ \begin{equation}
9
+ \int_\Omega d\omega = \int_{\partial\Omega} \omega \qquad\mbox{Stokes's Theorem}
10
+ \end{equation}
11
+ We'll probably have to handle numbering and cross-references in a post-processing step.
12
+
13
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
14
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
15
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
16
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
17
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
18
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
19
+
20
+ Of course, inline math like $\Omega > 0$ and \( x^2 - 2 \equiv 0 \) should also work fine.
21
+
22
+ \begin{align}
23
+ x^2 + y^2 &= 1
24
+ \\ y &= \sqrt{1 - x^2}.
25
+ \end{align}
26
+
27
+ Maxwell's Equations:
28
+ \begin{equation}
29
+ \begin{aligned}
30
+ \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
31
+ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
32
+ \nabla \cdot \vec{\mathbf{B}} & = 0
33
+ \end{aligned}
34
+ \end{equation}
35
+
36
+ \begin{equation*}
37
+ \left.\begin{aligned}
38
+ dE &= \rho \\
39
+ d*E &= -\dot{B} \\
40
+ dB &= 0 \\
41
+ d*B &= J + \dot{E}
42
+ \end{aligned}
43
+ \right\}
44
+ \qquad \text{Maxwell's equations}
45
+ \end{equation*}
46
+
47
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
48
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
49
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
50
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
51
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
52
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
53
+ \begin{multline}
54
+ a+b+c+d+e+f\\
55
+ +i+j+k+l+m+n
56
+ \end{multline}
@@ -0,0 +1,9 @@
1
+ \section{Foo bar}
2
+ \label{sec:foobar}
3
+
4
+ This is a section. The next section is Section~\ref{sec:bazquux}
5
+
6
+ \section{Baz quux}
7
+ \label{sec:bazquux}
8
+
9
+ This is another section. It comes immediately after Section~\ref{sec:foobar}.
@@ -0,0 +1,10 @@
1
+ We also support numbered, cross-referenced boxes, as defined by a custom ``sidebar'' environment (since ``box'' is already a built-in \LaTeX command). An example is shown in Box~\ref{sidebar:example_box}.
2
+
3
+ \begin{sidebar}{Example box}{sidebar:example_box}
4
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
5
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
6
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
7
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
8
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
9
+ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
10
+ \end{sidebar}
@@ -0,0 +1,8 @@
1
+ This is a table:
2
+
3
+ \begin{tabular}{ l c r }
4
+ 1 & 2 & 3 \\
5
+ 4 & 5 & 6 \\
6
+ 7 & 8 & 9 \\
7
+ \end{tabular}
8
+
@@ -0,0 +1,11 @@
1
+
2
+ <p>This is inline verbatim text: <span class="inline_verbatim">\LaTeX and a literal $</span>.<span class="intersentencespace"></span> This is non-inline verbatim text:
3
+ </p><pre class="verbatim"> % \begin{verbatim}
4
+ % This is verbatim text.
5
+ % \end{verbatim}</pre>
6
+ <p>It would also be nice to support the environment from the Verbatim package:
7
+ </p><pre class="verbatim"> % \begin{Verbatim}
8
+ % This is an even more powerful verbatim environment.
9
+ % \end{Verbatim}</pre>
10
+ <p>We’ll see how it goes.
11
+ </p>
@@ -0,0 +1,13 @@
1
+ This is inline verbatim text: \verb+\LaTeX and a literal $+. This is non-inline verbatim text:
2
+ \begin{verbatim}
3
+ % \begin{verbatim}
4
+ % This is verbatim text.
5
+ % \end{verbatim}
6
+ \end{verbatim}
7
+ It would also be nice to support the environment from the Verbatim package:
8
+ \begin{Verbatim}
9
+ % \begin{Verbatim}
10
+ % This is an even more powerful verbatim environment.
11
+ % \end{Verbatim}
12
+ \end{Verbatim}
13
+ We'll see how it goes.
@@ -0,0 +1,34 @@
1
+ # encoding=utf-8
2
+ require 'spec_helper'
3
+
4
+ # Returns a list of fixture filenames.
5
+ def filenames
6
+ %w[inline_math verbatim_environments math_environments]
7
+ end
8
+
9
+ # Returns the results of converting the TeX filename to HTML.
10
+ def converted(filename)
11
+ Polytexnic::Pipeline.new(contents(filename, 'tex')).to_html
12
+ end
13
+
14
+ # Returns the contents of the HTML filename fixture.
15
+ def html(filename)
16
+ contents(filename, 'html')
17
+ end
18
+
19
+ # Returns the contents of a filename using its extension.
20
+ def contents(filename, extension)
21
+ File.open(File.join('spec', 'fixtures', "#{filename}.#{extension}")).read
22
+ end
23
+
24
+ describe Polytexnic::Pipeline do
25
+
26
+ filenames.each do |filename|
27
+ it "should correctly process #{filename}" do
28
+ tmp = 'tmp'
29
+ File.mkdir(tmp) unless File.directory?(tmp)
30
+ File.write(File.join(tmp, filename), converted(filename))
31
+ expect(converted(filename)).to resemble html(filename)
32
+ end
33
+ end
34
+ end