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 ADDED
@@ -0,0 +1,9 @@
1
+ 0.1.2
2
+ 2004-10-12 Christian Bang <cbang@cbang@web.de>
3
+
4
+ * Non-centered table columns are now supported.
5
+ See doc for table and new example.
6
+ * Bug with LatexFile optional arguments (extras) fixed.
7
+
8
+
9
+
data/README CHANGED
@@ -45,7 +45,7 @@ Usage
45
45
  -----
46
46
 
47
47
  In order to get an overview of the features you can generate
48
- the RDoc documentation and hava a look at the examples/ directory.
48
+ the RDoc documentation and have a look at the examples/ directory.
49
49
 
50
50
 
51
51
  License
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
@@ -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
- {'C'=> {'F'=>'11','G2'=>'22'},
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'=> '55'},
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.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", {:twocolumn => true, :fontsize => "11pt"})
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
- @extras.each_key{|key| @extras[key] |= @@default_extras[key] }
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 + ((child.class == Header) ? getNumColsOfHeader(child) : 1)
201
+ numChildren + (child.children ? getNumColsOfHeader(child) : 1)
198
202
  end
199
203
  end
200
204
  private :getNumColsOfHeader
201
205
 
202
- #+hash+:: must contain hashes as values for all keys.
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
- merged[key] = getHeaderMergedHash(value)
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! {|x,y| sort_block.call(x[0],y[0])}
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
- subtree = hash2HeaderList(value, sort_block)
238
- headerList << Header.new(key,subtree)
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.class != Header
261
- line << header #leaf node will not be put in an array with column width info
262
- nextLevel += ["~"] # insert this for lines below this
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.class == 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 "c|" * (leafColumns.length+1)
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}}{c|}{#{headerName}}"
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.1
7
- date: 2004-09-30
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/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: []