erbtex 0.2.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +25 -0
- data/LICENCE +22 -0
- data/README.md +127 -0
- data/Rakefile +15 -0
- data/bin/erbtex +49 -0
- data/bin/etex +49 -0
- data/bin/latex +49 -0
- data/bin/lualatex +49 -0
- data/bin/luatex +49 -0
- data/bin/pdfetex +49 -0
- data/bin/pdflatex +49 -0
- data/bin/pdftex +49 -0
- data/bin/pslatex +49 -0
- data/bin/tex +49 -0
- data/bin/xelatex +49 -0
- data/bin/xetex +49 -0
- data/docs/NOTES.org +34 -0
- data/erbtex.gemspec +29 -0
- data/examples/TrigTable.tex +125 -0
- data/examples/TrigTable2.tex +129 -0
- data/examples/dms.rb +185 -0
- data/examples/roots.tex +23 -0
- data/examples/testbind.rb +3 -0
- data/examples/testbind.tex +31 -0
- data/lib/erbtex/command_line.rb +160 -0
- data/lib/erbtex/find_binary.rb +41 -0
- data/lib/erbtex/runner.rb +108 -0
- data/lib/erbtex/version.rb +3 -0
- data/lib/erbtex.rb +10 -0
- data/test/test_command_line.rb +181 -0
- data/test/test_find_executable.rb +44 -0
- data/test/test_helper.rb +10 -0
- metadata +148 -0
data/bin/tex
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
verbose = true
|
4
|
+
|
5
|
+
# This adds our lib subdirectory to the ruby load path
|
6
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
7
|
+
|
8
|
+
# This adds our RUBYLIB env to ruby load path
|
9
|
+
if ENV['RUBYLIB']
|
10
|
+
STDERR.puts "ENV['RUBYLIB']:" if verbose
|
11
|
+
ENV['RUBYLIB'].split(':').each do |p|
|
12
|
+
$LOAD_PATH.unshift p
|
13
|
+
STDERR.puts "\t#{p}" if verbose
|
14
|
+
end
|
15
|
+
else
|
16
|
+
STDERR.puts "ENV['RUBYLIB'] is EMPTY" if verbose
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'erbtex'
|
20
|
+
|
21
|
+
progname = File.basename($0)
|
22
|
+
commandline = progname
|
23
|
+
ARGV.each do |a|
|
24
|
+
if a =~ /\s/
|
25
|
+
a = "'" + a + "'"
|
26
|
+
end
|
27
|
+
commandline += " #{a}"
|
28
|
+
end
|
29
|
+
|
30
|
+
if verbose
|
31
|
+
STDERR.puts "Program name: #{progname}"
|
32
|
+
STDERR.puts "Command line: #{commandline}"
|
33
|
+
STDERR.puts "Ruby Load path:"
|
34
|
+
$:.each do |p|
|
35
|
+
STDERR.puts "\t#{p}"
|
36
|
+
end
|
37
|
+
STDERR.puts 'ARGV:'
|
38
|
+
ARGV.each do |a|
|
39
|
+
STDERR.puts "\t#{a}"
|
40
|
+
end
|
41
|
+
STDERR.puts 'PATH:'
|
42
|
+
ENV['PATH'].split(':').each do |p|
|
43
|
+
STDERR.puts "\t#{p}"
|
44
|
+
end
|
45
|
+
STDERR.puts "Executable: "
|
46
|
+
STDERR.puts ErbTeX.find_executable($0)
|
47
|
+
end
|
48
|
+
|
49
|
+
ErbTeX.run(commandline)
|
data/bin/xelatex
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
verbose = true
|
4
|
+
|
5
|
+
# This adds our lib subdirectory to the ruby load path
|
6
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
7
|
+
|
8
|
+
# This adds our RUBYLIB env to ruby load path
|
9
|
+
if ENV['RUBYLIB']
|
10
|
+
STDERR.puts "ENV['RUBYLIB']:" if verbose
|
11
|
+
ENV['RUBYLIB'].split(':').each do |p|
|
12
|
+
$LOAD_PATH.unshift p
|
13
|
+
STDERR.puts "\t#{p}" if verbose
|
14
|
+
end
|
15
|
+
else
|
16
|
+
STDERR.puts "ENV['RUBYLIB'] is EMPTY" if verbose
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'erbtex'
|
20
|
+
|
21
|
+
progname = File.basename($0)
|
22
|
+
commandline = progname
|
23
|
+
ARGV.each do |a|
|
24
|
+
if a =~ /\s/
|
25
|
+
a = "'" + a + "'"
|
26
|
+
end
|
27
|
+
commandline += " #{a}"
|
28
|
+
end
|
29
|
+
|
30
|
+
if verbose
|
31
|
+
STDERR.puts "Program name: #{progname}"
|
32
|
+
STDERR.puts "Command line: #{commandline}"
|
33
|
+
STDERR.puts "Ruby Load path:"
|
34
|
+
$:.each do |p|
|
35
|
+
STDERR.puts "\t#{p}"
|
36
|
+
end
|
37
|
+
STDERR.puts 'ARGV:'
|
38
|
+
ARGV.each do |a|
|
39
|
+
STDERR.puts "\t#{a}"
|
40
|
+
end
|
41
|
+
STDERR.puts 'PATH:'
|
42
|
+
ENV['PATH'].split(':').each do |p|
|
43
|
+
STDERR.puts "\t#{p}"
|
44
|
+
end
|
45
|
+
STDERR.puts "Executable: "
|
46
|
+
STDERR.puts ErbTeX.find_executable($0)
|
47
|
+
end
|
48
|
+
|
49
|
+
ErbTeX.run(commandline)
|
data/bin/xetex
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
verbose = true
|
4
|
+
|
5
|
+
# This adds our lib subdirectory to the ruby load path
|
6
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
7
|
+
|
8
|
+
# This adds our RUBYLIB env to ruby load path
|
9
|
+
if ENV['RUBYLIB']
|
10
|
+
STDERR.puts "ENV['RUBYLIB']:" if verbose
|
11
|
+
ENV['RUBYLIB'].split(':').each do |p|
|
12
|
+
$LOAD_PATH.unshift p
|
13
|
+
STDERR.puts "\t#{p}" if verbose
|
14
|
+
end
|
15
|
+
else
|
16
|
+
STDERR.puts "ENV['RUBYLIB'] is EMPTY" if verbose
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'erbtex'
|
20
|
+
|
21
|
+
progname = File.basename($0)
|
22
|
+
commandline = progname
|
23
|
+
ARGV.each do |a|
|
24
|
+
if a =~ /\s/
|
25
|
+
a = "'" + a + "'"
|
26
|
+
end
|
27
|
+
commandline += " #{a}"
|
28
|
+
end
|
29
|
+
|
30
|
+
if verbose
|
31
|
+
STDERR.puts "Program name: #{progname}"
|
32
|
+
STDERR.puts "Command line: #{commandline}"
|
33
|
+
STDERR.puts "Ruby Load path:"
|
34
|
+
$:.each do |p|
|
35
|
+
STDERR.puts "\t#{p}"
|
36
|
+
end
|
37
|
+
STDERR.puts 'ARGV:'
|
38
|
+
ARGV.each do |a|
|
39
|
+
STDERR.puts "\t#{a}"
|
40
|
+
end
|
41
|
+
STDERR.puts 'PATH:'
|
42
|
+
ENV['PATH'].split(':').each do |p|
|
43
|
+
STDERR.puts "\t#{p}"
|
44
|
+
end
|
45
|
+
STDERR.puts "Executable: "
|
46
|
+
STDERR.puts ErbTeX.find_executable($0)
|
47
|
+
end
|
48
|
+
|
49
|
+
ErbTeX.run(commandline)
|
data/docs/NOTES.org
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
During an installation of texlive from ubuntu package, the following
|
2
|
+
error was triggered which appears to be the fault of erbtex.
|
3
|
+
Investigate.
|
4
|
+
|
5
|
+
#+begin_quote
|
6
|
+
fmtutil: running `mf-nowin -ini -jobname=mf -progname=mf -translate-file=cp227.tcx mf.ini' ...
|
7
|
+
This is METAFONT, Version 2.718281 (TeX Live 2012/Debian) (INIMF)
|
8
|
+
(/usr/share/texlive/texmf/web2c/cp227.tcx)
|
9
|
+
(/usr/share/texlive/texmf-dist/metafont/config/mf.ini
|
10
|
+
(/usr/share/texlive/texmf-dist/metafont/base/plain.mf
|
11
|
+
Preloading the plain base, version 2.71: preliminaries,
|
12
|
+
basic constants and mathematical macros,
|
13
|
+
macros for converting from device-independent units to pixels,
|
14
|
+
macros and tables for various modes of operation,
|
15
|
+
macros for drawing and filling,
|
16
|
+
macros for proof labels and rules,
|
17
|
+
macros for character and font administration,
|
18
|
+
and a few last-minute items.)
|
19
|
+
(/usr/share/texlive/texmf-dist/metafont/misc/modes.mf) )
|
20
|
+
Beginning to dump on file mf.base
|
21
|
+
(base=mf 2013.1.17)
|
22
|
+
2226 strings of total length 30005
|
23
|
+
11864 memory locations dumped; current usage is 3658&7844
|
24
|
+
1004 symbolic tokens
|
25
|
+
Transcript written on mf.log.
|
26
|
+
fmtutil: /var/lib/texmf/web2c/metafont/mf.base installed.
|
27
|
+
fmtutil: running `pdftex -ini -jobname=pdfetex -progname=pdfetex -translate-file=cp227.tcx *pdfetex.ini' ...
|
28
|
+
/home/ded/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs': Could not find erbtex (>= 0) amongst [bigdecimal-1.1.0, io-console-0.3, json-1.5.4, minitest-2.5.1, rake-0.9.2.2, rdoc-3.9.4] (Gem::LoadError)
|
29
|
+
from /home/ded/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'
|
30
|
+
from /home/ded/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems.rb:1231:in `gem'
|
31
|
+
from /home/ded/.rvm/gems/ruby-1.9.3-p194/bin/pdftex:18:in `<main>'
|
32
|
+
from /home/ded/.rvm/gems/ruby-1.9.3-p194/bin/ruby_noexec_wrapper:14:in `eval'
|
33
|
+
from /home/ded/.rvm/gems/ruby-1.9.3-p194/bin/ruby_noexec_wrapper:14:in `<main>'
|
34
|
+
#+end_quote
|
data/erbtex.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "./lib/erbtex/version.rb"
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = %q{erbtex}
|
7
|
+
gem.version = ErbTeX::VERSION
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.date = %q{2012-05-13}
|
10
|
+
gem.homepage = ""
|
11
|
+
gem.authors = ["Daniel E. Doherty"]
|
12
|
+
gem.email = %q{ded-erbtex@ddoherty.net}
|
13
|
+
gem.summary = %q{Preprocesses TeX and LaTeX files with erubis for ruby.}
|
14
|
+
gem.description = %q{Create a local link called pdflatex to erbtex and it will
|
15
|
+
act just like pdflatex except that it will process ruby fragments
|
16
|
+
between {: and :} markers, greatly expanding the ability to generate
|
17
|
+
automated TeX and LaTeX documents.}
|
18
|
+
|
19
|
+
gem.files = `git ls-files`.split("\n")
|
20
|
+
gem.files.delete_if {|f| f =~ /(log|etc|aux|etx|pdf|gem)$/}
|
21
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
gem.require_paths = ["lib"]
|
24
|
+
|
25
|
+
gem.add_dependency "erubis"
|
26
|
+
gem.add_development_dependency 'rake'
|
27
|
+
gem.add_development_dependency "bundler"
|
28
|
+
gem.add_development_dependency "byebug"
|
29
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
\documentclass{article}
|
2
|
+
|
3
|
+
\usepackage[mathbf]{euler}
|
4
|
+
\usepackage{longtable}
|
5
|
+
\usepackage{geometry}
|
6
|
+
\geometry{hmargin=0.5in,vmargin=1.2in}
|
7
|
+
|
8
|
+
%% Set up indexing headers and footer for fast lookup while
|
9
|
+
%% flipping pages.
|
10
|
+
\usepackage{fancyhdr}
|
11
|
+
\pagestyle{fancy}
|
12
|
+
\renewcommand{\headrulewidth}{0pt}
|
13
|
+
\rhead{\large\mathversion{bold}$\firstmark$}
|
14
|
+
\rfoot{\large\mathversion{bold}$\botmark$}
|
15
|
+
\lhead{}
|
16
|
+
|
17
|
+
\begin{document}
|
18
|
+
|
19
|
+
%% This function is a utility to help the sprintf
|
20
|
+
%% function keep the number of digits after the decimal
|
21
|
+
%% place at the right level to come out to 9 digits in total
|
22
|
+
%% both before and after the decimal point.
|
23
|
+
{: def digs(x)
|
24
|
+
if ("%0.8f" % x) =~ /[-+]?([0-9]*)\./
|
25
|
+
l = 10 - $1.length #$ This comment keeps syntax highlighting in emacs
|
26
|
+
# from getting confused. The single dollar
|
27
|
+
# sign makes it think is in math mode.
|
28
|
+
# Occasionally needed when ruby and LaTeX mix.
|
29
|
+
l = (l > 0 ? l : 0)
|
30
|
+
return l
|
31
|
+
end
|
32
|
+
return(0)
|
33
|
+
end
|
34
|
+
:}
|
35
|
+
|
36
|
+
%% Set up the longtable environment by specifying the header for
|
37
|
+
%% each page and the footer.
|
38
|
+
\begin{longtable}[c]{l|llllll}
|
39
|
+
\hline\hline
|
40
|
+
\multicolumn{1}{c|}{\mathversion{bold}$x$}&
|
41
|
+
\multicolumn{1}{c}{\mathversion{bold}$\sin(x)$}&
|
42
|
+
\multicolumn{1}{c}{\mathversion{bold}$\cos(x)$}&
|
43
|
+
\multicolumn{1}{c}{\mathversion{bold}$\tan(x)$}&
|
44
|
+
\multicolumn{1}{c}{\mathversion{bold}$\cot(x)$}&
|
45
|
+
\multicolumn{1}{c}{\mathversion{bold}$\sec(x)$}&
|
46
|
+
\multicolumn{1}{c}{\mathversion{bold}$\csc(x)$}\\
|
47
|
+
\hline\hline
|
48
|
+
\endhead
|
49
|
+
\hline\hline
|
50
|
+
\endfoot
|
51
|
+
|
52
|
+
{:
|
53
|
+
## Set up variables needed for computing the values that go into
|
54
|
+
## the table, taking care to use ruby's BigDecimal class to ensure
|
55
|
+
## accuracy. The table is set up here to go from 0 to pi/2 in
|
56
|
+
## increments of step
|
57
|
+
|
58
|
+
require 'bigdecimal'
|
59
|
+
step = BigDecimal.new("0.001")
|
60
|
+
one = BigDecimal("1.0")
|
61
|
+
z0 = BigDecimal("0.0")
|
62
|
+
p2 = BigDecimal.new((Math::PI / 2.0).to_s)
|
63
|
+
-:}
|
64
|
+
|
65
|
+
%% Treat the first line of the table, for an x value of 0 specially
|
66
|
+
%% by giving exact answers in symbolic form.
|
67
|
+
{:= "\\multicolumn{1}{c|}{{\\mathversion{bold}\\mark{0}$0$}}" :}&
|
68
|
+
{:= "\\multicolumn{1}{c}{{$0$}}" :}&
|
69
|
+
{:= "\\multicolumn{1}{c}{{$1$}}" :}&
|
70
|
+
{:= "\\multicolumn{1}{c}{{$0$}}" :}&
|
71
|
+
{:= "\\multicolumn{1}{c}{{$\\infty$}}" :}&
|
72
|
+
{:= "\\multicolumn{1}{c}{{$1$}}" :}&
|
73
|
+
{:= "\\multicolumn{1}{c}{{$\\infty$}}" :}\\
|
74
|
+
|
75
|
+
%% Here is the loop for the body of the table, which starts with
|
76
|
+
%% x one step beyond 0 and pre-computes some of the functions
|
77
|
+
{: x = z0 + step
|
78
|
+
while (x < p2) do
|
79
|
+
tanx = BigDecimal.new(Math.tan(x).to_s)
|
80
|
+
cotx = one / BigDecimal.new(Math.tan(x).to_s)
|
81
|
+
secx = one / BigDecimal.new(Math.cos(x).to_s)
|
82
|
+
cscx = one / BigDecimal.new(Math.sin(x).to_s)
|
83
|
+
:}
|
84
|
+
|
85
|
+
{:
|
86
|
+
## Here is where each line of the main body of the table is set.
|
87
|
+
## We use the digs function defined above to make sure that every
|
88
|
+
## column as the same number of significant digits for the functions
|
89
|
+
## that tend toward infinity.
|
90
|
+
##
|
91
|
+
## NB: I could write this comment as a LaTeX comment outside a code
|
92
|
+
## segment, but then it would end up in the generated LaTeX file,
|
93
|
+
## TrigTable.etx. Doing so made that file about 6MB in size; by
|
94
|
+
## putting the comments inside this ruby code block, the size was
|
95
|
+
## around 2MB.
|
96
|
+
-:}
|
97
|
+
{: xf = "%0.4f" % x :}
|
98
|
+
\mark{{:= xf :}}
|
99
|
+
{:= "\\mathversion{bold}$%0.4f$" % x :}&
|
100
|
+
{:= "$%0.8f$" % Math.sin(x) :}&
|
101
|
+
{:= "$%0.8f$" % Math.cos(x) :}&
|
102
|
+
{:= "$%0.*f$" % [ digs(tanx), tanx ] :}&
|
103
|
+
{:= "$%0.*f$" % [ digs(cotx), cotx ] :}&
|
104
|
+
{:= "$%0.*f$" % [ digs(secx), secx ] :}&
|
105
|
+
{:= "$%0.*f$" % [ digs(cscx), cscx ] :}\\
|
106
|
+
|
107
|
+
%% Step and loop
|
108
|
+
{:
|
109
|
+
x += step
|
110
|
+
end
|
111
|
+
:}
|
112
|
+
|
113
|
+
%% Finally, treat the last row of the table for pi/2 specially
|
114
|
+
%% by giving exact values symbolically.
|
115
|
+
{:= "\\multicolumn{1}{c}{{\\mark{\\pi/{2}}\\mathversion{bold}$\\pi/{2}$}}" :}&
|
116
|
+
{:= "\\multicolumn{1}{c}{$1$}" :}&
|
117
|
+
{:= "\\multicolumn{1}{c}{$0$}" :}&
|
118
|
+
{:= "\\multicolumn{1}{c}{$\\infty$}" :}&
|
119
|
+
{:= "\\multicolumn{1}{c}{$0$}" :}&
|
120
|
+
{:= "\\multicolumn{1}{c}{$\\infty$}" :}&
|
121
|
+
{:= "\\multicolumn{1}{c}{$1$}" :}\\
|
122
|
+
|
123
|
+
%% End the table and document---this version comes to 315 pages!
|
124
|
+
\end{longtable}
|
125
|
+
\end{document}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
\documentclass{article}
|
2
|
+
|
3
|
+
\usepackage[mathbf]{euler}
|
4
|
+
\usepackage{longtable}
|
5
|
+
\usepackage{geometry}
|
6
|
+
\geometry{head=14pt,hmargin=0.5in,vmargin=1.35in}
|
7
|
+
|
8
|
+
%% Set up indexing headers and footer for fast lookup while
|
9
|
+
%% flipping pages.
|
10
|
+
\usepackage{fancyhdr}
|
11
|
+
\pagestyle{fancy}
|
12
|
+
\renewcommand{\headrulewidth}{0pt}
|
13
|
+
\rhead{\large\mathversion{bold}\firstmark}
|
14
|
+
\rfoot{\large\mathversion{bold}\botmark}
|
15
|
+
\lhead{}
|
16
|
+
|
17
|
+
\begin{document}
|
18
|
+
|
19
|
+
%% This function is a utility to help the sprintf
|
20
|
+
%% function keep the number of digits after the decimal
|
21
|
+
%% place at the right level to come out to 9 digits in total
|
22
|
+
%% both before and after the decimal point.
|
23
|
+
{: def digs(x)
|
24
|
+
if ("%0.8f" % x) =~ /[-+]?([0-9]*)\./
|
25
|
+
l = 10 - $1.length #$
|
26
|
+
l = (l > 0 ? l : 0)
|
27
|
+
return l
|
28
|
+
end
|
29
|
+
return(0)
|
30
|
+
end
|
31
|
+
:}
|
32
|
+
|
33
|
+
%% Set up the longtable environment by specifying the header for
|
34
|
+
%% each page and the footer.
|
35
|
+
\begin{longtable}[c]{c|llllll}
|
36
|
+
\hline\hline
|
37
|
+
\multicolumn{1}{c|}{\mathversion{bold}$x$}&
|
38
|
+
\multicolumn{1}{c}{\mathversion{bold}$\sin(x)$}&
|
39
|
+
\multicolumn{1}{c}{\mathversion{bold}$\cos(x)$}&
|
40
|
+
\multicolumn{1}{c}{\mathversion{bold}$\tan(x)$}&
|
41
|
+
\multicolumn{1}{c}{\mathversion{bold}$\cot(x)$}&
|
42
|
+
\multicolumn{1}{c}{\mathversion{bold}$\sec(x)$}&
|
43
|
+
\multicolumn{1}{c}{\mathversion{bold}$\csc(x)$}\\
|
44
|
+
\hline\hline
|
45
|
+
\endhead
|
46
|
+
\hline\hline
|
47
|
+
\endfoot
|
48
|
+
|
49
|
+
{:
|
50
|
+
## Set up variables needed for computing the values that go into
|
51
|
+
## the table, taking care to use ruby's BigDecimal class to ensure
|
52
|
+
## accuracy. The table is set up here to go from 0 to pi/2 in
|
53
|
+
## increments of step.
|
54
|
+
|
55
|
+
require 'bigdecimal'
|
56
|
+
require 'dms'
|
57
|
+
DMS.precision = 0
|
58
|
+
step = DMS.new(0, 0, 30)
|
59
|
+
one = BigDecimal("1.0")
|
60
|
+
d0 = DMS.new(0)
|
61
|
+
d90 = DMS.new(90)
|
62
|
+
-:}
|
63
|
+
|
64
|
+
%% Treat the first line of the table, for an x value of 0 specially
|
65
|
+
%% by giving exact answers in symbolic form.
|
66
|
+
{:= "\\multicolumn{1}{c|}{{\\mathversion{bold}\\mark{%s}$0$}}" % d0.to_tex :}&
|
67
|
+
{:= "\\multicolumn{1}{c}{{$0$}}" :}&
|
68
|
+
{:= "\\multicolumn{1}{c}{{$1$}}" :}&
|
69
|
+
{:= "\\multicolumn{1}{c}{{$0$}}" :}&
|
70
|
+
{:= "\\multicolumn{1}{c}{{$\\infty$}}" :}&
|
71
|
+
{:= "\\multicolumn{1}{c}{{$1$}}" :}&
|
72
|
+
{:= "\\multicolumn{1}{c}{{$\\infty$}}" :}\\
|
73
|
+
|
74
|
+
%% Here is the loop for the body of the table, which starts with
|
75
|
+
%% x one step beyond 0 and pre-computes some of the functions
|
76
|
+
{: x = d0 + step
|
77
|
+
while (x < d90) do
|
78
|
+
tanx = x.tan
|
79
|
+
cotx = x.cotan
|
80
|
+
secx = x.sec
|
81
|
+
cscx = x.csc
|
82
|
+
:}
|
83
|
+
|
84
|
+
{:
|
85
|
+
## Here is where each line of the main body of the table is set.
|
86
|
+
## We use the digs function defined above to make sure that every
|
87
|
+
## column as the same number of significant digits for the functions
|
88
|
+
## that tend toward infinity.
|
89
|
+
##
|
90
|
+
## NB: I could write this comment as a LaTeX comment outside a code
|
91
|
+
## segment, but then it would end up in the generated LaTeX file,
|
92
|
+
## TrigTable.etx. Doing so made that file about 6MB in size; by
|
93
|
+
## putting the comments inside this ruby code block, the size was
|
94
|
+
## around 2MB.
|
95
|
+
-:}
|
96
|
+
\mark{{:= x.to_tex :}}
|
97
|
+
{:= "\\mathversion{bold}#{x.to_tex}" :}&
|
98
|
+
{:= "$%0.8f$" % x.sin :}&
|
99
|
+
{:= "$%0.8f$" % x.cos :}&
|
100
|
+
{:= "$%0.*f$" % [ digs(tanx), tanx ] :}&
|
101
|
+
{:= "$%0.*f$" % [ digs(cotx), cotx ] :}&
|
102
|
+
{:= "$%0.*f$" % [ digs(secx), secx ] :}&
|
103
|
+
{:= "$%0.*f$" % [ digs(cscx), cscx ] :}\\
|
104
|
+
|
105
|
+
%% Step and loop
|
106
|
+
{:
|
107
|
+
x += step
|
108
|
+
end
|
109
|
+
:}
|
110
|
+
|
111
|
+
%% This causes a LaTeX error, but nonetheless gets the final line of
|
112
|
+
%% the table squeezed onto the last page instead of on a page by
|
113
|
+
%% itself. Uncomment if that's what you want.
|
114
|
+
%{\enlargethispage{20pt}}
|
115
|
+
|
116
|
+
%% Finally, treat the last row of the table for pi/2 specially
|
117
|
+
%% by giving exact values symbolically.
|
118
|
+
{:= "\\multicolumn{1}{c|}{\\mark{%s}\\mathversion{bold}%s}" %
|
119
|
+
[d90.to_tex, d90.to_tex] :}&
|
120
|
+
{:= "\\multicolumn{1}{c}{$1$}" :}&
|
121
|
+
{:= "\\multicolumn{1}{c}{$0$}" :}&
|
122
|
+
{:= "\\multicolumn{1}{c}{$\\infty$}" :}&
|
123
|
+
{:= "\\multicolumn{1}{c}{$0$}" :}&
|
124
|
+
{:= "\\multicolumn{1}{c}{$\\infty$}" :}&
|
125
|
+
{:= "\\multicolumn{1}{c}{$1$}" :}\\
|
126
|
+
|
127
|
+
%% End the table and document---this version comes to 649 pages!
|
128
|
+
\end{longtable}
|
129
|
+
\end{document}
|
data/examples/dms.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
# A class for maipulating angles expressed as degreed, minutes,
|
4
|
+
# and seconds.
|
5
|
+
|
6
|
+
class DMS
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
attr_reader :degrees, :minutes, :seconds
|
10
|
+
|
11
|
+
@@precision = 4
|
12
|
+
|
13
|
+
def initialize(d, m = 0, s = 0.0)
|
14
|
+
@degrees = d.to_i
|
15
|
+
@minutes = m.to_i
|
16
|
+
@seconds = s.to_f
|
17
|
+
self.normalize
|
18
|
+
end
|
19
|
+
|
20
|
+
def DMS.from_radians(r)
|
21
|
+
if r < 0
|
22
|
+
r = -r
|
23
|
+
sign = -1
|
24
|
+
else
|
25
|
+
sign = 1
|
26
|
+
end
|
27
|
+
deg = r * (360.0 / (2.0 * Math::PI))
|
28
|
+
degrees = deg.floor
|
29
|
+
min = (deg - degrees) * 60.0
|
30
|
+
minutes = min.floor
|
31
|
+
seconds = min - minutes
|
32
|
+
DMS.new(degrees, minutes, seconds)
|
33
|
+
end
|
34
|
+
|
35
|
+
def DMS.precision=(p)
|
36
|
+
@@precision = p
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"#{@degrees}* #{@minutes}' %0.*f''" % [@@precision, @seconds]
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_f
|
44
|
+
@degrees.to_f + (@minutes / 60.0) + (@seconds / 3600.0)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_radians
|
48
|
+
self.to_f * ((2.0 * Math::PI) / 360.0)
|
49
|
+
end
|
50
|
+
|
51
|
+
# If degrees are at well-known values, eppress as radians
|
52
|
+
# symbolically, using TeX notation
|
53
|
+
def to_radians_tex
|
54
|
+
unless @seconds == 0.0 and @minutes == 0
|
55
|
+
return "$%0.*f$" % [@@precision, self.to_radians]
|
56
|
+
end
|
57
|
+
|
58
|
+
# This gets deg to 0 <= x <= 360, even for negative
|
59
|
+
# values of @degrees
|
60
|
+
deg = @degrees.divmod(360)[1]
|
61
|
+
case deg
|
62
|
+
when 0
|
63
|
+
"$0$"
|
64
|
+
when 30
|
65
|
+
"$\\pi/6$"
|
66
|
+
when 60
|
67
|
+
"$\\pi/3$"
|
68
|
+
when 90
|
69
|
+
"$\\pi/2$"
|
70
|
+
when 120
|
71
|
+
"$2\\pi/2$"
|
72
|
+
when 150
|
73
|
+
"$5\\pi/6$"
|
74
|
+
when 180
|
75
|
+
"$\\pi$"
|
76
|
+
when 210
|
77
|
+
"$7\\pi/6$"
|
78
|
+
when 240
|
79
|
+
"$4\\pi/3$"
|
80
|
+
when 270
|
81
|
+
"$3\\pi/2$"
|
82
|
+
when 300
|
83
|
+
"5\\pi/3$"
|
84
|
+
when 330
|
85
|
+
"11\\pi/6$"
|
86
|
+
when 360
|
87
|
+
"$2\\pi$"
|
88
|
+
else
|
89
|
+
"$%0.*f$" % [@@precision, self.to_radians]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_tex
|
94
|
+
# "$#{@degrees}^\\circ #{@minutes}' %0.*f''$" % [@@precision, @seconds] #"
|
95
|
+
"$%02d^\\circ~%02d'~%02.*f''$" % [@degrees, @minutes, @@precision, @seconds] #"
|
96
|
+
end
|
97
|
+
|
98
|
+
def -@
|
99
|
+
DMS.new(-@degrees, @minutes, @seconds)
|
100
|
+
end
|
101
|
+
|
102
|
+
def +@
|
103
|
+
DMS.new(@degrees, @minutes, @seconds)
|
104
|
+
end
|
105
|
+
|
106
|
+
def <=>(other)
|
107
|
+
self.to_radians <=> other.to_radians
|
108
|
+
end
|
109
|
+
|
110
|
+
def +(other)
|
111
|
+
seconds = @seconds + other.seconds
|
112
|
+
minutes = @minutes + other.minutes
|
113
|
+
degrees = @degrees + other.degrees
|
114
|
+
DMS.new(degrees, minutes, seconds)
|
115
|
+
end
|
116
|
+
|
117
|
+
def -(other)
|
118
|
+
r = (self + (-other))
|
119
|
+
DMS.new(r.degrees, r.minutes, r.seconds)
|
120
|
+
end
|
121
|
+
|
122
|
+
def *(scalar)
|
123
|
+
DMS.new(scalar*@degrees, scalar*@minutes, scalar*@seconds)
|
124
|
+
end
|
125
|
+
|
126
|
+
def /(scalar)
|
127
|
+
DMS.new(@degrees / scalar, @minutes / scalar, @seconds / scalar)
|
128
|
+
end
|
129
|
+
|
130
|
+
def sin
|
131
|
+
Math.sin(self.to_radians)
|
132
|
+
end
|
133
|
+
|
134
|
+
def cos
|
135
|
+
Math.cos(self.to_radians)
|
136
|
+
end
|
137
|
+
|
138
|
+
def tan
|
139
|
+
Math.tan(self.to_radians)
|
140
|
+
end
|
141
|
+
|
142
|
+
def sec
|
143
|
+
(1.0 / Math.cos(self.to_radians))
|
144
|
+
end
|
145
|
+
|
146
|
+
def csc
|
147
|
+
(1.0 / Math.sin(self.to_radians))
|
148
|
+
end
|
149
|
+
|
150
|
+
def cotan
|
151
|
+
(1.0 / Math.tan(self.to_radians))
|
152
|
+
end
|
153
|
+
|
154
|
+
# Ensure that seconds and minutes are 0 <= x < 60.
|
155
|
+
# After normalization, only degrees can be negative,
|
156
|
+
# which will represent a negative quantity
|
157
|
+
def normalize
|
158
|
+
q, r = @seconds.divmod(60.0)
|
159
|
+
@seconds = r
|
160
|
+
@minutes += q
|
161
|
+
q, r = @minutes.divmod(60)
|
162
|
+
@minutes = r
|
163
|
+
@degrees += q
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Fixnum
|
168
|
+
alias times *
|
169
|
+
def *(dms)
|
170
|
+
case dms
|
171
|
+
when DMS
|
172
|
+
dms * self
|
173
|
+
else
|
174
|
+
self.times(dms)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
if __FILE__ == $0
|
180
|
+
print "Fifty seconds: #{DMS.new(0, 0, 50).to_radians}\n"
|
181
|
+
print "One minute: #{DMS.new(0, 1, 0).to_radians}\n"
|
182
|
+
print "Fifty seconds: #{DMS.new(0, 0, 50).to_f}\n"
|
183
|
+
print "One minute: #{DMS.new(0, 1, 0).to_f}\n"
|
184
|
+
print "#{DMS.from_radians(Math::PI / 2.0)}\n"
|
185
|
+
end
|
data/examples/roots.tex
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
\documentclass{article}
|
2
|
+
\usepackage[mathbf]{euler}
|
3
|
+
\usepackage{longtable}
|
4
|
+
|
5
|
+
\begin{document}
|
6
|
+
\begin{longtable}[c]{r|r}
|
7
|
+
\hline\hline
|
8
|
+
\multicolumn{1}{c|}{\mathversion{bold}$x$}&
|
9
|
+
\multicolumn{1}{c}{\mathversion{bold}\rule{0pt}{12pt}$\sqrt{x}$}\\
|
10
|
+
\hline\hline
|
11
|
+
\endhead
|
12
|
+
\hline\hline
|
13
|
+
\endfoot
|
14
|
+
|
15
|
+
%% Here is the loop for the body of the table, which starts with
|
16
|
+
%% x one step beyond 0 and pre-computes some of the functions
|
17
|
+
{:0.upto(100).each do |x| :}
|
18
|
+
{:= "\\mathversion{bold}$%0.4f$" % x :}&
|
19
|
+
{:= "$%0.8f$" % Math.sqrt(x) :}\\
|
20
|
+
{:end:}
|
21
|
+
%% End the table and document---this version comes to 315 pages!
|
22
|
+
\end{longtable}
|
23
|
+
\end{document}
|