erbtex 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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}
|