texlab 0.1.1 → 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.
data/Gemfile CHANGED
@@ -1,11 +1,12 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake4latex"
4
- gem "plusminus"
5
- gem "easystats"
6
- gem "to_latex"
7
- gem "gnuplot"
8
- gem "latex"
3
+ gem "rake4latex", "0.1.3"
4
+ gem "plusminus", "0.2.0"
5
+ gem "easystats", "0.1.0"
6
+ gem "to_latex", "0.4.0"
7
+ gem "gnuplot", "~> 2.4.1"
8
+ gem "latex", "0.1.3"
9
+ gem "nio-percent_fmt", "0.0.0"
9
10
 
10
11
  group :development do
11
12
  gem "rspec", "~> 2.8.0"
@@ -17,7 +17,9 @@ GEM
17
17
  log4r (1.1.10)
18
18
  nio (0.2.5)
19
19
  flt (>= 1.0.0)
20
- plusminus (0.1.0)
20
+ nio-percent_fmt (0.0.0)
21
+ nio
22
+ plusminus (0.2.0)
21
23
  nio
22
24
  rake (0.9.2.2)
23
25
  rake4latex (0.1.3)
@@ -42,13 +44,14 @@ PLATFORMS
42
44
 
43
45
  DEPENDENCIES
44
46
  bundler (~> 1.0.0)
45
- easystats
46
- gnuplot
47
+ easystats (= 0.1.0)
48
+ gnuplot (~> 2.4.1)
47
49
  jeweler (~> 1.8.3)
48
- latex
49
- plusminus
50
- rake4latex
50
+ latex (= 0.1.3)
51
+ nio-percent_fmt (= 0.0.0)
52
+ plusminus (= 0.2.0)
53
+ rake4latex (= 0.1.3)
51
54
  rcov
52
55
  rdoc (~> 3.12)
53
56
  rspec (~> 2.8.0)
54
- to_latex
57
+ to_latex (= 0.4.0)
data/Rakefile CHANGED
@@ -22,6 +22,7 @@ Jeweler::Tasks.new do |gem|
22
22
  gem.email = "kallo.bernat@gmail.com"
23
23
  gem.authors = ["Bernát Kalló"]
24
24
  gem.executables = ["texlab-compile"]
25
+ gem.files = FileList["lib/**/*.rb", "bin/*", "[A-Z]*", "spec/**/*"].to_a
25
26
  # dependencies defined in Gemfile
26
27
  end
27
28
  Jeweler::RubygemsDotOrgTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
Binary file
@@ -18,11 +18,11 @@ begin
18
18
  infile = ARGV[0] || fail
19
19
  outfile = ARGV[1] || infile.sub(/(\.texlab)?$/, ".tex")
20
20
 
21
- src = nil
21
+ content = nil
22
22
  File.open infile do |f|
23
- src = f.read
23
+ content = f.read
24
24
  end
25
- fail if !src
25
+ fail if !content
26
26
 
27
27
  rescue
28
28
  STDERR.puts File.basename($0) + " <inputfile> <outputfile>"
@@ -32,13 +32,25 @@ EOU
32
32
 
33
33
  else
34
34
 
