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 +7 -6
- data/Gemfile.lock +10 -7
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/texlab +0 -0
- data/bin/texlab-compile +18 -6
- data/lib/texlab/debug.rb +7 -0
- data/lib/texlab/figure.rb +32 -0
- data/lib/texlab/hash.rb +52 -0
- data/lib/texlab/latex.rb +22 -0
- data/lib/texlab/macro.rb +101 -0
- data/lib/texlab/math.rb +13 -0
- data/lib/texlab/plot.rb +177 -0
- data/lib/texlab/stats.rb +9 -0
- data/lib/texlab/table.rb +54 -0
- data/lib/texlab/tikz.rb +6 -0
- metadata +59 -44
- data/.document +0 -5
- data/.rspec +0 -1
- data/doc/readme.texlab +0 -284
- data/lib/texlab/boot.rb +0 -437
- data/texlab +0 -3
- data/texlab.gemspec +0 -92
- data/vim/texlab.vim +0 -136
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"
|
data/Gemfile.lock
CHANGED
@@ -17,7 +17,9 @@ GEM
|
|
17
17
|
log4r (1.1.10)
|
18
18
|
nio (0.2.5)
|
19
19
|
flt (>= 1.0.0)
|
20
|
-
|
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
|
-
|
50
|
-
|
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
|
+
0.2.0
|
data/bin/texlab
ADDED
Binary file
|
data/bin/texlab-compile
CHANGED
@@ -18,11 +18,11 @@ begin
|
|
18
18
|
infile = ARGV[0] || fail
|
19
19
|
outfile = ARGV[1] || infile.sub(/(\.texlab)?$/, ".tex")
|
20
20
|
|
21
|
-
|
21
|
+
content = nil
|
22
22
|
File.open infile do |f|
|
23
|
-
|
23
|
+
content = f.read
|
24
24
|
end
|
25
|
-
fail if !
|
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
|
-
|
36
|
-
|
37
|
-
|
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)
|
data/lib/texlab/debug.rb
ADDED
@@ -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
|
+
|
data/lib/texlab/hash.rb
ADDED
@@ -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
|
+
|
data/lib/texlab/latex.rb
ADDED
@@ -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
|
+
|
data/lib/texlab/macro.rb
ADDED
@@ -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
|
+
|
data/lib/texlab/math.rb
ADDED
data/lib/texlab/plot.rb
ADDED
@@ -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
|
+
|