viewworkbook 0.2 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/doc/html/viewworkbook.html +397 -517
- data/doc/license.txt +14 -674
- data/doc/man/viewworkbook.1.gz +0 -0
- data/doc/rst/viewworkbook.rst +70 -51
- data/lib/action.rb +4 -2
- data/lib/cell.rb +13 -1
- data/lib/column.rb +8 -3
- data/lib/menu.rb +4 -1
- data/lib/row.rb +5 -0
- data/lib/sheetdata.rb +5 -2
- data/lib/sheetinterface.rb +42 -33
- data/lib/user_input.rb +12 -10
- data/viewworkbook.gemspec +14 -7
- metadata +37 -18
data/doc/man/viewworkbook.1.gz
CHANGED
|
Binary file
|
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,75 +59,87 @@ 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
|
|
124
132
|
<michael.uplawski@uplawski.eu>
|
|
125
133
|
|
|
134
|
+
This document
|
|
135
|
+
-------------
|
|
136
|
+
.. _CC By-ND 4.0: https://creativecommons.org/licenses/by-nd/4.0/
|
|
137
|
+
.. |date| date::
|
|
138
|
+
|
|
139
|
+
©Michael Uplawski <michael.uplawski@uplawski.eu>
|
|
140
|
+
|
|
141
|
+
License: `CC BY-ND 4.0`_
|
|
142
|
+
|
|
143
|
+
Date: |date|
|
|
144
|
+
|
|
126
145
|
**Ω**
|
data/lib/action.rb
CHANGED
|
@@ -26,13 +26,13 @@ class Action
|
|
|
26
26
|
|
|
27
27
|
attr_accessor :name, :key, :proc, :global, :hidden
|
|
28
28
|
|
|
29
|
+
# return a string representation of the action
|
|
29
30
|
def to_s
|
|
30
31
|
"[#<" << classname << ':' << hash << '@name="' << name << '", @key="' << key << '">'
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
# create an action
|
|
34
35
|
def initialize(options = {}, &b)
|
|
35
|
-
|
|
36
36
|
@name = options[:name]
|
|
37
37
|
@key = options[:key]
|
|
38
38
|
@proc = b if b
|
|
@@ -40,6 +40,7 @@ class Action
|
|
|
40
40
|
@hidden = options[:hidden]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
# execute te action
|
|
43
44
|
def call(*args)
|
|
44
45
|
unless @proc
|
|
45
46
|
raise ActionError.new((@name ? '' : 'Unnamed ') << 'action' << (@name ? (' ' << @name) : '') << ' called before a command was defined')
|
|
@@ -47,3 +48,4 @@ class Action
|
|
|
47
48
|
@proc.call(*args)
|
|
48
49
|
end
|
|
49
50
|
end
|
|
51
|
+
# Ω
|
data/lib/cell.rb
CHANGED
|
@@ -26,6 +26,7 @@ class Cell
|
|
|
26
26
|
|
|
27
27
|
include BasicLogging
|
|
28
28
|
|
|
29
|
+
# create a cell in co:row and enter a value
|
|
29
30
|
def initialize(row = nil, col = nil, value = nil)
|
|
30
31
|
@row = row if row
|
|
31
32
|
@col = col if col
|
|
@@ -38,18 +39,22 @@ class Cell
|
|
|
38
39
|
debug(@debinfo << "cell.initialize, lines is #{@lines}, value is #{value}, ideal_width is #{@ideal_width}")
|
|
39
40
|
end
|
|
40
41
|
|
|
42
|
+
# returns self
|
|
41
43
|
def to_cell()
|
|
42
44
|
self
|
|
43
45
|
end
|
|
44
46
|
|
|
47
|
+
# return a line from the cell
|
|
45
48
|
def line(num = nil)
|
|
46
49
|
num && num < @lines.length ? @lines[num].to_s : ' ' if @lines && !@lines.empty?
|
|
47
50
|
end
|
|
48
51
|
|
|
52
|
+
# returns a string representation of the cell
|
|
49
53
|
def to_s
|
|
50
54
|
object_id.to_s << "{" << @row.number.to_s << ":" << @col.number.to_s << ", " << @lines.to_s << ", " << @ideal_height.to_s << ", " << @ideal_width.to_s << " }"
|
|
51
55
|
end
|
|
52
56
|
|
|
57
|
+
# resizes the cell to its ideal value.
|
|
53
58
|
def resize
|
|
54
59
|
@@split_pattern = nil
|
|
55
60
|
split_value
|
|
@@ -57,6 +62,7 @@ class Cell
|
|
|
57
62
|
@row.resize
|
|
58
63
|
end
|
|
59
64
|
|
|
65
|
+
# set the value of the cell
|
|
60
66
|
def value=(value)
|
|
61
67
|
@@split_pattern = nil
|
|
62
68
|
@value = value
|
|
@@ -64,10 +70,12 @@ class Cell
|
|
|
64
70
|
debug(@debinfo << 'after split_value, lines is ' << @lines.to_s)
|
|
65
71
|
end
|
|
66
72
|
|
|
73
|
+
# returns the column number of the cell
|
|
67
74
|
def col
|
|
68
75
|
@col.number
|
|
69
76
|
end
|
|
70
|
-
|
|
77
|
+
|
|
78
|
+
# returns the row number of the cell
|
|
71
79
|
def row
|
|
72
80
|
@row.number
|
|
73
81
|
end
|
|
@@ -76,6 +84,9 @@ class Cell
|
|
|
76
84
|
|
|
77
85
|
private
|
|
78
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.
|
|
79
90
|
def split_value()
|
|
80
91
|
# The regex may be used in many cells. Define on class-level.
|
|
81
92
|
# And...
|
|
@@ -100,6 +111,7 @@ class Cell
|
|
|
100
111
|
@row.resize
|
|
101
112
|
end
|
|
102
113
|
|
|
114
|
+
# Determines the ideal height and width of the cell
|
|
103
115
|
def set_limits
|
|
104
116
|
if @lines && !@lines.empty?
|
|
105
117
|
@ideal_height = @lines.length
|
data/lib/column.rb
CHANGED
|
@@ -31,7 +31,8 @@ class Column
|
|
|
31
31
|
@width = @@col_width
|
|
32
32
|
@@columns << self
|
|
33
33
|
end
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
# add a cell to the column
|
|
35
36
|
def add(cell)
|
|
36
37
|
n_cell = nil
|
|
37
38
|
if cell.respond_to?(:to_cell)
|
|
@@ -48,29 +49,32 @@ class Column
|
|
|
48
49
|
set_limits
|
|
49
50
|
end
|
|
50
51
|
|
|
52
|
+
# execute the block for each cell in the column
|
|
51
53
|
def each(&b)
|
|
52
54
|
@cells.each do |c|
|
|
53
55
|
yield(c)
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
|
|
59
|
+
# return the width of the column
|
|
57
60
|
def self::col_width
|
|
58
61
|
@@col_width
|
|
59
62
|
end
|
|
60
63
|
|
|
64
|
+
# set the column width to w
|
|
61
65
|
def self::col_width=(w)
|
|
62
66
|
@@col_width = w
|
|
63
|
-
debug(@number.to_s << ' ' <<"self::col_width=(#{w}), calling resize")
|
|
64
|
-
|
|
65
67
|
@@columns.each {|col| col.resize(w)}
|
|
66
68
|
end
|
|
67
69
|
|
|
70
|
+
# resize the column to width
|
|
68
71
|
def resize(width)
|
|
69
72
|
@width = width
|
|
70
73
|
debug(@number.to_s << ' ' <<'calling resize')
|
|
71
74
|
@cells.each {|cell| cell.resize}
|
|
72
75
|
end
|
|
73
76
|
|
|
77
|
+
# returns a string representation of the column
|
|
74
78
|
def to_s
|
|
75
79
|
'<' << self.class.name.dup << ':' << object_id.to_s << "{number=%s width=%s cells.length=}>" %[@number, @cells.length]
|
|
76
80
|
end
|
|
@@ -80,6 +84,7 @@ class Column
|
|
|
80
84
|
|
|
81
85
|
private
|
|
82
86
|
|
|
87
|
+
# determine ideal width of the column
|
|
83
88
|
def set_limits
|
|
84
89
|
@ideal_width = @cells.max{|c1, c2| c1.ideal_width <=> c2.ideal_width}.ideal_width
|
|
85
90
|
@ideal_width ||= @@DEF_WIDTH
|
data/lib/menu.rb
CHANGED
|
@@ -22,7 +22,6 @@ require_relative 'user_input'
|
|
|
22
22
|
|
|
23
23
|
# Shows options that the user can choose from.
|
|
24
24
|
# Options may be associated with sub-menus.
|
|
25
|
-
|
|
26
25
|
class Menu
|
|
27
26
|
include BasicLogging
|
|
28
27
|
|
|
@@ -33,6 +32,7 @@ class Menu
|
|
|
33
32
|
@@global_elements = []
|
|
34
33
|
@@hidden_elements = []
|
|
35
34
|
|
|
35
|
+
# create the menu
|
|
36
36
|
def initialize(options = {})
|
|
37
37
|
@elements = []
|
|
38
38
|
if(options && !options.respond_to?(:to_hash) )
|
|
@@ -42,10 +42,12 @@ class Menu
|
|
|
42
42
|
@key = options[:key] if options[:key]
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
# display menu
|
|
45
46
|
def call(*args)
|
|
46
47
|
show()
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
# add an action or sub menu to the menu
|
|
49
51
|
def add(element, pos = nil)
|
|
50
52
|
if(element.respond_to?(:call))
|
|
51
53
|
if(pos)
|
|
@@ -67,6 +69,7 @@ class Menu
|
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
private
|
|
72
|
+
# display menu and react to user input.
|
|
70
73
|
def show()
|
|
71
74
|
@elements.each do |ele|
|
|
72
75
|
name = ele.name.downcase
|
data/lib/row.rb
CHANGED
|
@@ -28,6 +28,7 @@ class Row
|
|
|
28
28
|
@height = 1
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# add a cell to the row
|
|
31
32
|
def add(cell)
|
|
32
33
|
n_cell = nil
|
|
33
34
|
if cell.respond_to?(:to_cell)
|
|
@@ -44,12 +45,15 @@ class Row
|
|
|
44
45
|
resize()
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
# execute block on each cell in the row
|
|
47
49
|
def each(&b)
|
|
48
50
|
@cells.each do |c|
|
|
49
51
|
yield(c)
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
# adapt the height of the row to the ideal height of the
|
|
56
|
+
# highest cell
|
|
53
57
|
def resize()
|
|
54
58
|
if(@cells && ! @cells.empty? )
|
|
55
59
|
if(@cells.length == 1 )
|
|
@@ -62,6 +66,7 @@ class Row
|
|
|
62
66
|
@height ||= @@DEF_HEIGHT
|
|
63
67
|
end
|
|
64
68
|
|
|
69
|
+
# returns a string representation of the row
|
|
65
70
|
def to_s
|
|
66
71
|
'#<' << self.class.name << ':' << object_id.to_s << "{number=%s height=%s cells.length=%s}" %[@number.to_s, @height.to_s, @cells.length.to_s]
|
|
67
72
|
end
|
data/lib/sheetdata.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
=begin
|
|
4
4
|
/***************************************************************************
|
|
5
|
-
* ©2016-
|
|
5
|
+
* ©2016-2025, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
|
6
6
|
* *
|
|
7
7
|
* This program is free software; you can redistribute it and/or modify *
|
|
8
8
|
* it under the terms of the WTFPL 2.0 or later, see *
|
|
@@ -21,7 +21,6 @@ require 'roo-xls'
|
|
|
21
21
|
|
|
22
22
|
require_relative 'basic_logging'
|
|
23
23
|
|
|
24
|
-
# Transforms a file into a Roo spreadsheet instance.
|
|
25
24
|
|
|
26
25
|
ODS_Magic = "OpenDocument Spreadsheet"
|
|
27
26
|
XLS_Magic = "Composite Document File V2 Document"
|
|
@@ -36,6 +35,9 @@ CSV_MIME = "text/plain"
|
|
|
36
35
|
# SoftMaker Office
|
|
37
36
|
PMDX_MIME = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
38
37
|
|
|
38
|
+
=begin
|
|
39
|
+
Transforms a file into a Roo spreadsheet instance.
|
|
40
|
+
=end
|
|
39
41
|
class SheetData
|
|
40
42
|
# logs on class level
|
|
41
43
|
self.extend BasicLogging
|
|
@@ -43,6 +45,7 @@ class SheetData
|
|
|
43
45
|
@@file = nil
|
|
44
46
|
@@workbook = nil
|
|
45
47
|
|
|
48
|
+
# returns a new workbook
|
|
46
49
|
def self::workbook(file)
|
|
47
50
|
@@file = file
|
|
48
51
|
if !@@workbook
|
data/lib/sheetinterface.rb
CHANGED
|
@@ -53,6 +53,7 @@ class SheetInterface
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def initialize(wb, num)
|
|
56
|
+
# set_level('debug')
|
|
56
57
|
@workbook = wb.sheet(num)
|
|
57
58
|
@menu = nil
|
|
58
59
|
@status = Status.new
|
|
@@ -60,6 +61,16 @@ class SheetInterface
|
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
private
|
|
64
|
+
=begin
|
|
65
|
+
Interrupts the screen refresh to display a debug message,
|
|
66
|
+
if the log level is BasicLogging::DEBUG.
|
|
67
|
+
=end
|
|
68
|
+
def pause_debug(text)
|
|
69
|
+
if @@log_level == BasicLogging::DEBUG
|
|
70
|
+
debug(text)
|
|
71
|
+
wait_for_user
|
|
72
|
+
end
|
|
73
|
+
end
|
|
63
74
|
=begin
|
|
64
75
|
returns [width, height] in columns and lines of the current
|
|
65
76
|
terminal-window.
|
|
@@ -68,7 +79,7 @@ class SheetInterface
|
|
|
68
79
|
size = `stty size`.split.map { |x| x.to_i }.reverse
|
|
69
80
|
return size
|
|
70
81
|
end
|
|
71
|
-
# Asks the user to enter a number, then verifies
|
|
82
|
+
# Asks the user to enter a number, then verifies against eventual
|
|
72
83
|
# constraints.
|
|
73
84
|
def ask_number(question, &constraint)
|
|
74
85
|
num = nil
|
|
@@ -190,8 +201,8 @@ class SheetInterface
|
|
|
190
201
|
end
|
|
191
202
|
|
|
192
203
|
if sn && !sn.to_s.empty?
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
pause_debug('calling workbook.sheet with ' << sn.to_s)
|
|
205
|
+
pause_debug('@workbook is of type ' << @workbook.class.name)
|
|
195
206
|
set_sheet(sn)
|
|
196
207
|
end
|
|
197
208
|
construct
|
|
@@ -208,10 +219,24 @@ class SheetInterface
|
|
|
208
219
|
save_Menu.add_action(Action.new(:name => 'current sheet', :key => 'c') do
|
|
209
220
|
file = new_file()
|
|
210
221
|
if(file)
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
num = 0
|
|
223
|
+
begin
|
|
224
|
+
content = draw(false)
|
|
225
|
+
pause_debug(__LINE__.to_s << 'have content – writing to ' << file)
|
|
226
|
+
num = File::write(file, content )
|
|
227
|
+
pause_debug(__LINE__.to_s << 'wrote ' << num.to_s << ' bytes')
|
|
228
|
+
rescue Exception => ex
|
|
229
|
+
@status.message = red( 'cannot write to ' << file << ': ' << ex.message)
|
|
230
|
+
# raise ex
|
|
231
|
+
end
|
|
232
|
+
if num > 0
|
|
233
|
+
@status.message = green('... done (' << num.to_s << ' bytes written)')
|
|
234
|
+
else
|
|
235
|
+
@status.message = red('Cannot write to ' << file << ' (' << num.to_s << ' bytes written)')
|
|
236
|
+
end
|
|
237
|
+
construct
|
|
213
238
|
end
|
|
214
|
-
|
|
239
|
+
# end action - close parenthesis
|
|
215
240
|
end)
|
|
216
241
|
|
|
217
242
|
save_Menu.add_action(Action.new(:name => 'all sheets', :key => 'a') do
|
|
@@ -223,12 +248,15 @@ class SheetInterface
|
|
|
223
248
|
begin
|
|
224
249
|
File::open(file, 'w+') do |out|
|
|
225
250
|
@workbook.sheets.each do |s|
|
|
226
|
-
debug('writing sheet ' << s)
|
|
227
251
|
set_sheet(s)
|
|
228
252
|
construct(false)
|
|
229
|
-
|
|
253
|
+
debug(__LINE__.to_s << 'writing sheet ' << s.to_s)
|
|
254
|
+
wait_for_user if @@log_level == BasicLogging::DEBUG
|
|
255
|
+
out.write draw(false)
|
|
230
256
|
end
|
|
231
257
|
end
|
|
258
|
+
rescue Errno => ex
|
|
259
|
+
@status.message = red(__LINE__.dup << 'cannot write to ' << file << ':' << ex.message )
|
|
232
260
|
rescue Interrupt
|
|
233
261
|
puts bold(red("Interrupted by user. Bye!"))
|
|
234
262
|
exit true
|
|
@@ -237,6 +265,7 @@ class SheetInterface
|
|
|
237
265
|
end
|
|
238
266
|
set_sheet(current_sheet)
|
|
239
267
|
construct
|
|
268
|
+
# end action - close parenthesis
|
|
240
269
|
end)
|
|
241
270
|
|
|
242
271
|
col_Menu = Menu.new(:name=>'column', :key => 'c')
|
|
@@ -255,7 +284,7 @@ class SheetInterface
|
|
|
255
284
|
if(@rows[row] && @columns[col])
|
|
256
285
|
cell = @rows[row].cells.detect {|c| c.col == col}
|
|
257
286
|
if(cell)
|
|
258
|
-
@status.message = "#{cell_coord[0].upcase}:#{cell_coord[1]} is \"" << cell.value.to_s << "\" (%d)" %cell.value.to_s.length
|
|
287
|
+
@status.message = yellow("value in #{cell_coord[0].upcase}:#{cell_coord[1]} is \"" << cell.value.to_s << "\" (%d)" %cell.value.to_s.length)
|
|
259
288
|
else
|
|
260
289
|
@status.message = red('invalid cell')
|
|
261
290
|
end
|
|
@@ -280,10 +309,12 @@ class SheetInterface
|
|
|
280
309
|
end
|
|
281
310
|
# This is hard to describe.
|
|
282
311
|
# The function basically draws a table on screen.
|
|
283
|
-
def draw(
|
|
312
|
+
def draw(on_screen = true)
|
|
284
313
|
if(@rows && !@rows.empty?)
|
|
285
314
|
# Welcome to hell.
|
|
286
|
-
|
|
315
|
+
debug 'drawing on screen' if on_screen
|
|
316
|
+
wait_for_user if on_screen && @@log_level == BasicLogging::DEBUG
|
|
317
|
+
|
|
287
318
|
col_w = Column::col_width
|
|
288
319
|
num_c = @rows[0].cells.length()
|
|
289
320
|
num_r = @rows.length
|
|
@@ -294,46 +325,33 @@ class SheetInterface
|
|
|
294
325
|
#-----
|
|
295
326
|
|
|
296
327
|
table_view << @workbook.default_sheet << "\n"
|
|
297
|
-
#out.puts @workbook.default_sheet
|
|
298
328
|
table_view << ('┌' << '─' * num_r.to_s.length << '┬' << (('─' * col_w) << '┬' ) * (num_c -1) ) << (('─' * col_w) << '┐' ) << "\n"
|
|
299
|
-
# out.puts ('┌' << '─' * num_r.to_s.length << '┬' << (('─' * col_w) << '┬' ) * (num_c -1) ) << (('─' * col_w) << '┐' )
|
|
300
329
|
lh = 0
|
|
301
330
|
@rows.each do |row|
|
|
302
331
|
|
|
303
332
|
if(row == @rows.first)
|
|
304
333
|
ch = 'A'
|
|
305
334
|
table_view << "│%#{num_r.to_s.length}s" %" "
|
|
306
|
-
#out.print "│%#{num_r.to_s.length}s" %" "
|
|
307
335
|
table_view << '│'
|
|
308
|
-
# out.print '│'
|
|
309
336
|
row.each do |c|
|
|
310
337
|
head = "%#{col_w}s" %ch
|
|
311
338
|
head = bold(head) if(on_screen)
|
|
312
|
-
# out.print(head << "|")
|
|
313
339
|
table_view << (head << "│")
|
|
314
340
|
ch = ch.next
|
|
315
341
|
end
|
|
316
|
-
# out.puts
|
|
317
342
|
table_view << "\n"
|
|
318
343
|
hline = ('├' << ('─' * (num_r.to_s.length) ) <<'┼' << (('─' * col_w) << '┼' ) * (num_c - 1) ) << (('─' * col_w) << '┤')if !hline
|
|
319
344
|
table_view << hline << "\n"
|
|
320
|
-
# out.puts hline
|
|
321
345
|
end
|
|
322
346
|
lh += 1
|
|
323
347
|
table_view << "│"
|
|
324
|
-
# out.print "│"
|
|
325
348
|
line_head = "%#{num_r.to_s.length}s" %lh.to_s
|
|
326
349
|
line_head = bold(line_head) if on_screen
|
|
327
350
|
table_view << line_head
|
|
328
|
-
# out.print line_head
|
|
329
|
-
|
|
330
|
-
# out.print "│" << bold("%#{num_r.to_s.length}s" %line_head)
|
|
331
351
|
|
|
332
352
|
row.height.times do |li|
|
|
333
353
|
table_view << "│%#{num_r.to_s.length}s" %" " if li > 0
|
|
334
|
-
# out.print "│%#{num_r.to_s.length}s" %" " if li > 0
|
|
335
354
|
table_view << '│'
|
|
336
|
-
# out.print '│'
|
|
337
355
|
row.each do |cell|
|
|
338
356
|
line = cell.line(li)
|
|
339
357
|
content = "%#{col_w}s│" %line
|
|
@@ -341,15 +359,12 @@ class SheetInterface
|
|
|
341
359
|
content = red(content)
|
|
342
360
|
end
|
|
343
361
|
table_view << content
|
|
344
|
-
# out.print content
|
|
345
362
|
end
|
|
346
363
|
table_view << "\n"
|
|
347
|
-
# out.puts
|
|
348
364
|
end
|
|
349
365
|
hlline = ('│' << (('─' * col_w) << '│' ) * num_c ) if !hline
|
|
350
366
|
|
|
351
367
|
table_view << hline << "\n"
|
|
352
|
-
# out.puts hline
|
|
353
368
|
|
|
354
369
|
# Some of the following code may go to a function as it repeats the
|
|
355
370
|
# procedure from the beginning of the table. I am currently unwilling to
|
|
@@ -359,26 +374,20 @@ class SheetInterface
|
|
|
359
374
|
if(row == @rows.last)
|
|
360
375
|
ch = 'A'
|
|
361
376
|
table_view << "│%#{num_r.to_s.length}s" %" "
|
|
362
|
-
# out.print "│%#{num_r.to_s.length}s" %" "
|
|
363
377
|
table_view << '│'
|
|
364
|
-
# out.print '│'
|
|
365
378
|
row.each do |c|
|
|
366
379
|
head = "%#{col_w}s" %ch
|
|
367
380
|
head = bold(head) if on_screen
|
|
368
381
|
table_view << ( head << '│')
|
|
369
|
-
# out.print( head << '│')
|
|
370
382
|
ch = ch.next
|
|
371
383
|
end
|
|
372
384
|
table_view << "\n"
|
|
373
|
-
# out.puts
|
|
374
385
|
hline = ('└' << ('─' * (num_r.to_s.length) ) << '┴' << (('─' * col_w) << '┴' ) * (num_c - 1) ) << (('─' * col_w) << '┘' )
|
|
375
386
|
|
|
376
387
|
table_view << hline << "\n"
|
|
377
|
-
# out.puts hline
|
|
378
388
|
end
|
|
379
389
|
|
|
380
390
|
end
|
|
381
|
-
|
|
382
391
|
return table_view
|
|
383
392
|
else
|
|
384
393
|
return nil
|