asciidoctor-latex 1.5.0.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.adoc +22 -0
  3. data/README.adoc +213 -0
  4. data/Rakefile +55 -0
  5. data/bin/asciidoctor-latex +22 -0
  6. data/data/asciidoc_tex_macros.tex +42 -0
  7. data/data/preamble_article.tex +45 -0
  8. data/data/preamble_book.tex +44 -0
  9. data/lib/asciidoctor-latex.rb +1 -0
  10. data/lib/asciidoctor/latex.rb +8 -0
  11. data/lib/asciidoctor/latex/chem.rb +24 -0
  12. data/lib/asciidoctor/latex/click_block.rb +121 -0
  13. data/lib/asciidoctor/latex/converter.rb +358 -0
  14. data/lib/asciidoctor/latex/core_ext/colored_string.rb +35 -0
  15. data/lib/asciidoctor/latex/dollar.rb +28 -0
  16. data/lib/asciidoctor/latex/ent_to_uni.rb +17 -0
  17. data/lib/asciidoctor/latex/environment_block.rb +190 -0
  18. data/lib/asciidoctor/latex/inject_html.rb +49 -0
  19. data/lib/asciidoctor/latex/inline_macros.rb +20 -0
  20. data/lib/asciidoctor/latex/macro_insert.rb +49 -0
  21. data/lib/asciidoctor/latex/node_processors.rb +695 -0
  22. data/lib/asciidoctor/latex/prepend_processor.rb +36 -0
  23. data/lib/asciidoctor/latex/preprocess.rb +37 -0
  24. data/lib/asciidoctor/latex/tex_block.rb +108 -0
  25. data/lib/asciidoctor/latex/tex_postprocessor.rb +44 -0
  26. data/lib/asciidoctor/latex/tex_preprocessor.rb +65 -0
  27. data/lib/asciidoctor/latex/version.rb +5 -0
  28. data/manual.adoc +285 -0
  29. data/rake/cacert.pem +3894 -0
  30. data/rake/jdk_helper.rb +105 -0
  31. data/rake/tar-licence +19 -0
  32. data/rake/tar.rb +38 -0
  33. data/rspec/README.adoc +45 -0
  34. data/rspec/a.rb +79 -0
  35. data/rspec/b.rb +111 -0
  36. data/rspec/c.rb +121 -0
  37. data/rspec/data/tex1 +65 -0
  38. data/rspec/data/tex2 +5 -0
  39. data/rspec/data/tex2.expect +5 -0
  40. data/rspec/transform.rb +36 -0
  41. data/spec/README.adoc +45 -0
  42. data/spec/a.rb +79 -0
  43. data/spec/b.rb +111 -0
  44. data/spec/c.rb +121 -0
  45. data/spec/data/foo +1 -0
  46. data/spec/data/lorem +1 -0
  47. data/spec/data/tex1 +65 -0
  48. data/spec/data/tex2 +5 -0
  49. data/spec/data/tex2.expect +5 -0
  50. data/spec/transform.rb +36 -0
  51. data/test/examples/adoc/env.adoc +16 -0
  52. data/test/examples/adoc/eq.adoc +12 -0
  53. data/test/examples/adoc/zero.adoc +3 -0
  54. data/test/examples/asciidoc-html/block_open.adoc +17 -0
  55. data/test/examples/tex/env.tex +132 -0
  56. data/test/examples/tex/eq.tex +132 -0
  57. data/test/examples/tex/zero.tex +121 -0
  58. data/test/html_test.rb +8 -0
  59. data/test/latex_test.rb +8 -0
  60. data/test/test_helper.rb +4 -0
  61. data/test_jc/admonition.adoc +4 -0
  62. data/test_jc/click.adoc +7 -0
  63. data/test_jc/env.adoc +31 -0
  64. data/test_jc/example.adoc +17 -0
  65. data/test_jc/floating_title.adoc +15 -0
  66. data/test_jc/image.adoc +84 -0
  67. data/test_jc/images/frog.jpg +0 -0
  68. data/test_jc/images/red_frog.jpeg +0 -0
  69. data/test_jc/images/yellow_frog.jpeg +0 -0
  70. data/test_jc/listing.adoc +9 -0
  71. data/test_jc/lists.adoc +20 -0
  72. data/test_jc/math.adoc +10 -0
  73. data/test_jc/preamble.adoc +14 -0
  74. data/test_jc/section-numbered.adoc +9 -0
  75. data/test_jc/section.adoc +7 -0
  76. data/test_jc/sidebar.adoc +61 -0
  77. data/test_jc/verse.adoc +15 -0
  78. data/try-out/README.adoc +348 -0
  79. data/try-out/click.adoc +108 -0
  80. data/try-out/code.adoc +122 -0
  81. data/try-out/env.adoc +139 -0
  82. data/try-out/eq-latex.adoc +37 -0
  83. data/try-out/eq-stem.adoc +41 -0
  84. data/try-out/eqno-latex.adoc +120 -0
  85. data/try-out/math_article.adoc +138 -0
  86. data/try-out/pyth-stem.adoc +52 -0
  87. data/try-out/theorem-latex.adoc +50 -0
  88. data/try-out/xref-equations.adoc +28 -0
  89. metadata +210 -0
