viewworkbook 0.1.3 → 0.3
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.
- checksums.yaml +4 -4
- data/README.md +126 -0
- data/bin/viewworkbook +12 -10
- data/doc/html/viewworkbook.html +98 -388
- data/doc/man/viewworkbook.1.gz +0 -0
- data/doc/rst/viewworkbook.rst +59 -51
- data/lib/action.rb +10 -16
- data/lib/basic_logging.rb +178 -0
- data/lib/cell.rb +22 -19
- data/lib/color_output.rb +16 -0
- data/lib/column.rb +17 -18
- data/lib/file_checking.rb +36 -11
- data/lib/menu.rb +11 -24
- data/lib/row.rb +13 -16
- data/lib/scrollable.rb +8 -17
- data/lib/sheetdata.rb +45 -58
- data/lib/sheetinterface.rb +11 -25
- data/lib/translating.rb +6 -12
- data/lib/user_input.rb +4 -11
- data/lib/viewworkbook.rb +20 -31
- data/viewworkbook.gemspec +26 -0
- metadata +22 -23
- data/lib/log.conf +0 -62
- data/lib/logging.rb +0 -195
data/doc/rst/viewworkbook.rst
CHANGED
@@ -11,28 +11,35 @@ viewworkbook <spreadsheet>
|
|
11
11
|
|
12
12
|
DESCRIPTION
|
13
13
|
=============
|
14
|
-
|
15
|
-
window. It reproduces the tables
|
14
|
+
ViewWorkbook allows you to read spreadsheet files in text mode in a terminal
|
15
|
+
window. It reproduces the tables contained in a spreadsheet file and It also
|
16
16
|
lets you navigate through the sheets. The visible part of a sheet is limited
|
17
|
-
laterally and horizontally by the
|
18
|
-
adapt the width of table
|
19
|
-
|
20
|
-
program, the utility serves to
|
21
|
-
received via email
|
17
|
+
laterally and horizontally by the size of the terminal, but you can scroll
|
18
|
+
through it. You can adapt the width of table columns to make the table more
|
19
|
+
readable. Finally, you can save tables to a text file if you wish. For the
|
20
|
+
author of the program, the utility serves to quickly glance at spreadsheets
|
21
|
+
that are received via email in the Mutt mail client, which is a terminal
|
22
22
|
application.
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
Supported spreadsheet formats are those handled by the Ruby gem "**roo**"
|
25
|
+
(2024, roo 2.10.1):
|
26
26
|
|
27
|
-
- Microsoft™
|
27
|
+
- Microsoft™ Excel 2007 - 2013 formats (**xlsx**, **xlsm**)
|
28
28
|
|
29
|
-
-
|
29
|
+
- LibreOffice / OpenOffice.org formats (**ods**)
|
30
30
|
|
31
|
-
-
|
31
|
+
- CSV
|
32
|
+
|
33
|
+
- Microsoft™ Excel 97, Excel 2002 XML, and Excel 2003 XML formats (**xls**,
|
34
|
+
**xml**)
|
35
|
+
|
36
|
+
Additionally also
|
37
|
+
|
38
|
+
- The SoftMaker™ spreadsheet formats **pmd** and **pmdx**.
|
32
39
|
|
33
40
|
Options
|
34
41
|
=============
|
35
|
-
Other than the path to the spreadsheet file, viewworkbook does currently
|
42
|
+
Other than the path to the spreadsheet file, viewworkbook does not currently
|
36
43
|
interpret any command line arguments.
|
37
44
|
|
38
45
|
Menu commands
|
@@ -52,72 +59,73 @@ below the current table:
|
|
52
59
|
|
53
60
|
**value (v) * save to file (f) * sheet (s) * column (c) * up(i) * down(k) * left(j) * right(l) * quit (q) ***
|
54
61
|
|
55
|
-
When you
|
56
|
-
to terminate the program)
|
57
|
-
|
58
|
-
|
59
|
-
|
62
|
+
When you press one of the hotkeys, you can execute a command directly (like "q"
|
63
|
+
to terminate the program) or a submenu may appear (like with "c" which gives
|
64
|
+
you control over column properties) or you may be prompted for input (like with
|
65
|
+
"v", where you have to enter a cell reference). Read on for an explanation of
|
66
|
+
each menu command.
|
60
67
|
|
61
68
|
value (v)
|
62
69
|
display the value from a cell. This is useful, when columns are not wide
|
63
|
-
enough to show
|
70
|
+
enough to show the full value. After entering "**v**", you are
|
64
71
|
immediately invited to enter a cell reference. Cells are referenced in
|
65
|
-
the format "
|
72
|
+
the format "column:row", e.g. D:12 for the cell in column "D" and row
|
66
73
|
"12".
|
67
74
|
|
68
75
|
save to file (f)
|
69
|
-
Save the current or all tables to a text file.
|
70
|
-
|
76
|
+
Save the current table or all tables to a text file. Initially, the command
|
77
|
+
shows two alternative sub-commands:
|
71
78
|
|
72
79
|
Current sheet (c) * all sheets (a)
|
73
|
-
|
74
|
-
path
|
75
|
-
|
76
|
-
|
80
|
+
Regardless of your choice, you will be prompted to enter the output file
|
81
|
+
path in the next step. You will receive a warning, if the file already
|
82
|
+
exists at which point you can choose to either overwrite the existing file
|
83
|
+
or give it a different name.
|
77
84
|
|
78
85
|
sheet (s)
|
79
|
-
Navigate to a different sheet
|
80
|
-
|
81
|
-
|
82
|
-
|
86
|
+
Navigate to a different sheet whthin the current workbook. You can choose
|
87
|
+
a sheet by its number or by its name. If you want to select the next sheet
|
88
|
+
**by name**, a list of available names will first be shown. You just type
|
89
|
+
the name you want.
|
83
90
|
|
84
91
|
column (c)
|
85
|
-
Alter the properties of the table
|
86
|
-
|
87
|
-
|
88
|
-
|
92
|
+
Alter the properties of the table columns. As of February 2017 the only
|
93
|
+
property that can be changed, is the width of all columns. When you enter
|
94
|
+
"**c**" the subcommand column width (w) is shown. After entering "**w**"
|
95
|
+
you can enter the desired width in characters.
|
89
96
|
|
90
97
|
Arrows(i, j, k, l)
|
91
|
-
|
92
|
-
These hotkeys correspond to the default navigation keys
|
93
|
-
|
98
|
+
Use these hotkeys to navigate a sheet that is too big to be displayed
|
99
|
+
entirely at once. These hotkeys correspond to the default navigation keys
|
100
|
+
in the Vi editor.
|
101
|
+
|
94
102
|
quit (q)
|
95
103
|
Enter "**q**" to quit the program at any moment except when an input
|
96
104
|
invitation is shown.
|
97
105
|
|
98
|
-
Hidden
|
99
|
-
|
100
|
-
|
101
|
-
|
106
|
+
Hidden menu commands
|
107
|
+
---------------------
|
108
|
+
Currently, there is only one such command available. Pressing the **Escape
|
109
|
+
key** will interrupt an unfinished action and refresh the display.
|
102
110
|
|
103
111
|
Other Information
|
104
112
|
=================
|
105
113
|
|
106
114
|
Development and source code
|
107
|
-
Viewworkbook has been written in Ruby.
|
108
|
-
language, the executable file and all
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
Viewworkbook has been written in Ruby. Since Ruby is an interpreted programming
|
116
|
+
language, the executable file and all files to which it refers at any given time
|
117
|
+
are the source files of the current program version. You can open these
|
118
|
+
files in any text editor to examine the source code. If you have received
|
119
|
+
the program as a Ruby-gem, you can also decompress a copy of the gem-file
|
120
|
+
with **tar -x**, then **tar -xzf**.
|
113
121
|
|
114
122
|
Bugs
|
115
|
-
Negative values are not always displayed, when very long (like 15
|
116
|
-
|
123
|
+
Negative values are not always displayed, when they are very long (like 15
|
124
|
+
ciphers). Increasing the column width further does not help.
|
117
125
|
|
118
126
|
License
|
119
|
-
Viewworkbook is distributed under the conditions of the
|
120
|
-
|
127
|
+
Viewworkbook is distributed under the conditions of the WTFPL 2.0 or later,
|
128
|
+
see http://www.wtfpl.net/about/ for details
|
121
129
|
|
122
130
|
Author
|
123
131
|
Viewworkbook has been developed by Michael Uplawski
|
data/lib/action.rb
CHANGED
@@ -1,46 +1,38 @@
|
|
1
1
|
#encoding: UTF-8
|
2
|
-
|
3
2
|
=begin
|
4
3
|
/***************************************************************************
|
5
|
-
*
|
4
|
+
* ©2016-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
5
|
* *
|
7
6
|
* This program is free software; you can redistribute it and/or modify *
|
8
|
-
* it under the terms of the
|
9
|
-
*
|
10
|
-
* (at your option) any later version. *
|
7
|
+
* it under the terms of the WTFPL 2.0 or later, see *
|
8
|
+
* http://www.wtfpl.net/about/ *
|
11
9
|
* *
|
12
10
|
* This program is distributed in the hope that it will be useful, *
|
13
11
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
14
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
15
|
-
* GNU General Public License for more details. *
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
16
13
|
* *
|
17
|
-
* You should have received a copy of the GNU General Public License *
|
18
|
-
* along with this program; if not, write to the *
|
19
|
-
* Free Software Foundation, Inc., *
|
20
|
-
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
21
14
|
***************************************************************************/
|
22
15
|
=end
|
23
16
|
|
24
|
-
require_relative '
|
17
|
+
require_relative 'basic_logging'
|
25
18
|
|
26
19
|
# An Action is executed on a user's request.
|
27
20
|
# It has a name, an associated closure and hotkey.
|
28
21
|
class Action
|
29
|
-
include
|
22
|
+
include BasicLogging
|
30
23
|
|
31
24
|
class ActionError < StandardError
|
32
25
|
end
|
33
26
|
|
34
27
|
attr_accessor :name, :key, :proc, :global, :hidden
|
35
28
|
|
29
|
+
# return a string representation of the action
|
36
30
|
def to_s
|
37
31
|
"[#<" << classname << ':' << hash << '@name="' << name << '", @key="' << key << '">'
|
38
32
|
end
|
39
33
|
|
40
|
-
|
34
|
+
# create an action
|
41
35
|
def initialize(options = {}, &b)
|
42
|
-
init_logger(STDOUT, Logger::INFO)
|
43
|
-
|
44
36
|
@name = options[:name]
|
45
37
|
@key = options[:key]
|
46
38
|
@proc = b if b
|
@@ -48,6 +40,7 @@ class Action
|
|
48
40
|
@hidden = options[:hidden]
|
49
41
|
end
|
50
42
|
|
43
|
+
# execute te action
|
51
44
|
def call(*args)
|
52
45
|
unless @proc
|
53
46
|
raise ActionError.new((@name ? '' : 'Unnamed ') << 'action' << (@name ? (' ' << @name) : '') << ' called before a command was defined')
|
@@ -55,3 +48,4 @@ class Action
|
|
55
48
|
@proc.call(*args)
|
56
49
|
end
|
57
50
|
end
|
51
|
+
# Ω
|
@@ -0,0 +1,178 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2023-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
|
+
* *
|
7
|
+
* This program is free software; you can redistribute it and/or modify *
|
8
|
+
* it under the terms of the WTFPL 2.0 or later, see *
|
9
|
+
* http://www.wtfpl.net/about/ *
|
10
|
+
* *
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
14
|
+
* *
|
15
|
+
***************************************************************************/
|
16
|
+
=end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Simplified logging.
|
20
|
+
# See example code at the bottom of this file.
|
21
|
+
# Execute this file to see the output.
|
22
|
+
#
|
23
|
+
|
24
|
+
#require 'time'
|
25
|
+
|
26
|
+
module BasicLogging
|
27
|
+
|
28
|
+
DEBUG = 0
|
29
|
+
INFO = 1
|
30
|
+
WARN = 2
|
31
|
+
ERROR = 3
|
32
|
+
FATAL = 4
|
33
|
+
UNKNOWN = nil
|
34
|
+
|
35
|
+
# this is mainly for the translation of method calls into log levels
|
36
|
+
Levels = {:debug => DEBUG, :info => INFO, :warn => WARN, :error => ERROR,
|
37
|
+
:fatal => FATAL, :unknown => UNKNOWN}
|
38
|
+
|
39
|
+
@@log_level = UNKNOWN
|
40
|
+
@@target = STDOUT
|
41
|
+
@@muted = []
|
42
|
+
|
43
|
+
# do not log, if caller is obj (class or instance)
|
44
|
+
def self.mute(obj)
|
45
|
+
name = obj.class == Class ? obj.name.dup : obj.class.name
|
46
|
+
@@muted << name
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.is_muted?(obj)
|
50
|
+
name = obj.class == Class ? obj.name.dup : obj.class.name
|
51
|
+
@@muted.include?(name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# set the log level
|
55
|
+
def self::set_level(lv)
|
56
|
+
if lv.respond_to?(:to_str)
|
57
|
+
lv = Levels[lv.to_sym]
|
58
|
+
end
|
59
|
+
if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
|
60
|
+
@@log_level = lv
|
61
|
+
else
|
62
|
+
STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
|
63
|
+
STDERR.puts "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_level(lv)
|
68
|
+
BasicLogging::set_level(lv)
|
69
|
+
end
|
70
|
+
|
71
|
+
# set the log target
|
72
|
+
def self::set_target(tg)
|
73
|
+
if tg.respond_to?(:to_io)
|
74
|
+
@@target = tg
|
75
|
+
elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
|
76
|
+
@@target = File.open(tg, 'w+')
|
77
|
+
else
|
78
|
+
STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
|
79
|
+
STDERR.puts "Keeping old target " << @@target.inspect
|
80
|
+
return
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_target(tg)
|
85
|
+
BasicLogging::set_target(tg)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Output of log messages, depending on the log level set for the calling class
|
89
|
+
# and the name of the alias method which is actually called.
|
90
|
+
def log(message)
|
91
|
+
if !BasicLogging.is_muted?(self)
|
92
|
+
# how has this method been called?
|
93
|
+
mlevel = __callee__
|
94
|
+
if Levels.has_key?(mlevel) && Levels[mlevel] <= FATAL
|
95
|
+
# output only for levels equal or above the value that corresponds to
|
96
|
+
# the calling alias.
|
97
|
+
format_log( message, mlevel) if @@log_level && Levels[mlevel] >= @@log_level
|
98
|
+
else
|
99
|
+
STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
alias :debug :log
|
105
|
+
alias :info :log
|
106
|
+
alias :warn :log
|
107
|
+
alias :error :log
|
108
|
+
alias :fatal :log
|
109
|
+
|
110
|
+
attr_reader :target, :log_level
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
# 1 format_log for all loggers.
|
115
|
+
def format_log(message, mlevel)
|
116
|
+
# indicate if a registered class or the registered object of a class is calling.
|
117
|
+
name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
|
118
|
+
@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message
|
119
|
+
end
|
120
|
+
end
|
121
|
+
#---------test: execute file----------
|
122
|
+
if $0 == __FILE__
|
123
|
+
Array.extend(BasicLogging)
|
124
|
+
Array.set_level(BasicLogging::INFO)
|
125
|
+
Array.info('TEST')
|
126
|
+
ar = Array.new
|
127
|
+
ar.extend(BasicLogging)
|
128
|
+
# --- no output :
|
129
|
+
l = __LINE__
|
130
|
+
ar.debug(l.next.to_s << ': debug-test 0')
|
131
|
+
# output
|
132
|
+
ar.set_level(BasicLogging::DEBUG)
|
133
|
+
l = __LINE__
|
134
|
+
ar.debug(l.next.to_s << ': debug-test 1')
|
135
|
+
|
136
|
+
obj = Object.new
|
137
|
+
obj.extend(BasicLogging)
|
138
|
+
obj.set_level(BasicLogging::DEBUG)
|
139
|
+
puts "--------debug-----------"
|
140
|
+
obj.debug('debug')
|
141
|
+
obj.info('info')
|
142
|
+
obj.warn('warn')
|
143
|
+
obj.error('error')
|
144
|
+
obj.fatal('fatal')
|
145
|
+
puts "--------info-----------"
|
146
|
+
obj.set_level("info")
|
147
|
+
obj.debug('debug')
|
148
|
+
obj.info('info')
|
149
|
+
obj.warn('warn')
|
150
|
+
obj.error('error')
|
151
|
+
obj.fatal('fatal')
|
152
|
+
puts "--------fatal-----------"
|
153
|
+
obj.set_level("fatal")
|
154
|
+
obj.debug('debug')
|
155
|
+
obj.info('info')
|
156
|
+
obj.warn('warn')
|
157
|
+
obj.error('error')
|
158
|
+
obj.fatal('fatal')
|
159
|
+
puts "--------UNKNOWN-----------"
|
160
|
+
obj.set_level(nil)
|
161
|
+
obj.debug('debug')
|
162
|
+
obj.info('info')
|
163
|
+
obj.warn('warn')
|
164
|
+
obj.error('error')
|
165
|
+
obj.fatal('fatal')
|
166
|
+
puts " ------ Output into file ----"
|
167
|
+
obj.set_target "/tmp/test_log.log"
|
168
|
+
puts " ------ INFO -----------"
|
169
|
+
obj.set_level BasicLogging::INFO
|
170
|
+
obj.info('info output')
|
171
|
+
|
172
|
+
obj.info('info output 2')
|
173
|
+
puts "---------- invalid -------"
|
174
|
+
obj.set_target "/dev/sr0"
|
175
|
+
obj.set_level "power"
|
176
|
+
end
|
177
|
+
|
178
|
+
# EOF
|
data/lib/cell.rb
CHANGED
@@ -1,27 +1,19 @@
|
|
1
1
|
#encoding: UTF-8
|
2
|
-
|
3
2
|
=begin
|
4
3
|
/***************************************************************************
|
5
|
-
*
|
4
|
+
* ©2016-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
5
|
* *
|
7
6
|
* This program is free software; you can redistribute it and/or modify *
|
8
|
-
* it under the terms of the
|
9
|
-
*
|
10
|
-
* (at your option) any later version. *
|
7
|
+
* it under the terms of the WTFPL 2.0 or later, see *
|
8
|
+
* http://www.wtfpl.net/about/ *
|
11
9
|
* *
|
12
10
|
* This program is distributed in the hope that it will be useful, *
|
13
11
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
14
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
15
|
-
* GNU General Public License for more details. *
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
16
13
|
* *
|
17
|
-
* You should have received a copy of the GNU General Public License *
|
18
|
-
* along with this program; if not, write to the *
|
19
|
-
* Free Software Foundation, Inc., *
|
20
|
-
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
21
14
|
***************************************************************************/
|
22
15
|
=end
|
23
|
-
|
24
|
-
require_relative 'logging'
|
16
|
+
require_relative 'basic_logging'
|
25
17
|
require_relative 'row'
|
26
18
|
require_relative 'column'
|
27
19
|
|
@@ -32,33 +24,37 @@ class Cell
|
|
32
24
|
@@DEF_TYPE=Integer
|
33
25
|
@@split_pattern = nil
|
34
26
|
|
35
|
-
|
36
|
-
@@log = self.init_logger
|
27
|
+
include BasicLogging
|
37
28
|
|
29
|
+
# create a cell in co:row and enter a value
|
38
30
|
def initialize(row = nil, col = nil, value = nil)
|
39
|
-
@log = @@log
|
40
31
|
@row = row if row
|
41
32
|
@col = col if col
|
33
|
+
@debinfo = '(' << @col.number.to_s << ':' << @row.number.to_s << ') '
|
42
34
|
@type_class = @@DEF_TYPE
|
43
35
|
@value = value
|
44
36
|
split_value
|
45
37
|
set_limits
|
46
38
|
@row.resize
|
47
|
-
|
39
|
+
debug(@debinfo << "cell.initialize, lines is #{@lines}, value is #{value}, ideal_width is #{@ideal_width}")
|
48
40
|
end
|
49
41
|
|
42
|
+
# returns self
|
50
43
|
def to_cell()
|
51
44
|
self
|
52
45
|
end
|
53
46
|
|
47
|
+
# return a line from the cell
|
54
48
|
def line(num = nil)
|
55
49
|
num && num < @lines.length ? @lines[num].to_s : ' ' if @lines && !@lines.empty?
|
56
50
|
end
|
57
51
|
|
52
|
+
# returns a string representation of the cell
|
58
53
|
def to_s
|
59
54
|
object_id.to_s << "{" << @row.number.to_s << ":" << @col.number.to_s << ", " << @lines.to_s << ", " << @ideal_height.to_s << ", " << @ideal_width.to_s << " }"
|
60
55
|
end
|
61
56
|
|
57
|
+
# resizes the cell to its ideal value.
|
62
58
|
def resize
|
63
59
|
@@split_pattern = nil
|
64
60
|
split_value
|
@@ -66,17 +62,20 @@ class Cell
|
|
66
62
|
@row.resize
|
67
63
|
end
|
68
64
|
|
65
|
+
# set the value of the cell
|
69
66
|
def value=(value)
|
70
67
|
@@split_pattern = nil
|
71
68
|
@value = value
|
72
69
|
split_value
|
73
|
-
|
70
|
+
debug(@debinfo << 'after split_value, lines is ' << @lines.to_s)
|
74
71
|
end
|
75
72
|
|
73
|
+
# returns the column number of the cell
|
76
74
|
def col
|
77
75
|
@col.number
|
78
76
|
end
|
79
|
-
|
77
|
+
|
78
|
+
# returns the row number of the cell
|
80
79
|
def row
|
81
80
|
@row.number
|
82
81
|
end
|
@@ -85,6 +84,9 @@ class Cell
|
|
85
84
|
|
86
85
|
private
|
87
86
|
|
87
|
+
# handle long values in a way to make part of them
|
88
|
+
# visible, hide the remainder, if the cell ist too
|
89
|
+
# small.
|
88
90
|
def split_value()
|
89
91
|
# The regex may be used in many cells. Define on class-level.
|
90
92
|
# And...
|
@@ -109,6 +111,7 @@ class Cell
|
|
109
111
|
@row.resize
|
110
112
|
end
|
111
113
|
|
114
|
+
# Determines the ideal height and width of the cell
|
112
115
|
def set_limits
|
113
116
|
if @lines && !@lines.empty?
|
114
117
|
@ideal_height = @lines.length
|
data/lib/color_output.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
#encoding 'UTF-8'
|
2
2
|
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2016-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
|
+
* *
|
7
|
+
* This program is free software; you can redistribute it and/or modify *
|
8
|
+
* it under the terms of the WTFPL 2.0 or later, see *
|
9
|
+
* http://www.wtfpl.net/about/ *
|
10
|
+
* *
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
14
|
+
* *
|
15
|
+
***************************************************************************/
|
16
|
+
=end
|
17
|
+
|
18
|
+
|
3
19
|
# functions to apply colors to terminal output
|
4
20
|
|
5
21
|
COLORS = {:default => 9, :black => 0, :red => 1, :green => 2, :yellow => 3, :blue => 4, :purple => 5, :cyan => 6, :white => 7 }
|
data/lib/column.rb
CHANGED
@@ -2,44 +2,37 @@
|
|
2
2
|
|
3
3
|
=begin
|
4
4
|
/***************************************************************************
|
5
|
-
*
|
5
|
+
* ©2016-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
6
|
* *
|
7
7
|
* This program is free software; you can redistribute it and/or modify *
|
8
|
-
* it under the terms of the
|
9
|
-
*
|
10
|
-
* (at your option) any later version. *
|
8
|
+
* it under the terms of the WTFPL 2.0 or later, see *
|
9
|
+
* http://www.wtfpl.net/about/ *
|
11
10
|
* *
|
12
11
|
* This program is distributed in the hope that it will be useful, *
|
13
12
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
14
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
15
|
-
* GNU General Public License for more details. *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
16
14
|
* *
|
17
|
-
* You should have received a copy of the GNU General Public License *
|
18
|
-
* along with this program; if not, write to the *
|
19
|
-
* Free Software Foundation, Inc., *
|
20
|
-
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
21
15
|
***************************************************************************/
|
22
16
|
=end
|
23
17
|
|
24
18
|
|
25
|
-
require_relative '
|
19
|
+
require_relative 'basic_logging'
|
26
20
|
|
27
21
|
# Objects of this class represent columns in a spreadsheet table
|
28
22
|
|
29
23
|
class Column
|
30
|
-
|
31
|
-
@@log = self.init_logger
|
24
|
+
include BasicLogging
|
32
25
|
@@DEF_WIDTH=15
|
33
26
|
@@col_width=@@DEF_WIDTH
|
34
27
|
@@columns = Array.new
|
35
28
|
def initialize(number = nil)
|
36
|
-
@log = @@log
|
37
29
|
@number = number
|
38
30
|
@cells = Array.new
|
39
31
|
@width = @@col_width
|
40
32
|
@@columns << self
|
41
33
|
end
|
42
|
-
|
34
|
+
|
35
|
+
# add a cell to the column
|
43
36
|
def add(cell)
|
44
37
|
n_cell = nil
|
45
38
|
if cell.respond_to?(:to_cell)
|
@@ -48,7 +41,7 @@ class Column
|
|
48
41
|
n_cell = Cell.new( cell, @number)
|
49
42
|
else
|
50
43
|
msg = 'For a new cell, a row-number must be specified'
|
51
|
-
|
44
|
+
error(yellow(msg))
|
52
45
|
raise StandardError(msg)
|
53
46
|
end
|
54
47
|
@cells.insert(n_cell.row, n_cell)
|
@@ -56,29 +49,34 @@ class Column
|
|
56
49
|
set_limits
|
57
50
|
end
|
58
51
|
|
52
|
+
# execute the block for each cell in the column
|
59
53
|
def each(&b)
|
60
54
|
@cells.each do |c|
|
61
55
|
yield(c)
|
62
56
|
end
|
63
57
|
end
|
64
58
|
|
59
|
+
# return the width of the column
|
65
60
|
def self::col_width
|
66
61
|
@@col_width
|
67
62
|
end
|
68
63
|
|
64
|
+
# set the column width to w
|
69
65
|
def self::col_width=(w)
|
70
66
|
@@col_width = w
|
71
|
-
@
|
67
|
+
debug(@number.to_s << ' ' <<"self::col_width=(#{w}), calling resize")
|
72
68
|
|
73
69
|
@@columns.each {|col| col.resize(w)}
|
74
70
|
end
|
75
71
|
|
72
|
+
# resize the column to width
|
76
73
|
def resize(width)
|
77
74
|
@width = width
|
78
|
-
@
|
75
|
+
debug(@number.to_s << ' ' <<'calling resize')
|
79
76
|
@cells.each {|cell| cell.resize}
|
80
77
|
end
|
81
78
|
|
79
|
+
# returns a string representation of the column
|
82
80
|
def to_s
|
83
81
|
'<' << self.class.name.dup << ':' << object_id.to_s << "{number=%s width=%s cells.length=}>" %[@number, @cells.length]
|
84
82
|
end
|
@@ -88,6 +86,7 @@ class Column
|
|
88
86
|
|
89
87
|
private
|
90
88
|
|
89
|
+
# determine ideal width of the column
|
91
90
|
def set_limits
|
92
91
|
@ideal_width = @cells.max{|c1, c2| c1.ideal_width <=> c2.ideal_width}.ideal_width
|
93
92
|
@ideal_width ||= @@DEF_WIDTH
|