texlab 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ require "rubygems"
2
+ require "rake4latex"
3
+
4
+ rule ".tex" => ".texlab" do |t|
5
+ sh %("#{File.expand_path(__FILE__+"/../../bin/texlab-compile")}" "#{t.source}" > "#{t.name}")
6
+ end
7
+
@@ -0,0 +1,20 @@
1
+ # To be sourced in VIM at startup
2
+
3
+ # Set up path
4
+ $: << (ENV["TEXLAB"]+"/lib") << (ENV["TEXLAB"]+"/lib/ruby")
5
+ Dir.glob(ENV["TEXLAB"]+"/gems/**/lib").each do |dir|
6
+ $: << dir
7
+ end
8
+
9
+
10
+ require "rubygems"
11
+ #require "irb"
12
+ require "yaml"
13
+ require "rake4latex"
14
+
15
+
16
+ task :compile do
17
+ Rake::Task[VIM::Buffer.current.name.sub(/\.[^.]+\z/, ".pdf")].invoke
18
+ end
19
+
20
+
@@ -0,0 +1,373 @@
1
+ # This is the boot file to be loaded before parsing a .texlab file
2
+ # encoding: ASCII-8bit
3
+ require "easystats"
4
+ require "plusminus"
5
+ require "to_latex"
6
+ require "gnuplot"
7
+ require "open3"
8
+
9
+ # tweak Array
10
+ class Array
11
+ def extract_options!
12
+ if last.is_a? Hash
13
+ pop
14
+ else
15
+ {}
16
+ end
17
+ end
18
+ end
19
+
20
+ # tweak Hash
21
+ class Hash
22
+ # Object-like behavior
23
+ def method_missing name, *args
24
+ name_string = name.to_s
25
+ case name_string[-1]
26
+ when "="
27
+ self[name_string[0..-2].to_sym] = args[0]
28
+ when "!"
29
+ self[name_string[0..-2].to_sym] = {}
30
+ when "?"
31
+ !! self[name_string[0..-2]]
32
+ else
33
+ self[name]
34
+ end
35
+ end
36
+ end
37
+
38
+ module Enumerable
39
+ # map-hash
40
+ def mash
41
+ res = {}
42
+ each do |*x|
43
+ k,v = yield(*x)
44
+ res[k] = v
45
+ end
46
+ res
47
+ end
48
+ end
49
+
50
+ class Hash
51
+ def mash! &block
52
+ replace mash(&block)
53
+ end
54
+ end
55
+
56
+
57
+ # Average method for array with uncertainty calculation
58
+ class Array
59
+ def average
60
+ m = mean
61
+ m.pm(Math.sqrt(m.delta**2 + (standard_deviation*3)**2))
62
+ end
63
+ end
64
+
65
+
66
+ # latex generation helper
67
+ require "texlab/texlabfile"
68
+
69
+ $_latexfile = TexlabFile.new $_erbout
70
+
71
+ def documentHeader *args
72
+ $_latexfile.documentHeader *args
73
+ end
74
+
75
+ def env *args
76
+ $_latexfile.env(*args){yield}
77
+ end
78
+
79
+ def puts string
80
+ $_erbout << string.to_latex << "\n"
81
+ end
82
+
83
+ # table generation
84
+ #
85
+
86
+ def table title, settings={}
87
+ @_table = {}
88
+ yield
89
+ entries = @_table
90
+
91
+ unless @_tables
92
+ $_latexfile.table(entries, title, settings)
93
+ else
94
+ @_tables << [entries, title, settings]
95
+ end
96
+ end
97
+
98
+ def column title
99
+ @_table_columns << (@_table_columns.last[title] || {})
100
+
101
+ result = yield
102
+ subcolumns = @_table_columns.pop
103
+
104
+ unless subcolumns.empty?
105
+ result = subcolumns
106
+ end
107
+
108
+ @_table_columns.last[title] = result
109
+ end
110
+
111
+ def row title
112
+ @_table_columns = [@_table[title] || {}]
113
+ yield
114
+ @_table[title] = @_table_columns.first
115
+ end
116
+
117
+ def tables *args
118
+ opts = args.extract_options!
119
+ caption = args.shift
120
+
121
+ @_tables = []
122
+ yield
123
+
124
+ $_latexfile.tables(@_tables, caption, opts)
125
+
126
+ @_tables = nil
127
+ end
128
+
129
+
130
+ # Figure generation
131
+ #
132
+
133
+ def figure *args
134
+ opts = args.extract_options!
135
+ caption = args.shift
136
+ format = opts[:width] ? "width=#{opts[:width]}" : opts[:format]
137
+ label = opts[:label]
138
+ filename = opts[:filename]
139
+ if @_figures
140
+ @_figures << Figure.new(format, filename, caption, label)
141
+ else
142
+ raise "not implemented"
143
+ end
144
+ end
145
+
146
+ def figures *args
147
+ opts = args.extract_options!
148
+ placement = opts.delete(:placement) || "htbp"
149
+ label = opts.delete(:label)
150
+ newPageThreshold = opts.delete(:newPageThreshold) || 29
151
+ caption = args.shift
152
+
153
+ @_figures = []
154
+ yield
155
+
156
+ $_latexfile.figures(caption, @_figures, newPageThreshold, placement, label)
157
+
158
+ @_figures = nil
159
+ end
160
+
161
+
162
+ # plotting
163
+ #
164
+
165
+ require "gnuplot"
166
+
167
+ # override to have "w+" mode
168
+ def Gnuplot.open( persist=true )
169
+ cmd = Gnuplot.gnuplot( persist ) or raise 'gnuplot not found'
170
+ IO::popen( cmd, "w+") { |io| yield io }
171
+ end
172
+
173
+ def plot *args
174
+ opts = args.extract_options!
175
+ title = args[0]
176
+
177
+ placement = opts.delete(:placement) || "htbp"
178
+ width = opts.delete(:width) || "17cm"
179
+ height = opts.delete(:height) || "10cm"
180
+ cmd = opts.delete(:cmd) || "plot"
181
+
182
+ env :figure, "[#{placement}]" do
183
+ env :center do
184
+ @_datasets = []
185
+ yield
186
+ @_datasets
187
+
188
+ gnuplot = Gnuplot.gnuplot(true) or raise "gnuplot not found"
189
+ Open3.popen3(gnuplot) do |gp, out, err, external|
190
+ gp <<<<-GP
191
+ set terminal latex size #{width}, #{height}
192
+ GP
193
+
194
+ Gnuplot::Plot.new(gp, cmd) do |plot|
195
+ opts.each do |key, value|
196
+ case value
197
+ when true
198
+ plot.send key
199
+ else
200
+ plot.send key, value.gsub(/([\\ ])/, "\\\\\\1")
201
+ end
202
+ end
203
+
204
+ @_datasets.each do |ds|
205
+ plot.data << ds
206
+ end
207
+ end
208
+ gp.close
209
+ $_erbout << out.readlines.join("\n")
210
+
211
+ if not external.value.success?
212
+ errlines = err.readlines
213
+ raise "could not plot:\n" + errlines.join("\n")
214
+ end
215
+ end
216
+ end
217
+ $_erbout << "\\caption{#{title}}" if title
218
+ end
219
+ end
220
+
221
+ def splot *args, &block
222
+ opts = args.extract_options!
223
+ opts.cmd = "splot"
224
+ plot *args, opts, &block
225
+ end
226
+
227
+ def dataset *args
228
+ opts = args.extract_options!
229
+
230
+ data = args.shift
231
+ data_is_expr = !!data
232
+ if data
233
+ # simple function
234
+ ds = Gnuplot::DataSet.new data
235
+ else
236
+ # data
237
+ @_datastrings = []
238
+ yield
239
+
240
+ c = @_datastrings.first.count
241
+ data = (0...c).map do |i|
242
+ @_datastrings.map{|t|t[i]}
243
+ end
244
+
245
+ ds = Gnuplot::DataSet.new data
246
+ end
247
+
248
+ # check args
249
+ raise ArgumentError, "Unnecessary parameters: #{args}" unless args.empty?
250
+
251
+ # tweak args (syntax candy)
252
+ opts[:title] = nil unless data_is_expr or opts.has_key? :title
253
+ if opts.key? :title and not opts[:title]
254
+ opts.delete(:title)
255
+ opts[:notitle] = true
256
+ end
257
+
258
+ # send options
259
+ opts.each do |key, value|
260
+ case value
261
+ when true
262
+ ds.send key
263
+ else
264
+ ds.send :"#{key}=", value
265
+ end
266
+ end
267
+
268
+ @_datasets << ds
269
+
270
+ end
271
+
272
+ def datastring arg
273
+ @_datastrings << arg
274
+ end
275
+
276
+ def data *args
277
+ datastring args
278
+ end
279
+
280
+
281
+ # fitting
282
+ def fit expr, opts={}
283
+ raise "via: is a necessary parameter" if not opts[:via]
284
+ via = opts[:via]
285
+ vars = via.split(",")
286
+
287
+ using = opts[:using]
288
+
289
+ @_datasets = []
290
+
291
+ dataset do
292
+ yield
293
+ end
294
+
295
+ ds = @_datasets.first
296
+
297
+ errlines = []
298
+ result = {}
299
+
300
+ gnuplot = Gnuplot.gnuplot(true) or raise "gnuplot not found"
301
+ Open3.popen3(gnuplot) do |gp, out, err, external|
302
+ vars.each do |var|
303
+ gp << "#{var} = #{rand}\n"
304
+ end
305
+ gp <<<<-GP
306
+ fit #{expr} '-' #{"using " + using if using} via #{via}
307
+ GP
308
+ gp << ds.to_gplot
309
+ gp.close
310
+
311
+ errlines = err.readlines
312
+ errlines.each do |l|
313
+ if l =~ /\A([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*([0-9eE.+-]+)\s*\+\/-\s*([0-9eE.+-]+)/
314
+ result[$1.to_sym] = $2.to_f.pm($3.to_f)
315
+ end
316
+ end
317
+ end
318
+
319
+ vars.map do |v|
320
+ result[v.to_sym] or raise "could not fit:\n" + errlines.join("\n")
321
+ end
322
+ end
323
+
324
+
325
+ # macros
326
+
327
+ $_macros={}
328
+
329
+ # a macro is available in tex (\asdf) and in ruby (:asdf.to_latex or $asdf). It will go to math
330
+ # mode
331
+ def macro hash
332
+ text_macro hash.mash{|key, value| [key, value.latex!.to_latex_math] }
333
+ end
334
+
335
+ # a text macro is available in tex (\asdf) and in ruby (:asdf). It will not be
336
+ # forced to math mode
337
+ def text_macro hash
338
+ hash.each do |key, value|
339
+ $_macros[key] = value
340
+ eval "$#{key} = '#{value.gsub("\\","\\\\").gsub("'", "\\'")}'"
341
+ $_erbout << "\\def\\#{key}{#{value}}"
342
+ end
343
+ end
344
+
345
+ class Symbol
346
+ # symbol's to_latex is the macro with the same name
347
+ def to_latex
348
+ $_macros[self] or raise "Undefined macro: #{self}"
349
+ end
350
+
351
+ def + str
352
+ "#{to_latex}#{str}".latex!.to_latex_math
353
+ end
354
+ end
355
+
356
+
357
+ # debug
358
+ def debug *args
359
+ args.each {|a| STDERR.puts a.inspect}
360
+ return *args
361
+ end
362
+
363
+ # include Math
364
+ include Math
365
+
366
+ # degree radian
367
+ def degrees x
368
+ x * 180.0 / Math::PI
369
+ end
370
+
371
+ def radians x
372
+ x / 180.0 * Math::PI
373
+ end
@@ -0,0 +1,164 @@
1
+ # encoding: ASCII-8bit
2
+ require "latex"
3
+
4
+ class TexlabFile < LatexFile
5
+ # create new instance.
6
+ # @param _erbout the string or file to write to
7
+ def initialize _erbout
8
+ # we don't call super
9
+
10
+ @_erbout = _erbout
11
+
12
+ # replay actions in super
13
+
14
+ @extras = {
15
+ :documentclass => :article,
16
+ :fontsize => "10pt"
17
+ }
18
+
19
+ #use defaults for unused entries:
20
+ @indent = 0 # indent lines in blocks
21
+
22
+ @usePackages = {
23
+ :inputenc=>:latin1,
24
+ :graphics=>:final,
25
+ :graphicx=>:pdftex,
26
+ :color=>:dvips,
27
+ :amsfonts=>true,
28
+ :subfigure=>true,
29
+ :lscape=>true,
30
+ :hyperref=>true,
31
+ :amsmath=>true,
32
+ :units=>true,
33
+ :float=>true,
34
+ :xcolor=>"table"
35
+ #:subfig=>["lofdepth", "lotdepth"]
36
+ }
37
+
38
+ @default_table_align = 'c'
39
+
40
+ @lastWasPrint = false
41
+ end
42
+
43
+ def puts string
44
+ lines = string.split("\n")
45
+ for line in lines
46
+ @indent -= 2 if line[0,5]=='\\end{' && @indent >= 2
47
+ if @lastWasPrint
48
+ @_erbout << line.latex! << "\n"
49
+ @lastWasPrint = false
50
+ else
51
+ @_erbout << (" " * @indent).latex! << line.latex! << "\n"
52
+ end
53
+ @indent += 2 if line[0,7]=='\\begin{'
54
+ end
55
+ end
56
+
57
+ def print string
58
+ @lastWasPrint = true
59
+ @indent -= 2 if string[/\\end/]
60
+ @indent += 2 if string[/\\begin/]
61
+ @_erbout << string.latex! << "\n"
62
+ end
63
+
64
+ def prettyPrintCell x
65
+ x.to_latex
66
+ end
67
+
68
+ def documentHeader extras={}
69
+ @extras.merge! extras
70
+ @usePackages.merge! extras[:usePackages] || {}
71
+
72
+ dcsettings = [@extras[:fontsize]]
73
+ dcsettings << "twocolumn" if @extras[:twocolumn]
74
+
75
+ puts "\\documentclass[#{dcsettings.join(",")}]{#{@extras[:documentclass]}}"
76
+
77
+ @usePackages.each do |package, settings|
78
+ case settings
79
+ when true then puts "\\usepackage{#{package}}"
80
+ when Array then puts "\\usepackage[#{settings.join(",")}]{#{package}}"
81
+ else puts "\\usepackage[#{settings}]{#{package}}"
82
+ end
83
+ end
84
+ puts "\\addtolength{\\oddsidemargin}{-3.5cm}"
85
+ puts "\\addtolength{\\textwidth}{7cm}"
86
+ puts "\\addtolength{\\topmargin}{-3cm}"
87
+ puts "\\addtolength{\\textheight}{5cm}"
88
+ puts "\\newcommand{\\hide}[1]{}"
89
+
90
+ puts "\\special{landscape}" if @extras[:landscape]
91
+
92
+ #puts "\\begin{document}"
93
+ puts "\\DeclareGraphicsExtensions{.jpg,.pdf,.mps,.png}"
94
+ end
95
+
96
+
97
+ def env(name, *args)
98
+ # overridden for compatibility with new Array#to_s
99
+ puts "\\begin{#{name}}#{args.join("")}"
100
+ yield if block_given?
101
+ puts "\\end{#{name}}"
102
+ end
103
+
104
+ def table entries, caption, args={}
105
+
106
+ # override defaults
107
+ args = {
108
+ :sort=> proc{0},
109
+ :header_hlines=>true
110
+ }.merge(args)
111
+
112
+
113
+ args[:rowTitle] = args[:rowTitle].to_latex if args[:rowTitle]
114
+
115
+ entries = convertKeysToLatex(entries)
116
+
117
+ super(entries, caption, args)
118
+ end
119
+
120
+ def plain_table entries, caption, opts={}
121
+ # capture output of table()
122
+ temp_erbout = @_erbout; @_erbout = ""
123
+ table(entries, caption, opts)
124
+ src = @_erbout; @_erbout = temp_erbout
125
+
126
+ src.sub!(/\A.*?\\begin{center}(.*)\\end{center}.*\z/m, '\1') or raise "internal error"
127
+ src.sub!(/\\caption{#{caption}}/, "") or raise "internal error"
128
+
129
+ end
130
+
131
+ def tables data, caption, opts={}
132
+ placement = opts.delete(:placement) || "htbp"
133
+ tableLandscape = opts.delete(:landscape)
134
+ tableFontSize = opts.delete(:fontSize) || @defaultTableFontSize
135
+ tableLabel = opts.delete(:label) || ""
136
+ tableCaption = caption
137
+
138
+ puts "\\begin{landscape}" if tableLandscape
139
+ puts "\n\\begin{table}[#{placement}]\n\\begin{center}"
140
+ puts "\\#{tableFontSize}" if tableFontSize
141
+
142
+ puts data.map { |args|
143
+ entries, caption, opts = *args
144
+ "\\subtable[#{caption}]{#{plain_table(*args)}}"
145
+ }.join("\\qquad")
146
+
147
+ puts "\\caption{#{tableCaption}}\n" if tableCaption
148
+ puts "\\label{tab:#{tableLabel}}" if tableLabel
149
+ puts "\\end{center}\n\\end{table}\n"
150
+ puts "\\end{landscape}" if @tableLandscape
151
+ end
152
+
153
+ private
154
+
155
+ def convertKeysToLatex value
156
+ case value
157
+ when Hash
158
+ value.mash{|k,v| [k.to_latex, convertKeysToLatex(v)] }
159
+ else
160
+ value
161
+ end
162
+ end
163
+
164
+ end