@@ -0,0 +1,105 @@
1
+ require 'open-uri'
2
+ require 'progressbar'
3
+ require_relative 'tar'
4
+
5
+ include Util::Tar
6
+
7
+ class JdkHelper
8
+
9
+ def self.extract_jdk path, extract_folder
10
+ FileUtils.remove_dir extract_folder, :force => true
11
+ io = ungzip File.new(path, "r")
12
+ untar io, extract_folder
13
+ jdk_bin_dir = "#{extract_folder}/bin"
14
+ File.chmod(0755, "#{jdk_bin_dir}/jjs")
15
+ File.chmod(0755, "#{jdk_bin_dir}/javac")
16
+ File.chmod(0755, "#{jdk_bin_dir}/java")
17
+ end
18
+
19
+ def self.download_binary_file url, destination_file
20
+ if File.file?(destination_file)
21
+ puts "File #{destination_file} already exists, skipping download"
22
+ else
23
+ puts "Downloading #{url} in #{destination_file}..."
24
+ pbar = nil
25
+ bindata = open(url, 'rb', :content_length_proc => lambda { |t|
26
+ if t && 0 < t
27
+ pbar = ProgressBar.new("...", t)
28
+ pbar.file_transfer_mode
29
+ end
30
+ }, :progress_proc => lambda {|s|
31
+ pbar.set s if pbar
32
+ }) {|file| file.read }
33
+ IO.binwrite(destination_file, bindata)
34
+ end
35
+ end
36
+
37
+ def self.get_jdk9_download_url
38
+ jdk_id = OS.windows? ? 'winOffline64JDK' : 'lin64JDKrpm'
39
+ get_jdk_download_url jdk_id, 'https://jdk9.java.net/download/'
40
+ end
41
+
42
+ def self.get_jdk8_download_url
43
+ jdk_id = OS.windows? ? 'winOffline64JDK' : 'lin64JDKrpm'
44
+ get_jdk_download_url jdk_id, 'https://jdk8.java.net/download.html'
45
+ end
46
+
47
+ def self.get_jdk_download_url jdk_id, url
48
+ html = open(url) {|file| file.read }
49
+ jdk_url_regexp = /document\.getElementById\(\"#{jdk_id}\"\)\.href = \"http:\/\/www.java.net\/download\/(.*)\";/
50
+ # Avoid redirection http -> https
51
+ "http://download.java.net/#{html.match(jdk_url_regexp).captures[0]}"
52
+ end
53
+
54
+ def self.compile_run_java_nashorn javac_bin, java_bin, file_path, class_name
55
+ puts "Compiling #{file_path} into build..."
56
+ `\"#{javac_bin}\" ./#{file_path} -d ./build`
57
+ puts "Compiling #{file_path} into build... OK"
58
+ puts "Running Nashorn java #{class_name}..."
59
+ beginning_time = Time.now
60
+ output = `\"#{java_bin}\" -classpath ./build #{class_name}`
61
+ end_time = Time.now
62
+ puts "Running Nashorn java #{class_name}... OK in #{(end_time - beginning_time)*1000} ms"
63
+ output
64
+ end
65
+
66
+ def self.run_jjs_nashorn jjs_bin, jjs_script
67
+ puts "Running Nashorn jjs #{jjs_script}..."
68
+ beginning_time = Time.now
69
+ output = `\"#{jjs_bin}\" #{jjs_script}`
70
+ end_time = Time.now
71
+ puts "Running Nashorn jjs #{jjs_script}... OK in #{(end_time - beginning_time)*1000} ms"
72
+ output
73
+ end
74
+ end
75
+
76
+ class Assertion
77
+ def self.check_convert output, test_name
78
+ unless output.include? "<h1>asciidoctor.js, AsciiDoc in JavaScript</h1>"
79
+ puts "output #{output}"
80
+ raise "#{test_name} failed, AsciiDoc source is not converted"
81
+ end
82
+ unless output.include? "include content"
83
+ puts "output #{output}"
84
+ raise "#{test_name} failed, include directive is not processed"
85
+ end
86
+ end
87
+ end
88
+
89
+ module OS
90
+ def OS.windows?
91
+ (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
92
+ end
93
+
94
+ def OS.mac?
95
+ (/darwin/ =~ RUBY_PLATFORM) != nil
96
+ end
97
+
98
+ def OS.unix?
99
+ !OS.windows?
100
+ end
101
+
102
+ def OS.linux?
103
+ OS.unix? and not OS.mac?
104
+ end
105
+ end
data/rake/tar-licence ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Colin MacKenzie IV
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/rake/tar.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rubygems/package'
3
+ require 'zlib'
4
+ require 'fileutils'
5
+
6
+ module Util
7
+ module Tar
8
+ # un-gzips the given IO, returning the
9
+ # decompressed version as a StringIO
10
+ def ungzip(tarfile)
11
+ z = Zlib::GzipReader.new(tarfile)
12
+ unzipped = StringIO.new(z.read)
13
+ z.close
14
+ unzipped
15
+ end
16
+
17
+ # untars the given IO into the specified
18
+ # directory
19
+ def untar(io, destination)
20
+ Gem::Package::TarReader.new io do |tar|
21
+ tar.each do |tarfile|
22
+ # NOTE skip the root directory of the tarfile
23
+ destination_file = File.join destination, tarfile.full_name.split('/', 2).last
24
+
25
+ if tarfile.directory?
26
+ FileUtils.mkdir_p destination_file
27
+ else
28
+ destination_directory = File.dirname(destination_file)
29
+ FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory)
30
+ File.open destination_file, "wb" do |f|
31
+ f.print tarfile.read
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
data/rspec/README.adoc ADDED
@@ -0,0 +1,45 @@
1
+ == rspec
2
+
3
+ At the moment there is just one set of tests, in
4
+ `transform_spec.rb`, which test a tiny piece
5
+ of a small part of the code. This is the
6
+ `gsub` call in the `TeXPreprocessor`.
7
+
8
+ I had been having some trouble with
9
+ instances of $ ... $ not being mapped
10
+ properly, and I think I've narrowd it down
11
+ to a few small edge cases -- I am trying
12
+ to collect these in the wild, as welll
13
+ as t imagine them.
14
+
15
+ I've organized the files as `a.rb`. `b.rb`,
16
+ and `c.rb`. The first two pass, the third
17
+ deos not. The strings that I try the
18
+ transformer on in `c.rb` are only a few
19
+ characters long.
20
+
21
+ === Help
22
+
23
+ @mojavelinux, my knowledge of regular expressions is not
24
+ so great -- could you look at this?
25
+
26
+ Please note that I had changed the output regular expression:
27
+
28
+ ----
29
+ TEX_DOLLAR_SUB = '\1\\\(\2\\\)\3'
30
+ TEX_DOLLAR_SUB2 = '\1latexmath:[\2]\3'
31
+ ----
32
+
33
+ using the first, rather than the second, which is your original. I don't
34
+ think that that is the problem -- it must be in the
35
+ recognizer,
36
+
37
+ ----
38
+ TEX_DOLLAR_RX = /(^|\s|\()\$(.*?)\$($|\s|\)|,|\.)/
39
+ ----
40
+
41
+ We can change back to (2), though I must say I like
42
+ (1) better since it parallels `\[ ... \]` and is more
43
+ succinct. Is there any difference in their function or
44
+ behavior _vis a vis_ Asciidoctor, i.e., in being
45
+ protected from substitution?
data/rspec/a.rb ADDED
@@ -0,0 +1,79 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/latex'
3
+ require 'asciidoctor/latex/core_ext/colored_string'
4
+ require_relative 'transform'
5
+
6
+ include Transform
7
+
8
+ VERBOSE = true
9
+
10
+ def compare_transform input, expected_output, transfomer
11
+
12
+ warn ' ' if VERBOSE
13
+ warn input.blue if VERBOSE
14
+ warn expected_output.cyan if VERBOSE
15
+ output = Transform.map_string input, transfomer
16
+ warn output.blue if VERBOSE
17
+ warn ' ' if VERBOSE
18
+ expect(output).to eq expected_output
19
+
20
+ end
21
+
22
+
23
+ describe Transform do
24
+
25
+ before :each do
26
+
27
+ end
28
+
29
+ it 'reads the contents of a file into a string (A1)' do
30
+
31
+ contents = Transform.read_string 'data/foo'
32
+ expect(contents.chomp).to eq 'foo.bar'
33
+
34
+ end
35
+
36
+ it 'implements the identity transform on strings (A2)' do
37
+
38
+ input = 'foo'
39
+ output = Transform.map_string input, $identity
40
+ expect(input).to eq output
41
+
42
+ end
43
+
44
+ it 'maps dollar-delimted strings to escapa-paren delimited strings (A3)' do
45
+
46
+ input = 'ha ha ha $a^2 = 1$ ho ho ho'
47
+ expected_output = 'ha ha ha \\(a^2 = 1\\) ho ho ho'
48
+ compare_transform input, expected_output, $fixmath
49
+
50
+ end
51
+
52
+ it 'maps dollar-delimted strings to latexmath-delimited strings' do
53
+
54
+ input = 'ha ha ha $a^2 = 1$ ho ho ho'
55
+ expected_output = 'ha ha ha latexmath:[a^2 = 1] ho ho ho'
56
+ compare_transform input, expected_output, $fixmath2
57
+
58
+ end
59
+
60
+
61
+ it 'reads strings from files' do
62
+
63
+ input = Transform.read_string 'data/lorem'
64
+ expect(input.length).to be > 0
65
+
66
+ end
67
+
68
+ it 'implements the identity transform on files' do
69
+
70
+ Transform.map_file 'data/lorem', 'data/tmp', $identity
71
+ original_content = Transform.read_string 'data/lorem'
72
+ transformed_content = Transform.read_string 'data/tmp'
73
+ expect(transformed_content).to eq original_content
74
+
75
+ end
76
+
77
+
78
+
79
+ end
data/rspec/b.rb ADDED
@@ -0,0 +1,111 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/latex'
3
+ require 'asciidoctor/latex/core_ext/colored_string'
4
+ require_relative 'transform'
5
+
6
+ include Transform
7
+
8
+ VERBOSE = true
9
+
10
+ def compare_transform input, expected_output, transfomer
11
+
12
+ warn ' ' if VERBOSE
13
+ warn input.blue if VERBOSE
14
+ warn expected_output.cyan if VERBOSE
15
+ output = Transform.map_string input, transfomer
16
+ warn output.blue if VERBOSE
17
+ warn ' ' if VERBOSE
18
+ expect(output).to eq expected_output
19
+
20
+ end
21
+
22
+
23
+ describe Transform do
24
+
25
+ before :each do
26
+
27
+ end
28
+
29
+
30
+
31
+ it 'handles the edge case of a dollar sign at the beginning of the line (A)' do
32
+
33
+ input = '$a^2 = 1$ ho ho ho'
34
+ expected_output = '\\(a^2 = 1\\) ho ho ho'
35
+ compare_transform input, expected_output, $fixmath
36
+
37
+ end
38
+
39
+ it 'handles the edge case of a dollar sign at the beginning of the line in latexmath (B)' do
40
+
41
+ input = '$a^2 = 1$ ho ho ho'
42
+ expected_output = 'latexmath:[a^2 = 1] ho ho ho'
43
+ compare_transform input, expected_output, $fixmath2
44
+
45
+ end
46
+
47
+ it 'handles the edge case of a dollar sign at the end of the line (C)' do
48
+
49
+ input = 'ha ha ha $a^2 = 1$'
50
+ expected_output = 'ha ha ha \\(a^2 = 1\\)'
51
+ compare_transform input, expected_output, $fixmath
52
+
53
+ end
54
+
55
+ it 'handles the edge case of a dollar sign at the end of the line wth latexmath (D)' do
56
+
57
+ input = 'ha ha ha $a^2 = 1$'
58
+ expected_output = 'ha ha ha latexmath:[a^2 = 1]'
59
+ compare_transform input, expected_output, $fixmath2
60
+
61
+ end
62
+
63
+ it 'handles the edge case of a dollar sign at the beginnng and end of the line (E)' do
64
+
65
+ input = '$a^2 = 1$'
66
+ expected_output = '\\(a^2 = 1\\)'
67
+ compare_transform input, expected_output, $fixmath
68
+
69
+ end
70
+
71
+ it 'handles the edge case of a dollar sign at the beginnng and end of the line plus a little space in mode 2 (F)' do
72
+
73
+ input = ' $a^2 = 1 $'
74
+ expected_output = ' latexmath:[a^2 = 1]'
75
+ compare_transform input, expected_output, $fixmath2
76
+
77
+ end
78
+
79
+ it 'handles the edge case of a dollar sign at the beginnng and end of the line in mode 2 (G)' do
80
+
81
+ input = '$a^2 = 1$'
82
+ expected_output = 'latexmath:[a^2 = 1]'
83
+ compare_transform input, expected_output, $fixmath2
84
+
85
+ end
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+ =begin
95
+ it 'applies the fixmath transform to files to files' do
96
+
97
+ Transform.map_file 'data/tex2', 'data/tmp', $fixmath
98
+
99
+ original_content = Transform.read_string 'data/tex2'
100
+ transformed_content = Transform.read_string 'data/tmp'
101
+ expected_content = Transform.read_string 'data/tex2.expect'
102
+
103
+ warn ('|||'+original_content+'|||').blue if VERBOSE
104
+ warn ('|||'+transformed_content+'|||').cyan if VERBOSE
105
+ warn ('|||'+expected_content+'|||').blue if VERBOSE
106
+ expect(transformed_content).to eq expected_content
107
+ end
108
+ =end
109
+
110
+
111
+ end
data/rspec/c.rb ADDED
@@ -0,0 +1,121 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/latex'
3
+ require 'asciidoctor/latex/core_ext/colored_string'
4
+ require_relative 'transform'
5
+
6
+ include Transform
7
+
8
+ VERBOSE = true
9
+
10
+ def compare_transform input, expected_output, transfomer
11
+
12
+ warn ' ' if VERBOSE
13
+ warn input.blue if VERBOSE
14
+ warn expected_output.cyan if VERBOSE
15
+ output = Transform.map_string input, transfomer
16
+ warn output.blue if VERBOSE
17
+ warn ' ' if VERBOSE
18
+ expect(output).to eq expected_output
19
+
20
+ end
21
+
22
+
23
+ describe Transform do
24
+
25
+ before :each do
26
+
27
+ end
28
+
29
+
30
+ it 'maps the text "$x$" correctly (A)' do
31
+
32
+ input = '$x$'
33
+ expected_output = '\(x\)'
34
+ compare_transform input, expected_output, $fixmath
35
+
36
+ end
37
+
38
+ it 'maps the text "$x$?" correctly (B)' do
39
+
40
+ input = '$x$?'
41
+ expected_output = '\(x\)?'
42
+ compare_transform input, expected_output, $fixmath
43
+
44
+ end
45
+
46
+ it 'maps the text "$x$-axis" correctly (C)' do
47
+
48
+ input = '$x$?-axis'
49
+ expected_output = '\(x\)-axis'
50
+ compare_transform input, expected_output, $fixmath
51
+
52
+ end
53
+
54
+ it 'maps the text "$Fe^{3+}$" correctly (D)' do
55
+
56
+ input = '$Fe^{3+}$'
57
+ expected_output = '\(Fe^{3+}\)'
58
+ compare_transform input, expected_output, $fixmath
59
+
60
+ end
61
+
62
+ it 'maps the text "$Cr^{+2}$ $Fe^{3+}$" correctly (E)' do
63
+
64
+ input = '$Cr^{+2}$ $Fe^{3+}$'
65
+ expected_output = '\(Cr^{+2}\) \(Fe^{3+}\)'
66
+ compare_transform input, expected_output, $fixmath
67
+
68
+ end
69
+
70
+ it 'maps the text "$\pi:U^+ \map U$" correctly (E)' do
71
+
72
+ input = '$\pi:U^+ \map U$'
73
+ expected_output = '\(\pi:U^+ \map U\)'
74
+ compare_transform input, expected_output, $fixmath
75
+
76
+ end
77
+
78
+ it 'maps the text "$\pi^{-1}(U) = U^+ \cup U^-" correctly (E)' do
79
+
80
+ input = '$\pi^{-1}(U) = U^+ \cup U^-$'
81
+ expected_output = '\(\pi^{-1}(U) = U^+ \cup U^-\)'
82
+ compare_transform input, expected_output, $fixmath
83
+
84
+ end
85
+
86
+ it 'maps the text "Then $\pi^{-1}(U) = U^+ \cup U^-$ is the disjoint union of two\nopen sets and $\pi:U^+ \map U$ is a local coordinate." correctly (E)' do
87
+
88
+ input = 'Then $\pi^{-1}(U) = U^+ \cup U^-$ is the disjoint union of two\nopen sets and $\pi:U^+ \map U$ is a local coordinate.'
89
+ expected_output = 'Then \(\pi^{-1}(U) = U^+ \cup U^-\) is the disjoint union of two\nopen sets and \(\pi:U^+ \map U\) is a local coordinate.'
90
+ compare_transform input, expected_output, $fixmath
91
+
92
+ end
93
+
94
+ it 'parses a complicated expression correctly (1)' do
95
+
96
+ input = <<EOF
97
+ iLet $a$ be a point of the set $\\CC - B$ let $U$ be a neighborhood of $a$ in
98
+ that set. Then $\pi^{-1}(U) = U^+ \\cup U^-$ is the disjoint union of two
99
+ open sets and $\pi:U^+ \map U$ is a local coordinate.
100
+ EOF
101
+
102
+ expected_output = <<EOF
103
+ Let \(a\) be a point of the set \(\\CC - B\) let \(U\) be a neighborhood of \(a\) in
104
+ that set. Then \(pi^{-1}(U) = U^+ \\cup U^-\) is the disjoint union of two
105
+ open sets and \(\pi:U^+ \map U\)is a local coordinate.
106
+ EOF
107
+
108
+ compare_transform input, expected_output, $fixmath
109
+
110
+ end
111
+
112
+ it 'maps the text "Call these $y_+$ and $y_-$." correctly (E)' do
113
+
114
+ input = 'Call these $y_+$ and $y_-$.'
115
+ expected_output = 'Call these \(y_+\) and \(y_-\).'
116
+ compare_transform input, expected_output, $fixmath
117
+
118
+ end
119
+
120
+
121
+ end