35
- # load boot code
36
- File.open File.expand_path(__FILE__+"/../../lib/texlab/boot.rb") do |f|
37
- src = "<%\n" << f.read << "\n%>\n" << src
35
+ src = "<% $_binding=binding %>"
36
+
37
+ # load modules
38
+
39
+ %w(hash latex debug figure macro math plot stats table tikz).each do |f|
40
+ f = File.expand_path(__FILE__+"/../../lib/texlab/#{f}.rb")
41
+ File.open f do |file|
42
+ s = file.read
43
+ s.gsub!(/([\\#"])/,"\\\\\\1"); s.gsub!(/\n/, "\\\\n")
44
+ f.gsub!(/([\\#"])/,"\\\\\\1"); f.gsub!(/\n/, "\\\\n")
45
+ src << "<% eval(\"#{s}\",binding,\"#{f}\") %>"
46
+ end
38
47
  end
39
48
 
49
+ src << content
50
+
40
51
  # run erb
41
52
  erb = TEXERB.new(src.untaint, nil, ">", "$_erbout")
53
+ erb.filename = infile
42
54
 
43
55
  File.open outfile, "w" do |f|
44
56
  f.print erb.result(TOPLEVEL_BINDING.taint)
@@ -0,0 +1,7 @@
1
+
2
+ # debug
3
+ def debug *args
4
+ args.each {|a| STDERR.puts a.inspect}
5
+ return *args
6
+ end
7
+
@@ -0,0 +1,32 @@
1
+ # Figure generation
2
+ #
3
+
4
+ def figure *args
5
+ opts = args.extract_options!
6
+ caption = args.shift
7
+ format = opts[:width] ? "width=#{opts[:width]}" : opts[:format]
8
+ label = opts[:label]
9
+ filename = opts[:filename]
10
+ if @_figures
11
+ @_figures << Figure.new(format, filename, caption, label)
12
+ else
13
+ raise "not implemented"
14
+ end
15
+ end
16
+
17
+ def figures *args
18
+ opts = args.extract_options!
19
+ placement = opts.delete(:placement) || "htbp"
20
+ label = opts.delete(:label)
21
+ newPageThreshold = opts.delete(:newPageThreshold) || 29
22
+ caption = args.shift
23
+
24
+ @_figures = []
25
+ yield
26
+
27
+ $_latexfile.figures(caption, @_figures, newPageThreshold, placement, label)
28
+
29
+ @_figures = nil
30
+ end
31
+
32
+
@@ -0,0 +1,52 @@
1
+
2
+ # tweak Array
3
+ class Array
4
+ def extract_options!
5
+ if last.is_a? Hash
6
+ pop
7
+ else
8
+ {}
9
+ end
10
+ end
11
+ end
12
+
13
+ # tweak Hash
14
+ class Hash
15
+ # Object-like behavior
16
+ def method_missing name, *args
17
+ name_string = name.to_s
18
+ case name_string[-1]
19
+ when "="
20
+ self[name_string[0..-2].to_sym] = args[0]
21
+ when "!"
22
+ self[name_string[0..-2].to_sym] = {}
23
+ when "?"
24
+ !! self[name_string[0..-2]]
25
+ else
26
+ self[name]
27
+ end
28
+ end
29
+
30
+ def slice *args
31
+ args.mash{|k| self[k]}
32
+ end
33
+ end
34
+
35
+ module Enumerable
36
+ # map-hash
37
+ def mash
38
+ res = {}
39
+ each do |*x|
40
+ k,v = yield(*x)
41
+ res[k] = v
42
+ end
43
+ res
44
+ end
45
+ end
46
+
47
+ class Hash
48
+ def mash! &block
49
+ replace mash(&block)
50
+ end
51
+ end
52
+
@@ -0,0 +1,22 @@
1
+ # latex generation helper
2
+ require "plusminus"
3
+ require "to_latex"
4
+ require "nio/percent_fmt"
5
+
6
+ require "texlab/texlabfile"
7
+
8
+ $_latexfile = TexlabFile.new $_erbout
9
+
10
+ def documentHeader *args
11
+ $_latexfile.documentHeader *args
12
+ end
13
+
14
+ def env *args
15
+ $_latexfile.env(*args){yield}
16
+ end
17
+
18
+ def puts string
19
+ $_erbout << string.to_latex << "\n"
20
+ end
21
+
22
+
@@ -0,0 +1,101 @@
1
+ # macros
2
+
3
+ $_macros={}
4
+
5
+ # a macro is available in tex (\asdf) and in ruby (:asdf.to_latex or $asdf). It will go to math
6
+ # mode
7
+ def macro hash
8
+ hash.each do |key, value|
9
+ value = value.latex!.to_latex_math
10
+ define_latex_macro key, value
11
+ define_symbol_macro key, value
12
+ define_global_macro key, value
13
+ end
14
+ end
15
+
16
+ # a text macro is available in tex (\asdf) and in ruby (:asdf, $asdf). It will not be
17
+ # forced to math mode
18
+ def text_macro hash
19
+ hash.each do |key, value|
20
+ value = "\\text{#{value}}".latex!
21
+ define_latex_macro key, value
22
+ define_symbol_macro key, value
23
+ define_global_macro key, value
24
+ end
25
+ end
26
+
27
+ def define_symbol_macro key, value
28
+ $_macros[key] = value
29
+ end
30
+
31
+ def define_latex_macro key, value
32
+ $_erbout << "\\def\\#{key}{#{value}}"
33
+ end
34
+
35
+ def define_global_macro key, value
36
+ eval "$#{key} = '#{value.gsub("\\","\\\\").gsub("'", "\\'")}'"
37
+ end
38
+
39
+ class Symbol
40
+ # symbol's to_latex is the macro with the same name
41
+ def to_latex
42
+ $_macros[self] or raise "Undefined macro: #{self}"
43
+ end
44
+
45
+ def + str
46
+ "#{to_latex}#{str}".latex!.to_latex_math
47
+ end
48
+
49
+ def * unit
50
+ "\\unit[\\text{#{to_latex}}]{#{unit}}".latex!.to_latex_math
51
+ end
52
+ end
53
+
54
+
55
+
56
+
57
+ %w(
58
+ alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho sigma tau upsilon phi chi psi omega
59
+ ).each do |a|
60
+ [a, a.capitalize].each do |b|
61
+ key = b.to_sym
62
+ value = "\\#{b}".latex!.to_latex_math
63
+ define_symbol_macro key, value
64
+ define_global_macro key, value
65
+ end
66
+ end
67
+
68
+ ('a'..'z').each do |a|
69
+ [a, a.capitalize].each do |b|
70
+ key = b.to_sym
71
+ value = "#{b}".latex!.to_latex_math
72
+ define_symbol_macro key, value
73
+ define_global_macro key, value
74
+ end
75
+ end
76
+
77
+
78
+ # units
79
+ $_units = {}
80
+
81
+ def unit hash
82
+ # allow array keys to be DRY
83
+ hash.each do |ks,v|
84
+ [*ks].each do |k|
85
+ $_units[k] = v
86
+ end
87
+ end
88
+ end
89
+
90
+ class Symbol
91
+ def with_unit
92
+ raise "No unit defined for #{self}" unless $_units.key? self
93
+ if $_units[self]
94
+ self * "(#{$_units[self]})"
95
+ else
96
+ to_latex
97
+ end
98
+ end
99
+ end
100
+
101
+
@@ -0,0 +1,13 @@
1
+ # include Math
2
+ include Math
3
+
4
+ # degree radian
5
+ def degrees x
6
+ x * 180.0 / Math::PI
7
+ end
8
+
9
+ def radians x
10
+ x / 180.0 * Math::PI
11
+ end
12
+
13
+
@@ -0,0 +1,177 @@
1
+ # plotting
2
+ #
3
+
4
+ require "gnuplot"
5
+ require "open3"
6
+
7
+ # override to have "w+" mode
8
+ def Gnuplot.open( persist=true )
9
+ cmd = Gnuplot.gnuplot( persist ) or raise 'gnuplot not found'
10
+ IO::popen( cmd, "w+") { |io| yield io }
11
+ end
12
+
13
+ def plot *args
14
+ opts = args.extract_options!
15
+ title = args[0]
16
+
17
+ placement = opts.delete(:placement) || (opts[:label] ? "htbp" : "H")
18
+ width = opts.delete(:width) || "17cm"
19
+ height = opts.delete(:height) || "10cm"
20
+ cmd = opts.delete(:cmd) || "plot"
21
+ label = opts.delete(:label)
22
+ debug = opts.delete(:debug)
23
+
24
+ env :figure, "[#{placement}]" do
25
+ env :center do
26
+ @_datasets = []
27
+ yield
28
+ @_datasets
29
+
30
+ gnuplot = Gnuplot.gnuplot(true) or raise "gnuplot not found"
31
+ Open3.popen3(gnuplot) do |gp, out, err, external|
32
+ gp = STDERR if debug
33
+ gp <<<<-GP
34
+ set terminal latex size #{width}, #{height}
35
+ GP
36
+
37
+ Gnuplot::Plot.new(gp, cmd) do |plot|
38
+ opts.each do |key, value|
39
+ case value
40
+ when true
41
+ plot.send key
42
+ when false
43
+ gp << "unset #{key}\n"
44
+ else
45
+ plot.send key, value.to_s.gsub(/([\\])/, "\\\\\\1")
46
+ end
47
+ end
48
+
49
+ @_datasets.each do |ds|
50
+ plot.data << ds
51
+ end
52
+ end
53
+ gp.close
54
+ $_erbout << out.readlines.join("\n")
55
+
56
+ if not external.value.success?
57
+ errlines = err.readlines
58
+ raise "could not plot:\n" + errlines.join("\n")
59
+ end
60
+ end
61
+ end
62
+ $_erbout << "\\caption{#{title}}" if title
63
+ $_erbout << "\\label{#{label}}" if label
64
+ end
65
+ end
66
+
67
+ def splot *args, &block
68
+ opts = args.extract_options!
69
+ opts.cmd = "splot"
70
+ plot *args, opts, &block
71
+ end
72
+
73
+ def dataset *args
74
+ opts = args.extract_options!
75
+
76
+ data = args.shift
77
+ data_is_expr = !!data
78
+ if data
79
+ # simple function
80
+ ds = Gnuplot::DataSet.new data
81
+ else
82
+ # data
83
+ @_datastrings = []
84
+ yield
85
+
86
+ c = @_datastrings.first.count
87
+ data = (0...c).map do |i|
88
+ @_datastrings.map do |t|
89
+ case value = t[i]
90
+ when String
91
+ "\"#{value.to_s.gsub(/([\\"])/, "\\\\\\1")}\""
92
+ else
93
+ value.to_s
94
+ end
95
+ end
96
+ end
97
+
98
+ ds = Gnuplot::DataSet.new data
99
+ end
100
+
101
+ # check args
102
+ raise ArgumentError, "Unnecessary parameters: #{args}" unless args.empty?
103
+
104
+ # tweak args (syntax candy)
105
+ opts[:title] = nil unless data_is_expr or opts.has_key? :title
106
+ if opts.key? :title and not opts[:title]
107
+ opts.delete(:title)
108
+ opts[:notitle] = true
109
+ end
110
+
111
+ # send options
112
+ opts.each do |key, value|
113
+ case value
114
+ when true
115
+ ds.send key
116
+ else
117
+ ds.send :"#{key}=", value
118
+ end
119
+ end
120
+
121
+ @_datasets << ds
122
+
123
+ end
124
+
125
+ def datastring arg
126
+ @_datastrings << arg
127
+ end
128
+
129
+ def data *args
130
+ datastring args
131
+ end
132
+
133
+
134
+ # fitting
135
+ def fit expr, opts={}
136
+ raise "via: is a necessary parameter" if not opts[:via]
137
+ via = opts[:via]
138
+ vars = via.split(",")
139
+
140
+ using = opts[:using]
141
+
142
+ @_datasets = []
143
+
144
+ dataset do
145
+ yield
146
+ end
147
+
148
+ ds = @_datasets.first
149
+
150
+ errlines = []
151
+ result = {}
152
+
153
+ gnuplot = Gnuplot.gnuplot(true) or raise "gnuplot not found"
154
+ Open3.popen3(gnuplot) do |gp, out, err, external|
155
+ vars.each do |var|
156
+ gp << "#{var} = #{rand}\n"
157
+ end
158
+ gp <<<<-GP
159
+ fit #{expr} '-' #{"using " + using if using} via #{via}
160
+ GP
161
+ gp << ds.to_gplot
162
+ gp.close
163
+
164
+ errlines = err.readlines
165
+ errlines.each do |l|
166
+ if l =~ /\A([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*([0-9eE.+-]+)\s*\+\/-\s*([0-9eE.+-]+)/
167
+ result[$1.to_sym] = $2.to_f.pm($3.to_f)
168
+ end
169
+ end
170
+ end
171
+
172
+ vars.map do |v|
173
+ result[v.to_sym] or raise "could not fit:\n" + errlines.join("\n")
174
+ end
175
+ end
176
+
177
+