latex 0.1.1 → 0.1.2
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/ChangeLog +9 -0
- data/README +1 -1
- data/examples/latex.rb +558 -0
- data/examples/latextest.aux +19 -0
- data/examples/latextest.dvi +0 -0
- data/examples/latextest.log +197 -0
- data/examples/latextest.out +0 -0
- data/examples/latextest.tex +91 -0
- data/examples/latextest.tex~ +91 -0
- data/examples/saved_table.dat +1 -0
- data/examples/test-latex.rb +9 -5
- data/examples/test-latex.rb.~1.3.~ +40 -0
- data/lib/latex.rb +64 -22
- metadata +13 -3
data/ChangeLog
ADDED
data/README
CHANGED
data/examples/latex.rb
ADDED
@@ -0,0 +1,558 @@
|
|
1
|
+
# Copyright (c) 2004 Christian Bang <cbang AT web.de> and Frank Hutter
|
2
|
+
#
|
3
|
+
# Version 0.1.2
|
4
|
+
#
|
5
|
+
# All rights reserved. You can redistribute and/or modify it under the same terms as Ruby.
|
6
|
+
#
|
7
|
+
# This file provides a LatexFile class for Ruby.
|
8
|
+
|
9
|
+
class String
|
10
|
+
#Escapes underscores. Use this if you have a string that contains
|
11
|
+
#such but you don't mean the latex semantic of underscore.
|
12
|
+
def escape_
|
13
|
+
gsub(/_/,"\\_")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#examples: Figure.new("9cm", "image.eps", "Test image")
|
18
|
+
# Figure.new("angle=-90,width=9.5cm", "rotatedimage.eps", "Rotated image", "link01")
|
19
|
+
Figure = Struct.new(:format, :filename, :title, :label)
|
20
|
+
|
21
|
+
class FormatError < StandardError
|
22
|
+
end
|
23
|
+
|
24
|
+
# +LatexFile+ is a +File+ with special functions for easy generation of
|
25
|
+
# LaTeX code.
|
26
|
+
# Current mayor features are +table+ and +figures+ generation.
|
27
|
+
#
|
28
|
+
# You may want to quote underscores ('_') in some Latex code you create. For this use String.escape_ which
|
29
|
+
# is available with this file.
|
30
|
+
class LatexFile < File
|
31
|
+
Header = Struct.new(:name, :align, :children)
|
32
|
+
|
33
|
+
# the default table font size, default is nil which means the Latex default. See #table for possible values
|
34
|
+
attr_accessor :defaultTableFontSize
|
35
|
+
|
36
|
+
@@defaultUsePackages = %w([latin1]{inputenc} [final]{graphics} [pdftex]{graphicx} [dvips]{color}
|
37
|
+
{amsfonts} {subfigure} {lscape} {hyperref})
|
38
|
+
@@default_extras = {:fontsize => "10pt" }
|
39
|
+
attr_reader :extras
|
40
|
+
|
41
|
+
@default_table_align = 'c'
|
42
|
+
# The default table alignment is <tt>'c'</tt> but can be changed.
|
43
|
+
attr_accessor :default_table_align
|
44
|
+
|
45
|
+
# Open a new latex-file for writing.
|
46
|
+
# +extras+ is an optional hash that may contain the following flags
|
47
|
+
# <tt>:landscape</tt>:: turns all pages 90�
|
48
|
+
# <tt>:twocolumn</tt>:: the whole document has two columns
|
49
|
+
# <tt>extras[:fontsize]</tt>:: string containing the font size like "10pt"
|
50
|
+
# === Example:
|
51
|
+
# f = LatexFile.new("test.tex", :twocolumn => true, :fontsize => "11pt")
|
52
|
+
def initialize(filename, extras = nil)
|
53
|
+
super(filename,"w") # open a file for write access
|
54
|
+
@extras = extras || Hash.new
|
55
|
+
#use defaults for unused entries:
|
56
|
+
@@default_extras.each_key{|key| @extras[key] ||= @@default_extras[key] }
|
57
|
+
@indent = 0 # indent lines in blocks
|
58
|
+
|
59
|
+
@usePackages = @extras[:usePackages] || @@defaultUsePackages
|
60
|
+
|
61
|
+
writeDocumentHeader
|
62
|
+
@lastWasPrint = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def writeDocumentHeader
|
66
|
+
twocolumn = @extras[:twocolumn] ? ",twocolumn" : ""
|
67
|
+
landscape = @extras[:landscape] ? "\\special{landscape}" : ""
|
68
|
+
puts "\\documentclass[#{@extras[:fontsize]}#{twocolumn}]{article}"
|
69
|
+
@usePackages.each{|package| puts "\\usepackage#{package}"}
|
70
|
+
puts "\\addtolength{\\oddsidemargin}{-3.5cm}"
|
71
|
+
puts "\\addtolength{\\textwidth}{7cm}"
|
72
|
+
puts "\\addtolength{\\topmargin}{-3cm}"
|
73
|
+
puts "\\addtolength{\\textheight}{5cm}"
|
74
|
+
puts "\\newcommand{\\hide}[1]{}"
|
75
|
+
puts "#{landscape}"
|
76
|
+
puts "\\begin{document}"
|
77
|
+
puts "\\DeclareGraphicsExtensions{.jpg,.pdf,.mps,.png}"
|
78
|
+
end
|
79
|
+
|
80
|
+
#Write the latex-file footer and closes the file.
|
81
|
+
def close
|
82
|
+
puts "\\end{document}"
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
#Prints a string to the latex file and indents each line with respect to the
|
87
|
+
#current indentation level that depends on nested blocks.
|
88
|
+
def puts(string)
|
89
|
+
lines = string.split("\n")
|
90
|
+
for line in lines
|
91
|
+
@indent -= 2 if line[0,5]=='\\end{' && @indent >= 2
|
92
|
+
if @lastWasPrint
|
93
|
+
super(line)
|
94
|
+
@lastWasPrint = false
|
95
|
+
else
|
96
|
+
super(" " * @indent + line)
|
97
|
+
end
|
98
|
+
@indent += 2 if line[0,7]=='\\begin{'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#Insert spaces up to the current indentation level
|
103
|
+
def indent
|
104
|
+
print " "*@indent
|
105
|
+
end
|
106
|
+
|
107
|
+
#Other than puts, print does NOT indent the text. If you want to do so
|
108
|
+
#call +indent+ before.
|
109
|
+
def print(string)
|
110
|
+
@lastWasPrint = true
|
111
|
+
@indent -= 2 if string[/\\end/]
|
112
|
+
@indent += 2 if string[/\\begin/]
|
113
|
+
super(string)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Easy creation of environments.
|
117
|
+
# +name+:: the name of the environment.
|
118
|
+
# +args+:: an optional list of arguments that will be added after the environment definition.
|
119
|
+
# === Example:
|
120
|
+
# tex.env("table","[ht]") do
|
121
|
+
# tex.puts "<table body>"
|
122
|
+
# end
|
123
|
+
def env(name, *args)
|
124
|
+
puts "\\begin{#{name}}#{args}"
|
125
|
+
yield if block_given?
|
126
|
+
puts "\\end{#{name}}"
|
127
|
+
end
|
128
|
+
|
129
|
+
########### Figure generation #################################################
|
130
|
+
|
131
|
+
#Inserts one (ore more) figure block(s) with given figures as subfigures.
|
132
|
+
#+figures+::
|
133
|
+
# is an array consisting of +Figure+ instances.
|
134
|
+
# <tt>Figure = Struct.new(:format, :filename, :title)</tt>
|
135
|
+
# If +format+ begins with a number, it is assumed to be the width of the image.
|
136
|
+
# But you can also set e.g. <tt>"height=10.5cm,angle=-90"</tt>.
|
137
|
+
# For more info see the documentation to <tt>\includegraphics </tt> in the
|
138
|
+
# +graphicx+ package of _LaTeX_.
|
139
|
+
#+caption+:: is placed on each figure block that is created.
|
140
|
+
#+newPageThreshold+::
|
141
|
+
# is maximum the number of figures in a block.
|
142
|
+
# If more figures are given then a new block is created with the same
|
143
|
+
# caption.
|
144
|
+
#+placement+:: an optional placement for the figure blocks.
|
145
|
+
#+label+:: an optional label of the figures block ('fig:' is added)
|
146
|
+
# You can also use label="\\hypertarget{...}" if you like.
|
147
|
+
# Otherwise a \label{fig:...} is generated.
|
148
|
+
#=== Example:
|
149
|
+
# Experiment = Struct.new(:caption, :figures)
|
150
|
+
# thisExperiment = Experiment.new
|
151
|
+
# thisExperiment.caption = "Instance: #{instance}_1.dat".escape_
|
152
|
+
# thisExperiment.figures = [
|
153
|
+
# Figure.new("6.5cm", epsDirectory, "#{instance}-a.eps"),
|
154
|
+
# Figure.new("6.5cm", epsDirectory, "#{instance}-b.eps"),
|
155
|
+
# Figure.new("14cm", epsDirectory, "#{instance}-c.eps", "Title for image c)")
|
156
|
+
# ]
|
157
|
+
# tex.figures(thisExperiment.caption, thisExperiment.figures, 3)
|
158
|
+
def figures(caption, figures, newPageThreshold, placement = "htbp", label = nil)
|
159
|
+
lastimagepath = ""
|
160
|
+
figures.each_with_index do |figure,i|
|
161
|
+
figure.title = "[{#{figure.title}}]" unless figure.title == "" or figure.title == nil
|
162
|
+
if i % newPageThreshold == 0
|
163
|
+
puts "\\begin{figure}[#{placement}]"
|
164
|
+
puts "\\caption{#{caption}}"
|
165
|
+
if label
|
166
|
+
if label[0,1]=='\\' #you can use \hypertarget here
|
167
|
+
puts label
|
168
|
+
else
|
169
|
+
puts "\\label{fig:#{label}}"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
puts "\\centering"
|
173
|
+
end
|
174
|
+
imagepath = File.dirname(figure.filename)
|
175
|
+
puts "\\graphicspath{{#{imagepath}}}" if imagepath != "" and imagepath != "." and lastimagepath != imagepath
|
176
|
+
lastimagepath = imagepath
|
177
|
+
figure.format = "width="+figure.format if figure.format =~ /^[0-9\.]/
|
178
|
+
if figure.label
|
179
|
+
if figure.label[0,1]=='\\'
|
180
|
+
puts figure.label
|
181
|
+
else
|
182
|
+
puts "\\label{#{figure.label}}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
puts "\\subfigure#{figure.title}{\\includegraphics[#{figure.format}]{#{File.basename(figure.filename)}}}"
|
186
|
+
if i % newPageThreshold == newPageThreshold-1 or figure == figures[-1]
|
187
|
+
puts "\\end{figure}"
|
188
|
+
puts "\\clearpage"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
########### Table Generation functions #################################################
|
194
|
+
|
195
|
+
#This is a helper function for table generation.
|
196
|
+
#It computes the number of columns that are leaves of the tree with root +header_node+.
|
197
|
+
#You can also say, it computes the number of leaves of the given tree.
|
198
|
+
#+header+:: is of type +Header+: (name, children)
|
199
|
+
def getNumColsOfHeader(header)
|
200
|
+
header.children.inject(0) do |numChildren, child|
|
201
|
+
numChildren + (child.children ? getNumColsOfHeader(child) : 1)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
private :getNumColsOfHeader
|
205
|
+
|
206
|
+
#+list+:: must contain hashes as values for all keys.
|
207
|
+
#These child hashes will be joined/merged to one big hash.
|
208
|
+
#The actual leafes will be ignored so that only the header remain.
|
209
|
+
def getHeaderMergedHash(list)
|
210
|
+
merged = {}
|
211
|
+
toMerge = Hash.new {|h,k| h[k] = [] }
|
212
|
+
nothingToMerge = true
|
213
|
+
for entry in list
|
214
|
+
if entry.class == Hash
|
215
|
+
entry.each_pair do |key,value|
|
216
|
+
toMerge[key] << value
|
217
|
+
end
|
218
|
+
nothingToMerge = false
|
219
|
+
end
|
220
|
+
end
|
221
|
+
#return list if nothingToMerge
|
222
|
+
return nil if nothingToMerge #return only header tree without any data
|
223
|
+
toMerge.each_pair do |key,value|
|
224
|
+
if key.class == Symbol
|
225
|
+
merged[key] = value unless merged[key]
|
226
|
+
else
|
227
|
+
merged[key] = getHeaderMergedHash(value)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
return merged
|
231
|
+
end
|
232
|
+
private :getHeaderMergedHash
|
233
|
+
|
234
|
+
@@default_sort = Proc.new { |x,y| x <=> y }
|
235
|
+
|
236
|
+
#Given a list of hashes, initially a hash-list of each row it
|
237
|
+
#returns a sorted tree representation - a headerList.
|
238
|
+
#+sort_block+:: a block that compares header names
|
239
|
+
#side effects::
|
240
|
+
# deletes :align entries from the +hash+ and transforms
|
241
|
+
# hash[:value] = value hashes to normal entries
|
242
|
+
def hash2HeaderList(hash, sort_block = @@default_sort)
|
243
|
+
headerList = []
|
244
|
+
entries = hash.to_a
|
245
|
+
entries.sort! do |x,y| sort_block.call(x[0],y[0])
|
246
|
+
end
|
247
|
+
for key,value in entries
|
248
|
+
if value.class == Hash
|
249
|
+
align = value.delete(:align) || @default_table_align
|
250
|
+
align = align[0] if align.class == Array
|
251
|
+
if value[:value] #transform hashes with :value keys to normal entries
|
252
|
+
hash[key] = value = value[:value]
|
253
|
+
headerList << Header.new(key,align,nil)
|
254
|
+
else
|
255
|
+
subtree = hash2HeaderList(value, sort_block)
|
256
|
+
headerList << Header.new(key,align,subtree)
|
257
|
+
end
|
258
|
+
else
|
259
|
+
headerList << Header.new(key,@default_table_align,nil)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
return headerList
|
263
|
+
end
|
264
|
+
private :hash2HeaderList
|
265
|
+
|
266
|
+
#Performes a breath first traversal of the given tree
|
267
|
+
#+headerList+:: a list of header nodes of class +Header+.
|
268
|
+
#Returns a list of headers (together with the number of columns they use) for each header line needed.
|
269
|
+
#example: <tt>[['B',['C',['F','G']], ['D',['H','I']],['E']]]</tt> =>
|
270
|
+
#<tt>[['B'], ['C','D','E'], ['F','G','H','I']]</tt> and with their column width information
|
271
|
+
#if the (sub)header covers more than one column =>
|
272
|
+
#<tt>[[['B',5]], [['C',2],['D',2],'E'], ['F','G','H','I']]</tt>
|
273
|
+
#The length of the returned list is the number of rows needed for the headers.
|
274
|
+
def getHeaderLines(headerList) #:nodoc:
|
275
|
+
line = []
|
276
|
+
nextLevel = [] # collects the children nodes of all nodes processed (BFS)
|
277
|
+
hasChildrenInNextLevel = false
|
278
|
+
for header in headerList
|
279
|
+
if header.is_a?(Array) and header[0] == "~"
|
280
|
+
line << header
|
281
|
+
nextLevel << header # insert this for lines below this
|
282
|
+
elsif header.children == nil # leaf node ?
|
283
|
+
line << [header.name, header.align]
|
284
|
+
nextLevel << ["~",header.align] # insert this for lines below this
|
285
|
+
else
|
286
|
+
line << [header.name, header.align, getNumColsOfHeader(header)]
|
287
|
+
nextLevel += header.children
|
288
|
+
hasChildrenInNextLevel = true
|
289
|
+
end
|
290
|
+
end
|
291
|
+
return hasChildrenInNextLevel ? [line] + getHeaderLines(nextLevel) : [line]
|
292
|
+
end
|
293
|
+
private :getHeaderLines
|
294
|
+
|
295
|
+
#Returns a list of paths to all leaf nodes of the given header-tree list. The Leaf nodes are the final
|
296
|
+
#columns. In order to compute the table value at (row,col) we want to access only the leaf cols and not
|
297
|
+
#the header columns.
|
298
|
+
#Example: let <tt>[['B',['C',['F','G']], ['D',['H','I']],['E']]]</tt> be our
|
299
|
+
#header tree. The real columns are F,G,H,I,E. In order to access e.g. 'I' we need to know the path [B,D,I].
|
300
|
+
#<tt> => [["B", "C", "F"], ["B", "C", "G"], ["B", "D", "H"], ["B", "D", "I"], ["B", "E"]]</tt>
|
301
|
+
def getLeafColumns(headerList, path_prefix = nil) #:nodoc:
|
302
|
+
paths = []
|
303
|
+
path_prefix = path_prefix || []
|
304
|
+
for header in headerList
|
305
|
+
if header.children
|
306
|
+
paths += getLeafColumns(header.children, path_prefix + [header.name])
|
307
|
+
else #header is not of class Header but a leaf header (string)
|
308
|
+
paths << path_prefix + [header.name]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
return paths
|
312
|
+
end
|
313
|
+
private :getLeafColumns
|
314
|
+
|
315
|
+
#Pretty print output of table entries. If an entry is an array then
|
316
|
+
#+prettyPrintCell+ will be called for every table item. You can override this
|
317
|
+
#function if you like a special behaviour.
|
318
|
+
def prettyPrintCell(x)
|
319
|
+
if x.kind_of?(Integer)
|
320
|
+
x = "%d" % x
|
321
|
+
elsif x.kind_of?(Float)
|
322
|
+
x = "%.2f" % x
|
323
|
+
else
|
324
|
+
x = x.to_s
|
325
|
+
end
|
326
|
+
raise(FormatError, "Invalid format: #{x.inspect} contains % that is not sufficiently quoted for latex.", caller) if x =~ /[^\\]%|^%/
|
327
|
+
x.gsub(/1.#J|Infinity|1.#INF0/, "$\\infty$")
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
# Generates a table with the specified entries.
|
332
|
+
# +entries+::
|
333
|
+
# the row-hash where the keys are the row names which are printed in the first column.
|
334
|
+
# The <tt>entries[row]</tt> is a column-hash. Its keys are the column names.
|
335
|
+
# A column-hash value can be either
|
336
|
+
# - an object (with a <tt>to_s</tt> method) that are printed
|
337
|
+
# - an array containing objects. In this case a new row is added for each array entry
|
338
|
+
# - a hash in which case the keys of this hash are subheaders.
|
339
|
+
# +caption+:: the caption of the table.
|
340
|
+
# +args+::
|
341
|
+
# is either a hash or further arguments
|
342
|
+
# Case 1::
|
343
|
+
# The hash is indexed by one of the argument symbols below, the values correspond to the
|
344
|
+
# argument values you want to set to the corresponding argument.
|
345
|
+
# Instead of symbols you can also use strings, e.g. <tt>:label</tt> or <tt>"label"<</tt>
|
346
|
+
# Case 2::
|
347
|
+
# args are some more arguments. Then they will be interpreted as the following arguments
|
348
|
+
# in the same order. You need not use all of them.
|
349
|
+
# <tt>:rowTitle</tt>:: the title of the first column that contains the row names.
|
350
|
+
# <tt>:label</tt>:: the label of the table. The "tab:" prefix is added automatically .
|
351
|
+
# <tt>:newTableThreshold</tt>::
|
352
|
+
# maximum number of lines per table. If reached then a new table will be created.
|
353
|
+
# Zero means no restriction. An empty row (entries[name] == nil) also toggles a new table.
|
354
|
+
# <tt>:placement</tt>:: the LaTeX placement for the table. See the LaTeX documentation for details.
|
355
|
+
# <tt>:empty</tt>:: a string that will be put in those fields that have no value.
|
356
|
+
# <tt>:sort</tt>::
|
357
|
+
# is used to sort the rows and columns. Default is alphabetical ordering.
|
358
|
+
# See the example below to get an idea on how to implement customized ordering.
|
359
|
+
# <tt>:landscape</tt>:: if true, it will turn the page by 90 degree.
|
360
|
+
# <tt>:fontSize</tt>::
|
361
|
+
# A latex fontsize modifier like tiny, scriptsize, footnotesize, small,
|
362
|
+
# normalsize (default), large, Large, LARGE, huge, Huge.
|
363
|
+
# <tt>:header_hlines</tt>::
|
364
|
+
# If +true+, then horizontal lines between headers of different depths are drawn.
|
365
|
+
# Default is +false+ (no horizontal header lines).
|
366
|
+
# <tt>:rowAlign</tt>::
|
367
|
+
# Alignment of the column containing the row names. Values are 'r','c','l'.
|
368
|
+
# See also the attribute +default_table_align+.
|
369
|
+
#
|
370
|
+
# === Example:
|
371
|
+
# require 'latex'
|
372
|
+
# tex = LatexFile.new("table.tex")
|
373
|
+
# rows["row1"] = {'Main Header'=>
|
374
|
+
# {'A'=> '5',
|
375
|
+
# 'B'=> {'D'=>'1','E'=>'2'},
|
376
|
+
# 'C'=> {'F'=>'3','G'=>'4'}},
|
377
|
+
# 'X'=> [1,3,55.55]}
|
378
|
+
# tex.table(rows,"table with hierarchical headers",:rowTitle=>"Instance")
|
379
|
+
# tableSort = Proc.new do |x,y|
|
380
|
+
# order = %w{A X B C D E}
|
381
|
+
# (order.index(x) && order.index(y)) ? order.index(x) <=> order.index(y) : x <=> y
|
382
|
+
# end
|
383
|
+
# tex.table(rows,"special ordering", :rowTitle=>"Instance", :sort => tableSort)
|
384
|
+
#
|
385
|
+
# === Column alignment:
|
386
|
+
# By default alignment is centered. You can change this for all columns using the attribute
|
387
|
+
# +default_table_align+.
|
388
|
+
# The alignment can also be changed for each column separately:
|
389
|
+
# Headers can be aligned as demonstrated in the following examples:
|
390
|
+
# rows['1'] = {'Main Header' => {:align => 'l', 'A' => '5','B' => '6'}}
|
391
|
+
# This affects only the header and not the columns, because this is no final column header.
|
392
|
+
# Subheader and so the final columns themselves are aligned as follows:
|
393
|
+
# rows['1'] = {'Main Header' => {'A' => {:value => '5', :align => 'l'} ,'B' => '6'}}
|
394
|
+
# rows['2'] = {'Main Header' => {'A' => '77','B' => '8'}}
|
395
|
+
# As you can see it is only needed to define the alignment of a column once. It can be done
|
396
|
+
# as often as you like but only one alignment definition is used.
|
397
|
+
def table(entries, caption, *args)
|
398
|
+
tableValidArgs = [:rowTitle, :label, :newTableThreshold, :placement, :empty, :sort, :landscape, :fontSize, :grouping, :header_hlines, :rowAlign]
|
399
|
+
# raise(ArgumentError,"Too many arguments Latex.table", caller) unless args.length <= 1
|
400
|
+
hash = {}
|
401
|
+
args = if args[0].kind_of?(Hash)
|
402
|
+
args[0].each_pair{|key,value| hash[key.to_sym]= value}; hash # allow string keys also
|
403
|
+
else
|
404
|
+
args.each_with_index{|arg,i| hash[tableValidArgs[i].to_sym] = arg}; hash
|
405
|
+
end
|
406
|
+
args.each_key{|key| raise(ArgumentError,"Invalid argument: #{key} for Latex.table", caller) unless tableValidArgs.include?(key)}
|
407
|
+
@tableCaption = caption
|
408
|
+
rowTitle = args[:rowTitle] || ""
|
409
|
+
@tableLabel = args[:label] || ""
|
410
|
+
newTableThreshold = args[:newTableThreshold] || (args[:landscape] ? 38 : 60)
|
411
|
+
placement = args[:placement] || "htbp"
|
412
|
+
empty = args[:empty] ||"-"
|
413
|
+
sort_block = args[:sort] ||@@default_sort
|
414
|
+
grouping = args[:grouping] || [entries.keys]
|
415
|
+
@tableLandscape = args[:landscape]
|
416
|
+
@tableFontSize = args[:fontSize] || @defaultTableFontSize
|
417
|
+
@header_hlines = args[:header_hlines]
|
418
|
+
@rowAlign = args[:rowAlign] || @default_table_align
|
419
|
+
|
420
|
+
#access an element in the table which is located in row _rowName_ and in a column
|
421
|
+
#that is defined by a _path_ through the headers that can be obtained with
|
422
|
+
#the function +getLeafColumns+.
|
423
|
+
def accessElement(entries, rowName, path) #:nodoc:
|
424
|
+
entry = entries[rowName]
|
425
|
+
for key in path
|
426
|
+
entry = entry[key]
|
427
|
+
return [] unless entry
|
428
|
+
end
|
429
|
+
entry = entry[:value] if entry.is_a?(Hash)
|
430
|
+
return entry.is_a?(Array) ? entry : [entry]
|
431
|
+
end
|
432
|
+
|
433
|
+
def printTableHeader(placement, headerLines, leafColumns, rowTitle) #:nodoc:
|
434
|
+
puts "\\begin{landscape}" if @tableLandscape
|
435
|
+
puts "\n\\begin{table}[#{placement}]\n\\begin{center}"
|
436
|
+
puts "\\#{@tableFontSize}" if @tableFontSize
|
437
|
+
print " "*@indent + "\\begin{tabular}{|"
|
438
|
+
# print the alignment {c,r,l} for each leaf column
|
439
|
+
print "#{@rowAlign}|" # the first column with the row names
|
440
|
+
headerLines[-1].each {|headerName, colAlign| print "#{colAlign}|" }
|
441
|
+
puts "}"
|
442
|
+
currentHeaderRowNumber = 0
|
443
|
+
puts "\\hline"
|
444
|
+
for headerLine in headerLines
|
445
|
+
print " "*@indent
|
446
|
+
if headerLine == headerLines[-1]
|
447
|
+
print "#{rowTitle} & " # row name title comes in the last header line
|
448
|
+
else
|
449
|
+
print "~ & "
|
450
|
+
end
|
451
|
+
currentColumn = 2
|
452
|
+
cline = ""
|
453
|
+
print headerLine.map {|headerName, align, columns|
|
454
|
+
raise(FormatError, "Invalid format: #{headerName.inspect} contains % that is not sufficiently quoted for latex.", caller) if headerName =~ /[^\\]%|^%/
|
455
|
+
if columns
|
456
|
+
cline += "\\cline{#{currentColumn}-#{(currentColumn+=columns)-1}}" if @header_hlines
|
457
|
+
"\\multicolumn{#{columns}}{#{align}|}{#{headerName}}"
|
458
|
+
else
|
459
|
+
currentColumn += 1
|
460
|
+
if currentHeaderRowNumber == headerLines.length-1 || headerName == "~"
|
461
|
+
headerName
|
462
|
+
else
|
463
|
+
delta = "%.1f" % ((headerLines.length-currentHeaderRowNumber-1).to_f)
|
464
|
+
"\\raisebox{-#{delta}\\totalheight}[1ex][1ex]{#{headerName}}"
|
465
|
+
end
|
466
|
+
end
|
467
|
+
}.join(" & ")
|
468
|
+
puts "\\\\"+cline
|
469
|
+
currentHeaderRowNumber += 1
|
470
|
+
end
|
471
|
+
puts "\\hline\\hline"
|
472
|
+
end
|
473
|
+
|
474
|
+
def printTableFooter #:nodoc:
|
475
|
+
puts "\\end{tabular}"
|
476
|
+
puts "\\caption{#{@tableCaption}}\n\\label{tab:#@tableLabel}"
|
477
|
+
puts "\\end{center}\n\\end{table}\n"
|
478
|
+
puts "\\end{landscape}" if @tableLandscape
|
479
|
+
end
|
480
|
+
|
481
|
+
#====== Generate header
|
482
|
+
headerList = hash2HeaderList(getHeaderMergedHash(entries.values), sort_block)
|
483
|
+
headerLines = getHeaderLines(headerList)
|
484
|
+
leafColumns = getLeafColumns(headerList)
|
485
|
+
printTableHeader(placement, headerLines, leafColumns, rowTitle)
|
486
|
+
|
487
|
+
currentRow = 0
|
488
|
+
for row_names in grouping
|
489
|
+
#======= Compute table break for multiple groupings.
|
490
|
+
new_lines = 0
|
491
|
+
for row_name in row_names
|
492
|
+
max_lines_per_entry = 1
|
493
|
+
for col_header in leafColumns
|
494
|
+
max_lines_per_entry = [max_lines_per_entry, accessElement(entries,row_name,col_header).length].max
|
495
|
+
end
|
496
|
+
new_lines += max_lines_per_entry
|
497
|
+
end
|
498
|
+
|
499
|
+
if (currentRow > 0 and currentRow + new_lines >= newTableThreshold)
|
500
|
+
currentRow = 0
|
501
|
+
printTableFooter # close last table
|
502
|
+
printTableHeader(placement, headerLines, leafColumns, rowTitle) # open new table
|
503
|
+
else
|
504
|
+
unless currentRow == 0
|
505
|
+
puts "\\hline" unless row_names == []
|
506
|
+
currentRow += 0.5
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
row_names.sort! &sort_block
|
511
|
+
#====== Generate entries.
|
512
|
+
for row_name in row_names
|
513
|
+
if (newTableThreshold > 0 and currentRow >= newTableThreshold)
|
514
|
+
currentRow = 0
|
515
|
+
printTableFooter # close last table
|
516
|
+
printTableHeader(placement, headerLines, leafColumns, rowTitle) # open new table
|
517
|
+
end
|
518
|
+
max_lines_per_entry = 1
|
519
|
+
for col_header in leafColumns
|
520
|
+
max_lines_per_entry = [max_lines_per_entry, accessElement(entries,row_name,col_header).length].max
|
521
|
+
end
|
522
|
+
|
523
|
+
for i in 0...max_lines_per_entry
|
524
|
+
#print row-name
|
525
|
+
print " "*@indent
|
526
|
+
output = (i==0 ? row_name.to_s.gsub(/_/,"\\_") : "~")
|
527
|
+
delta = "%.1f" % ((max_lines_per_entry-1).to_f)
|
528
|
+
output = "\\raisebox{-#{delta}\\totalheight}[1ex][1ex]{#{output}}" if max_lines_per_entry > 1
|
529
|
+
print output
|
530
|
+
|
531
|
+
#print the other columns
|
532
|
+
for col_header in leafColumns
|
533
|
+
entry = accessElement(entries,row_name,col_header)
|
534
|
+
if entry[i]
|
535
|
+
output = prettyPrintCell(entry[i])
|
536
|
+
delta = "%.1f" % (max_lines_per_entry-entry.length).to_f
|
537
|
+
else
|
538
|
+
output = (i==0 ? empty : "~")
|
539
|
+
delta = max_lines_per_entry
|
540
|
+
end
|
541
|
+
#Center the entries vertically in the cell. Out-comment this if you don't like that.
|
542
|
+
if entry.length != max_lines_per_entry# && entry.length > 0
|
543
|
+
output = "\\raisebox{-#{delta}\\totalheight}[1ex][1ex]{#{output}}" unless output == "~"
|
544
|
+
end
|
545
|
+
print " & " + output
|
546
|
+
end
|
547
|
+
puts "\\\\"
|
548
|
+
end
|
549
|
+
puts "\\hline"
|
550
|
+
currentRow += max_lines_per_entry
|
551
|
+
end
|
552
|
+
end
|
553
|
+
#====== Generate footer.
|
554
|
+
printTableFooter
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
\relax
|
2
|
+
\ifx\hyper@anchor\@undefined
|
3
|
+
\global \let \oldcontentsline\contentsline
|
4
|
+
\gdef \contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}}
|
5
|
+
\global \let \oldnewlabel\newlabel
|
6
|
+
\gdef \newlabel#1#2{\newlabelxx{#1}#2}
|
7
|
+
\gdef \newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}}
|
8
|
+
\AtEndDocument{\let \contentsline\oldcontentsline
|
9
|
+
\let \newlabel\oldnewlabel}
|
10
|
+
\else
|
11
|
+
\global \let \hyper@last\relax
|
12
|
+
\fi
|
13
|
+
|
14
|
+
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces common table}}{1}{table.1}}
|
15
|
+
\newlabel{tab:}{{1}{1}{\relax }{table.1}{}}
|
16
|
+
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces hierarchical headers}}{1}{table.2}}
|
17
|
+
\newlabel{tab:}{{2}{1}{\relax }{table.2}{}}
|
18
|
+
\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces both tables}}{2}{table.3}}
|
19
|
+
\newlabel{tab:}{{3}{2}{\relax }{table.3}{}}
|
Binary file
|
@@ -0,0 +1,197 @@
|
|
1
|
+
This is TeXk, Version 3.14159 (Web2C 7.4.5) (format=latex 2003.11.5) 12 OCT 2004 15:46
|
2
|
+
Source specials enabled.
|
3
|
+
**\nonstopmode\input{latextest.tex}
|
4
|
+
(./latextest.tex (/usr/share/texmf/tex/latex/base/article.cls
|
5
|
+
Document Class: article 2001/04/21 v1.4e Standard LaTeX document class
|
6
|
+
(/usr/share/texmf/tex/latex/base/size10.clo
|
7
|
+
File: size10.clo 2001/04/21 v1.4e Standard LaTeX file (size option)
|
8
|
+
)
|
9
|
+
\c@part=\count79
|
10
|
+
\c@section=\count80
|
11
|
+
\c@subsection=\count81
|
12
|
+
\c@subsubsection=\count82
|
13
|
+
\c@paragraph=\count83
|
14
|
+
\c@subparagraph=\count84
|
15
|
+
\c@figure=\count85
|
16
|
+
\c@table=\count86
|
17
|
+
\abovecaptionskip=\skip41
|
18
|
+
\belowcaptionskip=\skip42
|
19
|
+
\bibindent=\dimen102
|
20
|
+
)
|
21
|
+
(/usr/share/texmf/tex/latex/base/inputenc.sty
|
22
|
+
Package: inputenc 2001/07/10 v0.99a Input encoding file
|
23
|
+
|
24
|
+
(/usr/share/texmf/tex/latex/base/latin1.def
|
25
|
+
File: latin1.def 2001/07/10 v0.99a Input encoding file
|
26
|
+
))
|
27
|
+
(/usr/share/texmf/tex/latex/graphics/graphics.sty
|
28
|
+
Package: graphics 2001/07/07 v1.0n Standard LaTeX Graphics (DPC,SPQR)
|
29
|
+
|
30
|
+
(/usr/share/texmf/tex/latex/graphics/trig.sty
|
31
|
+
Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
|
32
|
+
)
|
33
|
+
(/usr/share/texmf/tex/latex/config/graphics.cfg
|
34
|
+
File: graphics.cfg 2001/08/31 v1.1 graphics configuration of teTeX/TeXLive
|
35
|
+
)
|
36
|
+
Package graphics Info: Driver file: dvips.def on input line 80.
|
37
|
+
|
38
|
+
(/usr/share/texmf/tex/latex/graphics/dvips.def
|
39
|
+
File: dvips.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
|
40
|
+
))
|
41
|
+
(/usr/share/texmf/tex/latex/graphics/graphicx.sty
|
42
|
+
Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
|
43
|
+
|
44
|
+
(/usr/share/texmf/tex/latex/graphics/keyval.sty
|
45
|
+
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
|
46
|
+
\KV@toks@=\toks14
|
47
|
+
)
|
48
|
+
\Gin@req@height=\dimen103
|
49
|
+
\Gin@req@width=\dimen104
|
50
|
+
)
|
51
|
+
(/usr/share/texmf/tex/latex/graphics/color.sty
|
52
|
+
Package: color 1999/02/16 v1.0i Standard LaTeX Color (DPC)
|
53
|
+
|
54
|
+
(/usr/share/texmf/tex/latex/config/color.cfg
|
55
|
+
File: color.cfg 2001/08/31 v1.1 color configuration of teTeX/TeXLive
|
56
|
+
)
|
57
|
+
Package color Info: Driver file: dvips.def on input line 125.
|
58
|
+
|
59
|
+
(/usr/share/texmf/tex/latex/graphics/dvipsnam.def
|
60
|
+
File: dvipsnam.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
|
61
|
+
))
|
62
|
+
(/usr/share/texmf/tex/latex/amsfonts/amsfonts.sty
|
63
|
+
Package: amsfonts 2001/10/25 v2.2f
|
64
|
+
\@emptytoks=\toks15
|
65
|
+
\symAMSa=\mathgroup4
|
66
|
+
\symAMSb=\mathgroup5
|
67
|
+
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
|
68
|
+
(Font) U/euf/m/n --> U/euf/b/n on input line 132.
|
69
|
+
)
|
70
|
+
(/usr/share/texmf/tex/latex/misc/subfigure.sty
|
71
|
+
Package: subfigure 2002/07/30 v2.1.4 subfigure package
|
72
|
+
\subfigtopskip=\skip43
|
73
|
+
\subfigcapskip=\skip44
|
74
|
+
\subfigcaptopadj=\dimen105
|
75
|
+
\subfigbottomskip=\skip45
|
76
|
+
\subfigcapmargin=\dimen106
|
77
|
+
\subfiglabelskip=\skip46
|
78
|
+
\c@subfigure=\count87
|
79
|
+
\c@lofdepth=\count88
|
80
|
+
\c@subtable=\count89
|
81
|
+
\c@lotdepth=\count90
|
82
|
+
\subfig@top=\skip47
|
83
|
+
\subfig@bottom=\skip48
|
84
|
+
)
|
85
|
+
(/usr/share/texmf/tex/latex/graphics/lscape.sty
|
86
|
+
Package: lscape 2000/10/22 v3.01 Landscape Pages (DPC)
|
87
|
+
)
|
88
|
+
(/usr/share/texmf/tex/latex/hyperref/hyperref.sty
|
89
|
+
Package: hyperref 2003/01/22 v6.73n Hypertext links for LaTeX
|
90
|
+
\@linkdim=\dimen107
|
91
|
+
\Hy@linkcounter=\count91
|
92
|
+
\Hy@pagecounter=\count92
|
93
|
+
|
94
|
+
(/usr/share/texmf/tex/latex/hyperref/pd1enc.def
|
95
|
+
File: pd1enc.def 2003/01/22 v6.73n Hyperref: PDFDocEncoding definition (HO)
|
96
|
+
)
|
97
|
+
(/usr/share/texmf/tex/latex/config/hyperref.cfg
|
98
|
+
File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive and teTeX
|
99
|
+
)
|
100
|
+
Package hyperref Info: Hyper figures OFF on input line 1792.
|
101
|
+
Package hyperref Info: Link nesting OFF on input line 1797.
|
102
|
+
Package hyperref Info: Hyper index ON on input line 1800.
|
103
|
+
Package hyperref Info: Plain pages ON on input line 1805.
|
104
|
+
Package hyperref Info: Backreferencing OFF on input line 1812.
|
105
|
+
|
106
|
+
Implicit mode ON; LaTeX internals redefined
|
107
|
+
Package hyperref Info: Bookmarks ON on input line 1916.
|
108
|
+
(/usr/share/texmf/tex/latex/html/url.sty
|
109
|
+
Package: url 1999/03/02 ver 1.4 Verb mode for urls, email addresses, and file
|
110
|
+
names
|
111
|
+
)
|
112
|
+
LaTeX Info: Redefining \url on input line 2055.
|
113
|
+
\Fld@menulength=\count93
|
114
|
+
\Field@Width=\dimen108
|
115
|
+
\Fld@charsize=\dimen109
|
116
|
+
\Choice@toks=\toks16
|
117
|
+
\Field@toks=\toks17
|
118
|
+
Package hyperref Info: Hyper figures OFF on input line 2513.
|
119
|
+
Package hyperref Info: Link nesting OFF on input line 2518.
|
120
|
+
Package hyperref Info: Hyper index ON on input line 2521.
|
121
|
+
Package hyperref Info: backreferencing OFF on input line 2528.
|
122
|
+
Package hyperref Info: Link coloring OFF on input line 2533.
|
123
|
+
\c@Item=\count94
|
124
|
+
\c@Hfootnote=\count95
|
125
|
+
)
|
126
|
+
*hyperref using default driver hdvips*
|
127
|
+
(/usr/share/texmf/tex/latex/hyperref/hdvips.def
|
128
|
+
File: hdvips.def 2003/01/22 v6.73n Hyperref driver for dvips
|
129
|
+
|
130
|
+
(/usr/share/texmf/tex/latex/hyperref/pdfmark.def
|
131
|
+
File: pdfmark.def 2003/01/22 v6.73n Hyperref definitions for pdfmark specials
|
132
|
+
\pdf@docset=\toks18
|
133
|
+
\pdf@box=\box26
|
134
|
+
\pdf@toks=\toks19
|
135
|
+
\pdf@defaulttoks=\toks20
|
136
|
+
\Fld@listcount=\count96
|
137
|
+
\@outlinefile=\write3
|
138
|
+
)) (./latextest.aux
|
139
|
+
|
140
|
+
LaTeX Warning: Label `tab:' multiply defined.
|
141
|
+
|
142
|
+
|
143
|
+
LaTeX Warning: Label `tab:' multiply defined.
|
144
|
+
|
145
|
+
)
|
146
|
+
\openout1 = `latextest.aux'.
|
147
|
+
|
148
|
+
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 15.
|
149
|
+
LaTeX Font Info: ... okay on input line 15.
|
150
|
+
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 15.
|
151
|
+
LaTeX Font Info: ... okay on input line 15.
|
152
|
+
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 15.
|
153
|
+
LaTeX Font Info: ... okay on input line 15.
|
154
|
+
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 15.
|
155
|
+
LaTeX Font Info: ... okay on input line 15.
|
156
|
+
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 15.
|
157
|
+
LaTeX Font Info: ... okay on input line 15.
|
158
|
+
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 15.
|
159
|
+
LaTeX Font Info: ... okay on input line 15.
|
160
|
+
LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 15.
|
161
|
+
LaTeX Font Info: ... okay on input line 15.
|
162
|
+
Package hyperref Info: Link coloring OFF on input line 15.
|
163
|
+
(/usr/share/texmf/tex/latex/hyperref/nameref.sty
|
164
|
+
Package: nameref 2001/01/27 v2.19 Cross-referencing by name of section
|
165
|
+
\c@section@level=\count97
|
166
|
+
)
|
167
|
+
LaTeX Info: Redefining \ref on input line 15.
|
168
|
+
LaTeX Info: Redefining \pageref on input line 15.
|
169
|
+
(./latextest.out)
|
170
|
+
(./latextest.out)
|
171
|
+
\openout3 = `latextest.out'.
|
172
|
+
|
173
|
+
LaTeX Font Info: Try loading font information for U+msa on input line 20.
|
174
|
+
(/usr/share/texmf/tex/latex/amsfonts/umsa.fd
|
175
|
+
File: umsa.fd 2002/01/19 v2.2g AMS font definitions
|
176
|
+
)
|
177
|
+
LaTeX Font Info: Try loading font information for U+msb on input line 20.
|
178
|
+
|
179
|
+
(/usr/share/texmf/tex/latex/amsfonts/umsb.fd
|
180
|
+
File: umsb.fd 2002/01/19 v2.2g AMS font definitions
|
181
|
+
) [1
|
182
|
+
|
183
|
+
] [2] (./latextest.aux)
|
184
|
+
|
185
|
+
LaTeX Warning: There were multiply-defined labels.
|
186
|
+
|
187
|
+
)
|
188
|
+
Here is how much of TeX's memory you used:
|
189
|
+
2561 strings out of 95847
|
190
|
+
35076 string characters out of 1195962
|
191
|
+
105293 words of memory out of 1000001
|
192
|
+
5494 multiletter control sequences out of 10000+50000
|
193
|
+
5339 words of font info for 22 fonts, out of 500000 for 1000
|
194
|
+
14 hyphenation exceptions out of 1000
|
195
|
+
26i,9n,24p,689b,344s stack positions out of 1500i,500n,5000p,200000b,5000s
|
196
|
+
|
197
|
+
Output written on latextest.dvi (2 pages, 13996 bytes).
|
File without changes
|
@@ -0,0 +1,91 @@
|
|
1
|
+
\documentclass[10pt]{article}
|
2
|
+
\usepackage[latin1]{inputenc}
|
3
|
+
\usepackage[final]{graphics}
|
4
|
+
\usepackage[pdftex]{graphicx}
|
5
|
+
\usepackage[dvips]{color}
|
6
|
+
\usepackage{amsfonts}
|
7
|
+
\usepackage{subfigure}
|
8
|
+
\usepackage{lscape}
|
9
|
+
\usepackage{hyperref}
|
10
|
+
\addtolength{\oddsidemargin}{-3.5cm}
|
11
|
+
\addtolength{\textwidth}{7cm}
|
12
|
+
\addtolength{\topmargin}{-3cm}
|
13
|
+
\addtolength{\textheight}{5cm}
|
14
|
+
\newcommand{\hide}[1]{}
|
15
|
+
\begin{document}
|
16
|
+
\DeclareGraphicsExtensions{.jpg,.pdf,.mps,.png}
|
17
|
+
|
18
|
+
\begin{table}[htbp]
|
19
|
+
\begin{center}
|
20
|
+
\begin{tabular}{|c|c|c|c|c|}
|
21
|
+
\hline
|
22
|
+
& Col3 & col1 & col2 & col3\\
|
23
|
+
\hline\hline
|
24
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{row1} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c1} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c2} & r1c3\\
|
25
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & 3\\
|
26
|
+
\hline
|
27
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{row2} & r2c3 & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c1} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c2} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
28
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & 1.4 & ~ & ~ & ~\\
|
29
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & 2 & ~ & ~ & ~\\
|
30
|
+
\hline
|
31
|
+
\end{tabular}
|
32
|
+
\caption{common table}
|
33
|
+
\label{tab:}
|
34
|
+
\end{center}
|
35
|
+
\end{table}
|
36
|
+
|
37
|
+
\begin{table}[htbp]
|
38
|
+
\begin{center}
|
39
|
+
\begin{tabular}{|c|c|c|c|c|c|c|c|c|r|c|c|}
|
40
|
+
\hline
|
41
|
+
~ & \multicolumn{10}{l|}{B} & \raisebox{-3.0\totalheight}[1ex][1ex]{X}\\
|
42
|
+
~ & \raisebox{-2.0\totalheight}[1ex][1ex]{A} & \multicolumn{3}{c|}{C} & \multicolumn{4}{c|}{D} & \raisebox{-2.0\totalheight}[1ex][1ex]{E} & \raisebox{-2.0\totalheight}[1ex][1ex]{X} & ~\\
|
43
|
+
~ & ~ & \raisebox{-1.0\totalheight}[1ex][1ex]{F} & \raisebox{-1.0\totalheight}[1ex][1ex]{G} & \raisebox{-1.0\totalheight}[1ex][1ex]{G2} & \raisebox{-1.0\totalheight}[1ex][1ex]{H} & \raisebox{-1.0\totalheight}[1ex][1ex]{I} & \multicolumn{2}{c|}{I2} & ~ & ~ & ~\\
|
44
|
+
Rows & ~ & ~ & ~ & ~ & ~ & ~ & a & b & ~ & ~ & ~\\
|
45
|
+
\hline\hline
|
46
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{A1} & \raisebox{-1.0\totalheight}[1ex][1ex]{5} & \raisebox{-2.0\totalheight}[1ex][1ex]{1} & \raisebox{-2.0\totalheight}[1ex][1ex]{2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{3} & \raisebox{-2.0\totalheight}[1ex][1ex]{4} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{11} & \raisebox{-3\totalheight}[1ex][1ex]{-} & 1\\
|
47
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & \raisebox{-1.0\totalheight}[1ex][1ex]{6} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3\\
|
48
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 55.55\\
|
49
|
+
\hline
|
50
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{A2} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{11} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{22} & \raisebox{-3.0\totalheight}[1ex][1ex]{33} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{44} & \raisebox{-3.0\totalheight}[1ex][1ex]{66} & \raisebox{-3.0\totalheight}[1ex][1ex]{55000} & 2.30 & \raisebox{-4\totalheight}[1ex][1ex]{-}\\
|
51
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 5.11 & ~\\
|
52
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1 & ~\\
|
53
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 4 & ~\\
|
54
|
+
\hline
|
55
|
+
\end{tabular}
|
56
|
+
\caption{hierarchical headers}
|
57
|
+
\label{tab:}
|
58
|
+
\end{center}
|
59
|
+
\end{table}
|
60
|
+
|
61
|
+
\begin{table}[htbp]
|
62
|
+
\begin{center}
|
63
|
+
\begin{tabular}{|c|c|c|c|c|c|c|c|c|r|c|c|c|c|c|c|}
|
64
|
+
\hline
|
65
|
+
~ & \multicolumn{10}{l|}{B} & \raisebox{-3.0\totalheight}[1ex][1ex]{Col3} & \raisebox{-3.0\totalheight}[1ex][1ex]{X} & \raisebox{-3.0\totalheight}[1ex][1ex]{col1} & \raisebox{-3.0\totalheight}[1ex][1ex]{col2} & \raisebox{-3.0\totalheight}[1ex][1ex]{col3}\\
|
66
|
+
~ & \raisebox{-2.0\totalheight}[1ex][1ex]{A} & \multicolumn{3}{c|}{C} & \multicolumn{4}{c|}{D} & \raisebox{-2.0\totalheight}[1ex][1ex]{E} & \raisebox{-2.0\totalheight}[1ex][1ex]{X} & ~ & ~ & ~ & ~ & ~\\
|
67
|
+
~ & ~ & \raisebox{-1.0\totalheight}[1ex][1ex]{F} & \raisebox{-1.0\totalheight}[1ex][1ex]{G} & \raisebox{-1.0\totalheight}[1ex][1ex]{G2} & \raisebox{-1.0\totalheight}[1ex][1ex]{H} & \raisebox{-1.0\totalheight}[1ex][1ex]{I} & \multicolumn{2}{c|}{I2} & ~ & ~ & ~ & ~ & ~ & ~ & ~\\
|
68
|
+
Instance & ~ & ~ & ~ & ~ & ~ & ~ & a & b & ~ & ~ & ~ & ~ & ~ & ~ & ~\\
|
69
|
+
\hline\hline
|
70
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{A1} & \raisebox{-1.0\totalheight}[1ex][1ex]{5} & \raisebox{-2.0\totalheight}[1ex][1ex]{1} & \raisebox{-2.0\totalheight}[1ex][1ex]{2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{3} & \raisebox{-2.0\totalheight}[1ex][1ex]{4} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{11} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & 1 & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
71
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & \raisebox{-1.0\totalheight}[1ex][1ex]{6} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3 & ~ & ~ & ~\\
|
72
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 55.55 & ~ & ~ & ~\\
|
73
|
+
\hline
|
74
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{A2} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{11} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{22} & \raisebox{-3.0\totalheight}[1ex][1ex]{33} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{44} & \raisebox{-3.0\totalheight}[1ex][1ex]{66} & \raisebox{-3.0\totalheight}[1ex][1ex]{55000} & 2.30 & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-}\\
|
75
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 5.11 & ~ & ~ & ~ & ~ & ~\\
|
76
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1 & ~ & ~ & ~ & ~ & ~\\
|
77
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 4 & ~ & ~ & ~ & ~ & ~\\
|
78
|
+
\hline
|
79
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{row1} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c1} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c2} & r1c3\\
|
80
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3\\
|
81
|
+
\hline
|
82
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{row2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & r2c3 & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c1} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c2} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
83
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1.4 & ~ & ~ & ~ & ~\\
|
84
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 2 & ~ & ~ & ~ & ~\\
|
85
|
+
\hline
|
86
|
+
\end{tabular}
|
87
|
+
\caption{both tables}
|
88
|
+
\label{tab:}
|
89
|
+
\end{center}
|
90
|
+
\end{table}
|
91
|
+
\end{document}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
\documentclass[]{article}
|
2
|
+
\usepackage[latin1]{inputenc}
|
3
|
+
\usepackage[final]{graphics}
|
4
|
+
\usepackage[pdftex]{graphicx}
|
5
|
+
\usepackage[dvips]{color}
|
6
|
+
\usepackage{amsfonts}
|
7
|
+
\usepackage{subfigure}
|
8
|
+
\usepackage{lscape}
|
9
|
+
\usepackage{hyperref}
|
10
|
+
\addtolength{\oddsidemargin}{-3.5cm}
|
11
|
+
\addtolength{\textwidth}{7cm}
|
12
|
+
\addtolength{\topmargin}{-3cm}
|
13
|
+
\addtolength{\textheight}{5cm}
|
14
|
+
\newcommand{\hide}[1]{}
|
15
|
+
\begin{document}
|
16
|
+
\DeclareGraphicsExtensions{.jpg,.pdf,.mps,.png}
|
17
|
+
|
18
|
+
\begin{table}[htbp]
|
19
|
+
\begin{center}
|
20
|
+
\begin{tabular}{|c|c|c|c|c|}
|
21
|
+
\hline
|
22
|
+
& Col3 & col1 & col2 & col3\\
|
23
|
+
\hline\hline
|
24
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{row1} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c1} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c2} & r1c3\\
|
25
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & 3\\
|
26
|
+
\hline
|
27
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{row2} & r2c3 & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c1} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c2} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
28
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & 1.4 & ~ & ~ & ~\\
|
29
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & 2 & ~ & ~ & ~\\
|
30
|
+
\hline
|
31
|
+
\end{tabular}
|
32
|
+
\caption{common table}
|
33
|
+
\label{tab:}
|
34
|
+
\end{center}
|
35
|
+
\end{table}
|
36
|
+
|
37
|
+
\begin{table}[htbp]
|
38
|
+
\begin{center}
|
39
|
+
\begin{tabular}{|c|c|c|c|c|c|c|c|c|r|c|c|}
|
40
|
+
\hline
|
41
|
+
~ & \multicolumn{10}{l|}{B} & \raisebox{-3.0\totalheight}[1ex][1ex]{X}\\
|
42
|
+
~ & \raisebox{-2.0\totalheight}[1ex][1ex]{A} & \multicolumn{3}{c|}{C} & \multicolumn{4}{c|}{D} & \raisebox{-2.0\totalheight}[1ex][1ex]{E} & \raisebox{-2.0\totalheight}[1ex][1ex]{X} & ~\\
|
43
|
+
~ & ~ & \raisebox{-1.0\totalheight}[1ex][1ex]{F} & \raisebox{-1.0\totalheight}[1ex][1ex]{G} & \raisebox{-1.0\totalheight}[1ex][1ex]{G2} & \raisebox{-1.0\totalheight}[1ex][1ex]{H} & \raisebox{-1.0\totalheight}[1ex][1ex]{I} & \multicolumn{2}{c|}{I2} & ~ & ~ & ~\\
|
44
|
+
Rows & ~ & ~ & ~ & ~ & ~ & ~ & a & b & ~ & ~ & ~\\
|
45
|
+
\hline\hline
|
46
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{A1} & \raisebox{-1.0\totalheight}[1ex][1ex]{5} & \raisebox{-2.0\totalheight}[1ex][1ex]{1} & \raisebox{-2.0\totalheight}[1ex][1ex]{2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{3} & \raisebox{-2.0\totalheight}[1ex][1ex]{4} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & 1\\
|
47
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & \raisebox{-1.0\totalheight}[1ex][1ex]{6} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3\\
|
48
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 55.55\\
|
49
|
+
\hline
|
50
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{A2} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{11} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{22} & \raisebox{-3.0\totalheight}[1ex][1ex]{33} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{44} & \raisebox{-3.0\totalheight}[1ex][1ex]{66} & \raisebox{-3.0\totalheight}[1ex][1ex]{55} & 2.30 & \raisebox{-4\totalheight}[1ex][1ex]{-}\\
|
51
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 5.11 & ~\\
|
52
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1 & ~\\
|
53
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 4 & ~\\
|
54
|
+
\hline
|
55
|
+
\end{tabular}
|
56
|
+
\caption{hierarchical headers}
|
57
|
+
\label{tab:}
|
58
|
+
\end{center}
|
59
|
+
\end{table}
|
60
|
+
|
61
|
+
\begin{table}[htbp]
|
62
|
+
\begin{center}
|
63
|
+
\begin{tabular}{|c|c|c|c|c|c|c|c|c|r|c|c|c|c|c|c|}
|
64
|
+
\hline
|
65
|
+
~ & \multicolumn{10}{l|}{B} & \raisebox{-3.0\totalheight}[1ex][1ex]{Col3} & \raisebox{-3.0\totalheight}[1ex][1ex]{X} & \raisebox{-3.0\totalheight}[1ex][1ex]{col1} & \raisebox{-3.0\totalheight}[1ex][1ex]{col2} & \raisebox{-3.0\totalheight}[1ex][1ex]{col3}\\
|
66
|
+
~ & \raisebox{-2.0\totalheight}[1ex][1ex]{A} & \multicolumn{3}{c|}{C} & \multicolumn{4}{c|}{D} & \raisebox{-2.0\totalheight}[1ex][1ex]{E} & \raisebox{-2.0\totalheight}[1ex][1ex]{X} & ~ & ~ & ~ & ~ & ~\\
|
67
|
+
~ & ~ & \raisebox{-1.0\totalheight}[1ex][1ex]{F} & \raisebox{-1.0\totalheight}[1ex][1ex]{G} & \raisebox{-1.0\totalheight}[1ex][1ex]{G2} & \raisebox{-1.0\totalheight}[1ex][1ex]{H} & \raisebox{-1.0\totalheight}[1ex][1ex]{I} & \multicolumn{2}{c|}{I2} & ~ & ~ & ~ & ~ & ~ & ~ & ~\\
|
68
|
+
Instance & ~ & ~ & ~ & ~ & ~ & ~ & a & b & ~ & ~ & ~ & ~ & ~ & ~ & ~\\
|
69
|
+
\hline\hline
|
70
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{A1} & \raisebox{-1.0\totalheight}[1ex][1ex]{5} & \raisebox{-2.0\totalheight}[1ex][1ex]{1} & \raisebox{-2.0\totalheight}[1ex][1ex]{2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{3} & \raisebox{-2.0\totalheight}[1ex][1ex]{4} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & 1 & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
71
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & \raisebox{-1.0\totalheight}[1ex][1ex]{6} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3 & ~ & ~ & ~\\
|
72
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 55.55 & ~ & ~ & ~\\
|
73
|
+
\hline
|
74
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{A2} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{11} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{22} & \raisebox{-3.0\totalheight}[1ex][1ex]{33} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-3.0\totalheight}[1ex][1ex]{44} & \raisebox{-3.0\totalheight}[1ex][1ex]{66} & \raisebox{-3.0\totalheight}[1ex][1ex]{55} & 2.30 & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-} & \raisebox{-4\totalheight}[1ex][1ex]{-}\\
|
75
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 5.11 & ~ & ~ & ~ & ~ & ~\\
|
76
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1 & ~ & ~ & ~ & ~ & ~\\
|
77
|
+
\raisebox{-3.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 4 & ~ & ~ & ~ & ~ & ~\\
|
78
|
+
\hline
|
79
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{row1} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-2\totalheight}[1ex][1ex]{-} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c1} & \raisebox{-1.0\totalheight}[1ex][1ex]{r1c2} & r1c3\\
|
80
|
+
\raisebox{-1.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 3\\
|
81
|
+
\hline
|
82
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{row2} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-3\totalheight}[1ex][1ex]{-} & r2c3 & \raisebox{-3\totalheight}[1ex][1ex]{-} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c1} & \raisebox{-2.0\totalheight}[1ex][1ex]{r2c2} & \raisebox{-3\totalheight}[1ex][1ex]{-}\\
|
83
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 1.4 & ~ & ~ & ~ & ~\\
|
84
|
+
\raisebox{-2.0\totalheight}[1ex][1ex]{~} & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & ~ & 2 & ~ & ~ & ~ & ~\\
|
85
|
+
\hline
|
86
|
+
\end{tabular}
|
87
|
+
\caption{both tables}
|
88
|
+
\label{tab:}
|
89
|
+
\end{center}
|
90
|
+
\end{table}
|
91
|
+
\end{document}
|
@@ -0,0 +1 @@
|
|
1
|
+
{" row1{" col1" r1c1" col2" r1c2" col3[" r1c3"3" row2{" col1" r2c1" col2" r2c2" Col3[" r2c3"1.4"2
|
data/examples/test-latex.rb
CHANGED
@@ -14,20 +14,24 @@ rows = {}
|
|
14
14
|
rows["A1"] = {'B'=>
|
15
15
|
{'A'=> ['5',6],
|
16
16
|
'C'=> {'F'=>'1','G'=>'2'},
|
17
|
-
'D'=> {'H'=>'3','I'=>'4'}
|
17
|
+
'D'=> {'H'=>'3','I'=>'4'},
|
18
|
+
'E'=> 11
|
18
19
|
},
|
19
20
|
'X'=>[1,3,55.55]}
|
20
|
-
rows["A2"] = {'B'=>
|
21
|
-
{
|
21
|
+
rows["A2"] = {'B'=>
|
22
|
+
{:align => "l", # define special alignment for the 'B' header, doesn't affect the final columns.
|
23
|
+
'C'=> {'F'=>'11','G2'=>'22'},
|
22
24
|
'D'=> {'H'=>'33','I2'=>{'a'=>'44','b'=>'66'}},
|
23
|
-
'E'=> '
|
24
|
-
'X'=>[2.3,5.111,1,4]}
|
25
|
+
'E'=> {:value => '55000', :align => 'r'}, # define alignment for the 'E' column and all data.
|
26
|
+
'X'=>[2.3,5.111,1,4]}}
|
27
|
+
|
25
28
|
tex.table(rows,"hierarchical headers", "Rows")
|
26
29
|
|
27
30
|
File.open("saved_table.dat","r") do |f|
|
28
31
|
old_rows = Marshal::load(f)
|
29
32
|
rows.merge!(old_rows)
|
30
33
|
end
|
34
|
+
|
31
35
|
tex.table(rows,"both tables",:rowTitle=>"Instance") do |x,y|
|
32
36
|
order = %w{X B C D E G F H col1 col2 col3 Col3}
|
33
37
|
if order.index(x) && order.index(y)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'latex'
|
2
|
+
|
3
|
+
tex=LatexFile.new("latextest.tex")
|
4
|
+
rows = {}
|
5
|
+
rows["row1"] = {"col1" => "r1c1", "col2"=>"r1c2", "col3"=>["r1c3","3"]}
|
6
|
+
rows["row2"] = {"col1" => "r2c1", "col2"=>"r2c2", "Col3"=>["r2c3","1.4","2"]}
|
7
|
+
tex.table(rows,"common table")
|
8
|
+
|
9
|
+
File.open("saved_table.dat","w") do |f|
|
10
|
+
Marshal::dump(rows, f)
|
11
|
+
end
|
12
|
+
|
13
|
+
rows = {}
|
14
|
+
rows["A1"] = {'B'=>
|
15
|
+
{'A'=> ['5',6],
|
16
|
+
'C'=> {'F'=>'1','G'=>'2'},
|
17
|
+
'D'=> {'H'=>'3','I'=>'4'}
|
18
|
+
},
|
19
|
+
'X'=>[1,3,55.55]}
|
20
|
+
rows["A2"] = {'B'=>
|
21
|
+
{'C'=> {'F'=>'11','G2'=>'22'},
|
22
|
+
'D'=> {'H'=>'33','I2'=>{'a'=>'44','b'=>'66'}},
|
23
|
+
'E'=> '55'},
|
24
|
+
'X'=>[2.3,5.111,1,4]}
|
25
|
+
tex.table(rows,"hierarchical headers", "Rows")
|
26
|
+
|
27
|
+
File.open("saved_table.dat","r") do |f|
|
28
|
+
old_rows = Marshal::load(f)
|
29
|
+
rows.merge!(old_rows)
|
30
|
+
end
|
31
|
+
tex.table(rows,"both tables",:rowTitle=>"Instance") do |x,y|
|
32
|
+
order = %w{X B C D E G F H col1 col2 col3 Col3}
|
33
|
+
if order.index(x) && order.index(y)
|
34
|
+
order.index(x) <=> order.index(y)
|
35
|
+
else
|
36
|
+
x <=> y
|
37
|
+
end
|
38
|
+
end
|
39
|
+
tex.close
|
40
|
+
|
data/lib/latex.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright (c) 2004 Christian Bang <cbang AT web.de> and Frank Hutter
|
2
2
|
#
|
3
|
-
# Version 0.1.
|
3
|
+
# Version 0.1.2
|
4
4
|
#
|
5
5
|
# All rights reserved. You can redistribute and/or modify it under the same terms as Ruby.
|
6
6
|
#
|
@@ -28,7 +28,7 @@ end
|
|
28
28
|
# You may want to quote underscores ('_') in some Latex code you create. For this use String.escape_ which
|
29
29
|
# is available with this file.
|
30
30
|
class LatexFile < File
|
31
|
-
Header = Struct.new(:name, :children)
|
31
|
+
Header = Struct.new(:name, :align, :children)
|
32
32
|
|
33
33
|
# the default table font size, default is nil which means the Latex default. See #table for possible values
|
34
34
|
attr_accessor :defaultTableFontSize
|
@@ -38,18 +38,22 @@ class LatexFile < File
|
|
38
38
|
@@default_extras = {:fontsize => "10pt" }
|
39
39
|
attr_reader :extras
|
40
40
|
|
41
|
+
@default_table_align = 'c'
|
42
|
+
# The default table alignment is <tt>'c'</tt> but can be changed.
|
43
|
+
attr_accessor :default_table_align
|
44
|
+
|
41
45
|
# Open a new latex-file for writing.
|
42
46
|
# +extras+ is an optional hash that may contain the following flags
|
43
47
|
# <tt>:landscape</tt>:: turns all pages 90�
|
44
48
|
# <tt>:twocolumn</tt>:: the whole document has two columns
|
45
49
|
# <tt>extras[:fontsize]</tt>:: string containing the font size like "10pt"
|
46
50
|
# === Example:
|
47
|
-
# f = LatexFile.new("test.tex",
|
51
|
+
# f = LatexFile.new("test.tex", :twocolumn => true, :fontsize => "11pt")
|
48
52
|
def initialize(filename, extras = nil)
|
49
53
|
super(filename,"w") # open a file for write access
|
50
54
|
@extras = extras || Hash.new
|
51
55
|
#use defaults for unused entries:
|
52
|
-
|
56
|
+
@@default_extras.each_key{|key| @extras[key] ||= @@default_extras[key] }
|
53
57
|
@indent = 0 # indent lines in blocks
|
54
58
|
|
55
59
|
@usePackages = @extras[:usePackages] || @@defaultUsePackages
|
@@ -194,12 +198,12 @@ class LatexFile < File
|
|
194
198
|
#+header+:: is of type +Header+: (name, children)
|
195
199
|
def getNumColsOfHeader(header)
|
196
200
|
header.children.inject(0) do |numChildren, child|
|
197
|
-
numChildren + (
|
201
|
+
numChildren + (child.children ? getNumColsOfHeader(child) : 1)
|
198
202
|
end
|
199
203
|
end
|
200
204
|
private :getNumColsOfHeader
|
201
205
|
|
202
|
-
#+
|
206
|
+
#+list+:: must contain hashes as values for all keys.
|
203
207
|
#These child hashes will be joined/merged to one big hash.
|
204
208
|
#The actual leafes will be ignored so that only the header remain.
|
205
209
|
def getHeaderMergedHash(list)
|
@@ -217,7 +221,11 @@ class LatexFile < File
|
|
217
221
|
#return list if nothingToMerge
|
218
222
|
return nil if nothingToMerge #return only header tree without any data
|
219
223
|
toMerge.each_pair do |key,value|
|
220
|
-
|
224
|
+
if key.class == Symbol
|
225
|
+
merged[key] = value unless merged[key]
|
226
|
+
else
|
227
|
+
merged[key] = getHeaderMergedHash(value)
|
228
|
+
end
|
221
229
|
end
|
222
230
|
return merged
|
223
231
|
end
|
@@ -228,16 +236,27 @@ class LatexFile < File
|
|
228
236
|
#Given a list of hashes, initially a hash-list of each row it
|
229
237
|
#returns a sorted tree representation - a headerList.
|
230
238
|
#+sort_block+:: a block that compares header names
|
239
|
+
#side effects::
|
240
|
+
# deletes :align entries from the +hash+ and transforms
|
241
|
+
# hash[:value] = value hashes to normal entries
|
231
242
|
def hash2HeaderList(hash, sort_block = @@default_sort)
|
232
243
|
headerList = []
|
233
244
|
entries = hash.to_a
|
234
|
-
entries.sort!
|
245
|
+
entries.sort! do |x,y| sort_block.call(x[0],y[0])
|
246
|
+
end
|
235
247
|
for key,value in entries
|
236
248
|
if value.class == Hash
|
237
|
-
|
238
|
-
|
249
|
+
align = value.delete(:align) || @default_table_align
|
250
|
+
align = align[0] if align.class == Array
|
251
|
+
if value[:value] #transform hashes with :value keys to normal entries
|
252
|
+
hash[key] = value = value[:value]
|
253
|
+
headerList << Header.new(key,align,nil)
|
254
|
+
else
|
255
|
+
subtree = hash2HeaderList(value, sort_block)
|
256
|
+
headerList << Header.new(key,align,subtree)
|
257
|
+
end
|
239
258
|
else
|
240
|
-
headerList << key
|
259
|
+
headerList << Header.new(key,@default_table_align,nil)
|
241
260
|
end
|
242
261
|
end
|
243
262
|
return headerList
|
@@ -257,11 +276,14 @@ class LatexFile < File
|
|
257
276
|
nextLevel = [] # collects the children nodes of all nodes processed (BFS)
|
258
277
|
hasChildrenInNextLevel = false
|
259
278
|
for header in headerList
|
260
|
-
if header.
|
261
|
-
line << header
|
262
|
-
nextLevel
|
279
|
+
if header.is_a?(Array) and header[0] == "~"
|
280
|
+
line << header
|
281
|
+
nextLevel << header # insert this for lines below this
|
282
|
+
elsif header.children == nil # leaf node ?
|
283
|
+
line << [header.name, header.align]
|
284
|
+
nextLevel << ["~",header.align] # insert this for lines below this
|
263
285
|
else
|
264
|
-
line << [header.name, getNumColsOfHeader(header)]
|
286
|
+
line << [header.name, header.align, getNumColsOfHeader(header)]
|
265
287
|
nextLevel += header.children
|
266
288
|
hasChildrenInNextLevel = true
|
267
289
|
end
|
@@ -280,10 +302,10 @@ class LatexFile < File
|
|
280
302
|
paths = []
|
281
303
|
path_prefix = path_prefix || []
|
282
304
|
for header in headerList
|
283
|
-
if header.
|
305
|
+
if header.children
|
284
306
|
paths += getLeafColumns(header.children, path_prefix + [header.name])
|
285
307
|
else #header is not of class Header but a leaf header (string)
|
286
|
-
paths << path_prefix + [header]
|
308
|
+
paths << path_prefix + [header.name]
|
287
309
|
end
|
288
310
|
end
|
289
311
|
return paths
|
@@ -341,6 +363,9 @@ class LatexFile < File
|
|
341
363
|
# <tt>:header_hlines</tt>::
|
342
364
|
# If +true+, then horizontal lines between headers of different depths are drawn.
|
343
365
|
# Default is +false+ (no horizontal header lines).
|
366
|
+
# <tt>:rowAlign</tt>::
|
367
|
+
# Alignment of the column containing the row names. Values are 'r','c','l'.
|
368
|
+
# See also the attribute +default_table_align+.
|
344
369
|
#
|
345
370
|
# === Example:
|
346
371
|
# require 'latex'
|
@@ -355,9 +380,22 @@ class LatexFile < File
|
|
355
380
|
# order = %w{A X B C D E}
|
356
381
|
# (order.index(x) && order.index(y)) ? order.index(x) <=> order.index(y) : x <=> y
|
357
382
|
# end
|
358
|
-
# tex.table(rows,"special ordering", :rowTitle=>"Instance", :sort => tableSort)
|
383
|
+
# tex.table(rows,"special ordering", :rowTitle=>"Instance", :sort => tableSort)
|
384
|
+
#
|
385
|
+
# === Column alignment:
|
386
|
+
# By default alignment is centered. You can change this for all columns using the attribute
|
387
|
+
# +default_table_align+.
|
388
|
+
# The alignment can also be changed for each column separately:
|
389
|
+
# Headers can be aligned as demonstrated in the following examples:
|
390
|
+
# rows['1'] = {'Main Header' => {:align => 'l', 'A' => '5','B' => '6'}}
|
391
|
+
# This affects only the header and not the columns, because this is no final column header.
|
392
|
+
# Subheader and so the final columns themselves are aligned as follows:
|
393
|
+
# rows['1'] = {'Main Header' => {'A' => {:value => '5', :align => 'l'} ,'B' => '6'}}
|
394
|
+
# rows['2'] = {'Main Header' => {'A' => '77','B' => '8'}}
|
395
|
+
# As you can see it is only needed to define the alignment of a column once. It can be done
|
396
|
+
# as often as you like but only one alignment definition is used.
|
359
397
|
def table(entries, caption, *args)
|
360
|
-
tableValidArgs = [:rowTitle, :label, :newTableThreshold, :placement, :empty, :sort, :landscape, :fontSize, :grouping, :header_hlines]
|
398
|
+
tableValidArgs = [:rowTitle, :label, :newTableThreshold, :placement, :empty, :sort, :landscape, :fontSize, :grouping, :header_hlines, :rowAlign]
|
361
399
|
# raise(ArgumentError,"Too many arguments Latex.table", caller) unless args.length <= 1
|
362
400
|
hash = {}
|
363
401
|
args = if args[0].kind_of?(Hash)
|
@@ -377,6 +415,7 @@ class LatexFile < File
|
|
377
415
|
@tableLandscape = args[:landscape]
|
378
416
|
@tableFontSize = args[:fontSize] || @defaultTableFontSize
|
379
417
|
@header_hlines = args[:header_hlines]
|
418
|
+
@rowAlign = args[:rowAlign] || @default_table_align
|
380
419
|
|
381
420
|
#access an element in the table which is located in row _rowName_ and in a column
|
382
421
|
#that is defined by a _path_ through the headers that can be obtained with
|
@@ -387,6 +426,7 @@ class LatexFile < File
|
|
387
426
|
entry = entry[key]
|
388
427
|
return [] unless entry
|
389
428
|
end
|
429
|
+
entry = entry[:value] if entry.is_a?(Hash)
|
390
430
|
return entry.is_a?(Array) ? entry : [entry]
|
391
431
|
end
|
392
432
|
|
@@ -395,7 +435,9 @@ class LatexFile < File
|
|
395
435
|
puts "\n\\begin{table}[#{placement}]\n\\begin{center}"
|
396
436
|
puts "\\#{@tableFontSize}" if @tableFontSize
|
397
437
|
print " "*@indent + "\\begin{tabular}{|"
|
398
|
-
print
|
438
|
+
# print the alignment {c,r,l} for each leaf column
|
439
|
+
print "#{@rowAlign}|" # the first column with the row names
|
440
|
+
headerLines[-1].each {|headerName, colAlign| print "#{colAlign}|" }
|
399
441
|
puts "}"
|
400
442
|
currentHeaderRowNumber = 0
|
401
443
|
puts "\\hline"
|
@@ -408,11 +450,11 @@ class LatexFile < File
|
|
408
450
|
end
|
409
451
|
currentColumn = 2
|
410
452
|
cline = ""
|
411
|
-
print headerLine.map {|headerName, columns|
|
453
|
+
print headerLine.map {|headerName, align, columns|
|
412
454
|
raise(FormatError, "Invalid format: #{headerName.inspect} contains % that is not sufficiently quoted for latex.", caller) if headerName =~ /[^\\]%|^%/
|
413
455
|
if columns
|
414
456
|
cline += "\\cline{#{currentColumn}-#{(currentColumn+=columns)-1}}" if @header_hlines
|
415
|
-
"\\multicolumn{#{columns}}{
|
457
|
+
"\\multicolumn{#{columns}}{#{align}|}{#{headerName}}"
|
416
458
|
else
|
417
459
|
currentColumn += 1
|
418
460
|
if currentHeaderRowNumber == headerLines.length-1 || headerName == "~"
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.1
|
|
3
3
|
specification_version: 1
|
4
4
|
name: latex
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2004-
|
6
|
+
version: 0.1.2
|
7
|
+
date: 2004-10-19
|
8
8
|
summary: Latex is a LaTeX text generation library for Ruby.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -13,7 +13,7 @@ email: cbang AT web.de
|
|
13
13
|
homepage: http://latex.rubyforge.org
|
14
14
|
rubyforge_project: latex
|
15
15
|
description:
|
16
|
-
autorequire: latex
|
16
|
+
autorequire: latex
|
17
17
|
default_executable:
|
18
18
|
bindir: bin
|
19
19
|
has_rdoc: true
|
@@ -29,7 +29,17 @@ files:
|
|
29
29
|
- lib/latex.rb
|
30
30
|
- README
|
31
31
|
- LICENSE.txt
|
32
|
+
- ChangeLog
|
33
|
+
- examples/saved_table.dat
|
34
|
+
- examples/test-latex.rb.~1.3.~
|
32
35
|
- examples/test-latex.rb
|
36
|
+
- examples/latextest.aux
|
37
|
+
- examples/latextest.dvi
|
38
|
+
- examples/latextest.log
|
39
|
+
- examples/latextest.out
|
40
|
+
- examples/latextest.tex
|
41
|
+
- examples/latextest.tex~
|
42
|
+
- examples/latex.rb
|
33
43
|
test_files: []
|
34
44
|
rdoc_options: []
|
35
45
|
extra_rdoc_files: []
|