write_xlsx 0.0.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/.document +5 -0
- data/.gitattributes +1 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +78 -0
- data/VERSION +1 -0
- data/examples/a_simple.rb +45 -0
- data/examples/array_formula.rb +33 -0
- data/examples/autofilter.rb +235 -0
- data/examples/chart_area.rb +59 -0
- data/examples/chart_bar.rb +59 -0
- data/examples/chart_column.rb +58 -0
- data/examples/chart_line.rb +59 -0
- data/examples/chart_pie.rb +49 -0
- data/examples/chart_scatter.rb +59 -0
- data/examples/chart_stock.rb +65 -0
- data/examples/colors.rb +130 -0
- data/examples/comments1.rb +12 -0
- data/examples/comments2.rb +335 -0
- data/examples/conditional_format.rb +67 -0
- data/examples/data_validate.rb +279 -0
- data/examples/defined_name.rb +28 -0
- data/examples/demo.rb +104 -0
- data/examples/diag_border.rb +26 -0
- data/examples/headers.rb +119 -0
- data/examples/hide_sheet.rb +30 -0
- data/examples/hyperlink1.rb +58 -0
- data/examples/indent.rb +28 -0
- data/examples/merge1.rb +38 -0
- data/examples/merge2.rb +48 -0
- data/examples/merge3.rb +43 -0
- data/examples/merge4.rb +82 -0
- data/examples/merge5.rb +70 -0
- data/examples/merge6.rb +48 -0
- data/examples/outline.rb +252 -0
- data/examples/properties.rb +33 -0
- data/examples/protection.rb +34 -0
- data/examples/rich_strings.rb +42 -0
- data/examples/right_to_left.rb +24 -0
- data/examples/tab_colors.rb +26 -0
- data/lib/write_xlsx.rb +77 -0
- data/lib/write_xlsx/chart.rb +3027 -0
- data/lib/write_xlsx/chart/area.rb +52 -0
- data/lib/write_xlsx/chart/bar.rb +126 -0
- data/lib/write_xlsx/chart/column.rb +132 -0
- data/lib/write_xlsx/chart/line.rb +51 -0
- data/lib/write_xlsx/chart/pie.rb +210 -0
- data/lib/write_xlsx/chart/scatter.rb +252 -0
- data/lib/write_xlsx/chart/stock.rb +134 -0
- data/lib/write_xlsx/chartsheet.rb +173 -0
- data/lib/write_xlsx/colors.rb +65 -0
- data/lib/write_xlsx/compatibility.rb +71 -0
- data/lib/write_xlsx/drawing.rb +547 -0
- data/lib/write_xlsx/format.rb +683 -0
- data/lib/write_xlsx/package/app.rb +218 -0
- data/lib/write_xlsx/package/comments.rb +221 -0
- data/lib/write_xlsx/package/content_types.rb +189 -0
- data/lib/write_xlsx/package/core.rb +196 -0
- data/lib/write_xlsx/package/packager.rb +510 -0
- data/lib/write_xlsx/package/relationships.rb +98 -0
- data/lib/write_xlsx/package/shared_strings.rb +96 -0
- data/lib/write_xlsx/package/styles.rb +705 -0
- data/lib/write_xlsx/package/theme.rb +45 -0
- data/lib/write_xlsx/package/vml.rb +386 -0
- data/lib/write_xlsx/package/xml_writer_simple.rb +90 -0
- data/lib/write_xlsx/utility.rb +113 -0
- data/lib/write_xlsx/workbook.rb +1488 -0
- data/lib/write_xlsx/worksheet.rb +6578 -0
- data/lib/write_xlsx/zip_file_utils.rb +98 -0
- data/test/chart/test_add_series.rb +113 -0
- data/test/chart/test_process_names.rb +27 -0
- data/test/chart/test_write_auto.rb +15 -0
- data/test/chart/test_write_ax_id.rb +15 -0
- data/test/chart/test_write_ax_pos.rb +15 -0
- data/test/chart/test_write_chart_space.rb +15 -0
- data/test/chart/test_write_cross_ax.rb +15 -0
- data/test/chart/test_write_crosses.rb +15 -0
- data/test/chart/test_write_format_code.rb +15 -0
- data/test/chart/test_write_idx.rb +15 -0
- data/test/chart/test_write_label_align.rb +15 -0
- data/test/chart/test_write_label_offset.rb +15 -0
- data/test/chart/test_write_lang.rb +15 -0
- data/test/chart/test_write_layout.rb +15 -0
- data/test/chart/test_write_legend.rb +16 -0
- data/test/chart/test_write_legend_pos.rb +15 -0
- data/test/chart/test_write_major_gridlines.rb +15 -0
- data/test/chart/test_write_marker.rb +17 -0
- data/test/chart/test_write_marker_size.rb +15 -0
- data/test/chart/test_write_marker_value.rb +16 -0
- data/test/chart/test_write_num_cache.rb +16 -0
- data/test/chart/test_write_num_fmt.rb +16 -0
- data/test/chart/test_write_number_format.rb +15 -0
- data/test/chart/test_write_order.rb +15 -0
- data/test/chart/test_write_orientation.rb +15 -0
- data/test/chart/test_write_page_margins.rb +15 -0
- data/test/chart/test_write_page_setup.rb +15 -0
- data/test/chart/test_write_plot_vis_only.rb +15 -0
- data/test/chart/test_write_pt.rb +16 -0
- data/test/chart/test_write_pt_count.rb +16 -0
- data/test/chart/test_write_series_formula.rb +16 -0
- data/test/chart/test_write_style.rb +41 -0
- data/test/chart/test_write_symbol.rb +16 -0
- data/test/chart/test_write_tick_lbl_pos.rb +16 -0
- data/test/chart/test_write_v.rb +16 -0
- data/test/drawing/test_drawing_chart_01.rb +50 -0
- data/test/drawing/test_drawing_image_01.rb +59 -0
- data/test/helper.rb +90 -0
- data/test/package/app/test_app01.rb +44 -0
- data/test/package/app/test_app02.rb +46 -0
- data/test/package/app/test_app03.rb +53 -0
- data/test/package/comments/test_comments01.rb +36 -0
- data/test/package/comments/test_write_text_t.rb +44 -0
- data/test/package/content_types/test_content_types.rb +35 -0
- data/test/package/content_types/test_write_default.rb +13 -0
- data/test/package/content_types/test_write_override.rb +13 -0
- data/test/package/core/test_core01.rb +28 -0
- data/test/package/core/test_core02.rb +42 -0
- data/test/package/relationships/test_relationships.rb +28 -0
- data/test/package/relationships/test_sheet_rels.rb +22 -0
- data/test/package/shared_strings/test_shared_strings01.rb +30 -0
- data/test/package/shared_strings/test_shared_strings02.rb +30 -0
- data/test/package/shared_strings/test_write_si.rb +13 -0
- data/test/package/shared_strings/test_write_sst.rb +15 -0
- data/test/package/styles/test_styles_01.rb +69 -0
- data/test/package/styles/test_styles_02.rb +104 -0
- data/test/package/styles/test_styles_03.rb +90 -0
- data/test/package/styles/test_styles_04.rb +216 -0
- data/test/package/styles/test_styles_05.rb +150 -0
- data/test/package/styles/test_styles_06.rb +104 -0
- data/test/package/styles/test_styles_07.rb +104 -0
- data/test/package/styles/test_styles_08.rb +109 -0
- data/test/package/styles/test_styles_09.rb +95 -0
- data/test/package/vml/test_vml_01.rb +42 -0
- data/test/package/vml/test_write_anchor.rb +14 -0
- data/test/package/vml/test_write_auto_fill.rb +14 -0
- data/test/package/vml/test_write_column.rb +14 -0
- data/test/package/vml/test_write_div.rb +14 -0
- data/test/package/vml/test_write_fill.rb +14 -0
- data/test/package/vml/test_write_idmap.rb +14 -0
- data/test/package/vml/test_write_move_with_cells.rb +14 -0
- data/test/package/vml/test_write_path.rb +22 -0
- data/test/package/vml/test_write_row.rb +14 -0
- data/test/package/vml/test_write_shadow.rb +14 -0
- data/test/package/vml/test_write_shapelayout.rb +14 -0
- data/test/package/vml/test_write_shapetype.rb +14 -0
- data/test/package/vml/test_write_size_with_cells.rb +14 -0
- data/test/package/vml/test_write_stroke.rb +14 -0
- data/test/package/vml/test_write_textbox.rb +14 -0
- data/test/perl_output/a_simple.xlsx +0 -0
- data/test/perl_output/array_formula.xlsx +0 -0
- data/test/perl_output/autofilter.xlsx +0 -0
- data/test/perl_output/chart_area.xlsx +0 -0
- data/test/perl_output/chart_bar.xlsx +0 -0
- data/test/perl_output/chart_column.xlsx +0 -0
- data/test/perl_output/chart_line.xlsx +0 -0
- data/test/perl_output/chart_pie.xlsx +0 -0
- data/test/perl_output/chart_scatter.xlsx +0 -0
- data/test/perl_output/chart_stock.xlsx +0 -0
- data/test/perl_output/comments1.xlsx +0 -0
- data/test/perl_output/comments2.xlsx +0 -0
- data/test/perl_output/conditional_format.xlsx +0 -0
- data/test/perl_output/data_validate.xlsx +0 -0
- data/test/perl_output/defined_name.xlsx +0 -0
- data/test/perl_output/demo.xlsx +0 -0
- data/test/perl_output/diag_border.xlsx +0 -0
- data/test/perl_output/fit_to_pages.xlsx +0 -0
- data/test/perl_output/headers.xlsx +0 -0
- data/test/perl_output/hide_sheet.xlsx +0 -0
- data/test/perl_output/hyperlink.xlsx +0 -0
- data/test/perl_output/indent.xlsx +0 -0
- data/test/perl_output/merge1.xlsx +0 -0
- data/test/perl_output/merge2.xlsx +0 -0
- data/test/perl_output/merge3.xlsx +0 -0
- data/test/perl_output/merge4.xlsx +0 -0
- data/test/perl_output/merge5.xlsx +0 -0
- data/test/perl_output/merge6.xlsx +0 -0
- data/test/perl_output/outline.xlsx +0 -0
- data/test/perl_output/print_scale.xlsx +0 -0
- data/test/perl_output/properties.xlsx +0 -0
- data/test/perl_output/protection.xlsx +0 -0
- data/test/perl_output/rich_strings.xlsx +0 -0
- data/test/perl_output/right_to_left.xlsx +0 -0
- data/test/perl_output/tab_colors.xlsx +0 -0
- data/test/test_delete_files.rb +37 -0
- data/test/test_example_match.rb +2281 -0
- data/test/test_xml_writer_simple.rb +63 -0
- data/test/workbook/test_get_chart_range.rb +59 -0
- data/test/workbook/test_sort_defined_names.rb +77 -0
- data/test/workbook/test_workbook_01.rb +29 -0
- data/test/workbook/test_workbook_02.rb +31 -0
- data/test/workbook/test_workbook_03.rb +31 -0
- data/test/workbook/test_workbook_new.rb +18 -0
- data/test/workbook/test_write_defined_name.rb +17 -0
- data/test/workbook/test_write_defined_names.rb +41 -0
- data/test/worksheet/test_calculate_spans.rb +58 -0
- data/test/worksheet/test_convert_date_time_01.rb +439 -0
- data/test/worksheet/test_convert_date_time_02.rb +478 -0
- data/test/worksheet/test_convert_date_time_03.rb +435 -0
- data/test/worksheet/test_extract_filter_tokens.rb +109 -0
- data/test/worksheet/test_parse_filter_expression.rb +143 -0
- data/test/worksheet/test_position_object.rb +50 -0
- data/test/worksheet/test_repeat_formula.rb +55 -0
- data/test/worksheet/test_worksheet_01.rb +32 -0
- data/test/worksheet/test_worksheet_02.rb +38 -0
- data/test/worksheet/test_worksheet_03.rb +44 -0
- data/test/worksheet/test_worksheet_04.rb +45 -0
- data/test/worksheet/test_write_array_formula_01.rb +99 -0
- data/test/worksheet/test_write_autofilter.rb +260 -0
- data/test/worksheet/test_write_brk.rb +18 -0
- data/test/worksheet/test_write_cell.rb +49 -0
- data/test/worksheet/test_write_cell_value.rb +33 -0
- data/test/worksheet/test_write_col_breaks.rb +27 -0
- data/test/worksheet/test_write_col_info.rb +95 -0
- data/test/worksheet/test_write_conditional_formatting.rb +72 -0
- data/test/worksheet/test_write_custom_filter.rb +18 -0
- data/test/worksheet/test_write_custom_filters.rb +25 -0
- data/test/worksheet/test_write_data_validation_01.rb +113 -0
- data/test/worksheet/test_write_data_validation_02.rb +528 -0
- data/test/worksheet/test_write_dimension.rb +94 -0
- data/test/worksheet/test_write_ext.rb +18 -0
- data/test/worksheet/test_write_ext_lst.rb +18 -0
- data/test/worksheet/test_write_filter.rb +18 -0
- data/test/worksheet/test_write_filter_column.rb +18 -0
- data/test/worksheet/test_write_filters.rb +32 -0
- data/test/worksheet/test_write_header_footer.rb +53 -0
- data/test/worksheet/test_write_hyperlink.rb +39 -0
- data/test/worksheet/test_write_hyperlinks.rb +27 -0
- data/test/worksheet/test_write_legacy_drawing.rb +19 -0
- data/test/worksheet/test_write_merge_cell.rb +18 -0
- data/test/worksheet/test_write_merge_cells.rb +192 -0
- data/test/worksheet/test_write_methods.rb +353 -0
- data/test/worksheet/test_write_mx_plv.rb +19 -0
- data/test/worksheet/test_write_page_margins.rb +98 -0
- data/test/worksheet/test_write_page_set_up_pr.rb +19 -0
- data/test/worksheet/test_write_page_setup.rb +54 -0
- data/test/worksheet/test_write_pane.rb +123 -0
- data/test/worksheet/test_write_phonetic_pr.rb +19 -0
- data/test/worksheet/test_write_print_options.rb +77 -0
- data/test/worksheet/test_write_row_breaks.rb +27 -0
- data/test/worksheet/test_write_row_element.rb +69 -0
- data/test/worksheet/test_write_selection.rb +18 -0
- data/test/worksheet/test_write_sheet_calc_pr.rb +18 -0
- data/test/worksheet/test_write_sheet_data.rb +18 -0
- data/test/worksheet/test_write_sheet_format_pr.rb +18 -0
- data/test/worksheet/test_write_sheet_pr.rb +36 -0
- data/test/worksheet/test_write_sheet_protection.rb +174 -0
- data/test/worksheet/test_write_sheet_view.rb +62 -0
- data/test/worksheet/test_write_sheet_view1.rb +64 -0
- data/test/worksheet/test_write_sheet_view2.rb +56 -0
- data/test/worksheet/test_write_sheet_view3.rb +83 -0
- data/test/worksheet/test_write_sheet_view4.rb +83 -0
- data/test/worksheet/test_write_sheet_view5.rb +74 -0
- data/test/worksheet/test_write_sheet_view6.rb +51 -0
- data/test/worksheet/test_write_sheet_view7.rb +71 -0
- data/test/worksheet/test_write_sheet_view8.rb +51 -0
- data/test/worksheet/test_write_sheet_view9.rb +51 -0
- data/test/worksheet/test_write_tab_color.rb +23 -0
- data/test/worksheet/test_write_worksheet.rb +19 -0
- data/write_xlsx.gemspec +308 -0
- metadata +363 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
module Writexlsx
|
|
3
|
+
# ==CELL FORMATTING
|
|
4
|
+
#
|
|
5
|
+
# This section describes the methods and properties that are available
|
|
6
|
+
# for formatting cells in Excel. The properties of a cell that can be
|
|
7
|
+
# formatted include: fonts, colours, patterns, borders, alignment and
|
|
8
|
+
# number formatting.
|
|
9
|
+
#
|
|
10
|
+
# ===Creating and using a Format object
|
|
11
|
+
#
|
|
12
|
+
# Cell formatting is defined through a Format object. Format objects
|
|
13
|
+
# are created by calling the workbook add_format() method as follows:
|
|
14
|
+
#
|
|
15
|
+
# format1 = workbook.add_format # Set properties later
|
|
16
|
+
# format2 = workbook.add_format(props_hash) # Set at creation
|
|
17
|
+
#
|
|
18
|
+
# The format object holds all the formatting properties that can be applied
|
|
19
|
+
# to a cell, a row or a column. The process of setting these properties is
|
|
20
|
+
# discussed in the next section.
|
|
21
|
+
#
|
|
22
|
+
# Once a Format object has been constructed and its properties have been
|
|
23
|
+
# set it can be passed as an argument to the worksheet write methods as
|
|
24
|
+
# follows:
|
|
25
|
+
#
|
|
26
|
+
# worksheet.write( 0, 0, 'One', format )
|
|
27
|
+
# worksheet.write_string( 1, 0, 'Two', format )
|
|
28
|
+
# worksheet.write_number( 2, 0, 3, format )
|
|
29
|
+
# worksheet.write_blank( 3, 0, format )
|
|
30
|
+
#
|
|
31
|
+
# Formats can also be passed to the worksheet set_row() and set_column()
|
|
32
|
+
# methods to define the default property for a row or column.
|
|
33
|
+
#
|
|
34
|
+
# worksheet.set_row( 0, 15, format )
|
|
35
|
+
# worksheet.set_column( 0, 0, 15, format )
|
|
36
|
+
#
|
|
37
|
+
# ===Format methods and Format properties
|
|
38
|
+
#
|
|
39
|
+
# The following table shows the Excel format categories, the formatting
|
|
40
|
+
# properties that can be applied and the equivalent object method:
|
|
41
|
+
#
|
|
42
|
+
# Category Description Property Method Name
|
|
43
|
+
# -------- ----------- -------- -----------
|
|
44
|
+
# Font Font type font set_font()
|
|
45
|
+
# Font size size set_size()
|
|
46
|
+
# Font color color set_color()
|
|
47
|
+
# Bold bold set_bold()
|
|
48
|
+
# Italic italic set_italic()
|
|
49
|
+
# Underline underline set_underline()
|
|
50
|
+
# Strikeout font_strikeout set_font_strikeout()
|
|
51
|
+
# Super/Subscript font_script set_font_script()
|
|
52
|
+
# Outline font_outline set_font_outline()
|
|
53
|
+
# Shadow font_shadow set_font_shadow()
|
|
54
|
+
#
|
|
55
|
+
# Number Numeric format num_format set_num_format()
|
|
56
|
+
#
|
|
57
|
+
# Protection Lock cells locked set_locked()
|
|
58
|
+
# Hide formulas hidden set_hidden()
|
|
59
|
+
#
|
|
60
|
+
# Alignment Horizontal align align set_align()
|
|
61
|
+
# Vertical align valign set_align()
|
|
62
|
+
# Rotation rotation set_rotation()
|
|
63
|
+
# Text wrap text_wrap set_text_wrap()
|
|
64
|
+
# Justify last text_justlast set_text_justlast()
|
|
65
|
+
# Center across center_across set_center_across()
|
|
66
|
+
# Indentation indent set_indent()
|
|
67
|
+
# Shrink to fit shrink set_shrink()
|
|
68
|
+
#
|
|
69
|
+
# Pattern Cell pattern pattern set_pattern()
|
|
70
|
+
# Background color bg_color set_bg_color()
|
|
71
|
+
# Foreground color fg_color set_fg_color()
|
|
72
|
+
#
|
|
73
|
+
# Border Cell border border set_border()
|
|
74
|
+
# Bottom border bottom set_bottom()
|
|
75
|
+
# Top border top set_top()
|
|
76
|
+
# Left border left set_left()
|
|
77
|
+
# Right border right set_right()
|
|
78
|
+
# Border color border_color set_border_color()
|
|
79
|
+
# Bottom color bottom_color set_bottom_color()
|
|
80
|
+
# Top color top_color set_top_color()
|
|
81
|
+
# Left color left_color set_left_color()
|
|
82
|
+
# Right color right_color set_right_color()
|
|
83
|
+
#
|
|
84
|
+
# There are two ways of setting Format properties: by using the object
|
|
85
|
+
# method interface or by setting the property directly. For example,
|
|
86
|
+
# a typical use of the method interface would be as follows:
|
|
87
|
+
#
|
|
88
|
+
# format = workbook.add_format
|
|
89
|
+
# format.set_bold
|
|
90
|
+
# format.set_color( 'red' )
|
|
91
|
+
#
|
|
92
|
+
# By comparison the properties can be set directly by passing a hash
|
|
93
|
+
# of properties to the Format constructor:
|
|
94
|
+
#
|
|
95
|
+
# format = workbook.add_format( :bold => 1, :color => 'red' )
|
|
96
|
+
#
|
|
97
|
+
# or after the Format has been constructed by means of the
|
|
98
|
+
# set_format_properties() method as follows:
|
|
99
|
+
#
|
|
100
|
+
# format = workbook.add_format
|
|
101
|
+
# format.set_format_properties( :bold => 1, :color => 'red' )
|
|
102
|
+
#
|
|
103
|
+
# You can also store the properties in one or more named hashes and pass
|
|
104
|
+
# them to the required method:
|
|
105
|
+
#
|
|
106
|
+
# font = {
|
|
107
|
+
# :font => 'Arial',
|
|
108
|
+
# :size => 12,
|
|
109
|
+
# :color => 'blue',
|
|
110
|
+
# :bold => 1
|
|
111
|
+
# }
|
|
112
|
+
#
|
|
113
|
+
# shading = {
|
|
114
|
+
# :bg_color => 'green',
|
|
115
|
+
# :pattern => 1
|
|
116
|
+
# }
|
|
117
|
+
#
|
|
118
|
+
# format1 = workbook.add_format( font ) # Font only
|
|
119
|
+
# format2 = workbook.add_format( font, shading ) # Font and shading
|
|
120
|
+
#
|
|
121
|
+
# The provision of two ways of setting properties might lead you to wonder
|
|
122
|
+
# which is the best way. The method mechanism may be better is you prefer
|
|
123
|
+
# setting properties via method calls (which the author did when the code
|
|
124
|
+
# was first written) otherwise passing properties to the constructor has
|
|
125
|
+
# proved to be a little more flexible and self documenting in practice.
|
|
126
|
+
# An additional advantage of working with property hashes is that it allows
|
|
127
|
+
# you to share formatting between workbook objects as shown in the example
|
|
128
|
+
# above.
|
|
129
|
+
#
|
|
130
|
+
# ===Working with formats
|
|
131
|
+
#
|
|
132
|
+
# The default format is Arial 10 with all other properties off.
|
|
133
|
+
#
|
|
134
|
+
# Each unique format in Excel::Writer::XLSX must have a corresponding Format
|
|
135
|
+
# object. It isn't possible to use a Format with a write() method and then
|
|
136
|
+
# redefine the Format for use at a later stage. This is because a Format
|
|
137
|
+
# is applied to a cell not in its current state but in its final state.
|
|
138
|
+
# Consider the following example:
|
|
139
|
+
#
|
|
140
|
+
# format = workbook.add_format
|
|
141
|
+
# format.set_bold
|
|
142
|
+
# format.set_color( 'red' )
|
|
143
|
+
# worksheet.write( 'A1', 'Cell A1', format )
|
|
144
|
+
# format.set_color( 'green' )
|
|
145
|
+
# worksheet.write( 'B1', 'Cell B1', format )
|
|
146
|
+
#
|
|
147
|
+
# Cell A1 is assigned the Format format which is initially set to the colour
|
|
148
|
+
# red. However, the colour is subsequently set to green. When Excel displays
|
|
149
|
+
# Cell A1 it will display the final state of the Format which in this case
|
|
150
|
+
# will be the colour green.
|
|
151
|
+
#
|
|
152
|
+
# In general a method call without an argument will turn a property on,
|
|
153
|
+
# for example:
|
|
154
|
+
#
|
|
155
|
+
# format1 = workbook.add_format
|
|
156
|
+
# format1.set_bold # Turns bold on
|
|
157
|
+
# format1.set_bold( 1 ) # Also turns bold on
|
|
158
|
+
# format1.set_bold( 0 ) # Turns bold off
|
|
159
|
+
#
|
|
160
|
+
class Format
|
|
161
|
+
attr_reader :xf_index, :dxf_index, :num_format # :nodoc:
|
|
162
|
+
attr_reader :underline, :font_script, :size, :theme, :font, :font_family, :hyperlink # :nodoc:
|
|
163
|
+
attr_reader :diag_type, :diag_color, :font_only, :color, :color_indexed # :nodoc:
|
|
164
|
+
attr_reader :left, :left_color, :right, :right_color, :top, :top_color, :bottom, :bottom_color # :nodoc:
|
|
165
|
+
attr_reader :font_scheme # :nodoc:
|
|
166
|
+
attr_accessor :font_index, :has_font, :has_dxf_font, :has_dxf_fill, :has_dxf_border # :nodoc:
|
|
167
|
+
attr_accessor :num_format_index, :border_index, :has_border # :nodoc:
|
|
168
|
+
attr_accessor :fill_index, :has_fill, :font_condense, :font_extend, :diag_border # :nodoc:
|
|
169
|
+
attr_accessor :bg_color, :fg_color, :pattern # :nodoc:
|
|
170
|
+
|
|
171
|
+
def initialize(xf_format_indices = {}, dxf_format_indices = {}, params = {}) # :nodoc:
|
|
172
|
+
@xf_format_indices = xf_format_indices
|
|
173
|
+
@dxf_format_indices = dxf_format_indices
|
|
174
|
+
|
|
175
|
+
@xf_index = nil
|
|
176
|
+
@dxf_index = nil
|
|
177
|
+
|
|
178
|
+
@num_format = 0
|
|
179
|
+
@num_format_index = 0
|
|
180
|
+
@font_index = 0
|
|
181
|
+
@has_font = 0
|
|
182
|
+
@has_dxf_font = 0
|
|
183
|
+
@font = 'Calibri'
|
|
184
|
+
@size = 11
|
|
185
|
+
@bold = 0
|
|
186
|
+
@italic = 0
|
|
187
|
+
@color = 0x0
|
|
188
|
+
@underline = 0
|
|
189
|
+
@font_strikeout = 0
|
|
190
|
+
@font_outline = 0
|
|
191
|
+
@font_shadow = 0
|
|
192
|
+
@font_script = 0
|
|
193
|
+
@font_family = 2
|
|
194
|
+
@font_charset = 0
|
|
195
|
+
@font_scheme = 'minor'
|
|
196
|
+
@font_condense = 0
|
|
197
|
+
@font_extend = 0
|
|
198
|
+
@theme = 0
|
|
199
|
+
@hyperlink = 0
|
|
200
|
+
|
|
201
|
+
@hidden = 0
|
|
202
|
+
@locked = 1
|
|
203
|
+
|
|
204
|
+
@text_h_align = 0
|
|
205
|
+
@text_wrap = 0
|
|
206
|
+
@text_v_align = 0
|
|
207
|
+
@text_justlast = 0
|
|
208
|
+
@rotation = 0
|
|
209
|
+
|
|
210
|
+
@fg_color = 0x00
|
|
211
|
+
@bg_color = 0x00
|
|
212
|
+
@pattern = 0
|
|
213
|
+
@has_fill = 0
|
|
214
|
+
@has_dxf_fill = 0
|
|
215
|
+
@fill_index = 0
|
|
216
|
+
@fill_count = 0
|
|
217
|
+
|
|
218
|
+
@border_index = 0
|
|
219
|
+
@has_border = 0
|
|
220
|
+
@has_dxf_border = 0
|
|
221
|
+
@border_count = 0
|
|
222
|
+
|
|
223
|
+
@bottom = 0
|
|
224
|
+
@bottom_color = 0x0
|
|
225
|
+
@diag_border = 0
|
|
226
|
+
@diag_color = 0x0
|
|
227
|
+
@diag_type = 0
|
|
228
|
+
@left = 0
|
|
229
|
+
@left_color = 0x0
|
|
230
|
+
@right = 0
|
|
231
|
+
@right_color = 0x0
|
|
232
|
+
@top = 0
|
|
233
|
+
@top_color = 0x0
|
|
234
|
+
|
|
235
|
+
@indent = 0
|
|
236
|
+
@shrink = 0
|
|
237
|
+
@merge_range = 0
|
|
238
|
+
@reading_order = 0
|
|
239
|
+
@just_distrib = 0
|
|
240
|
+
@color_indexed = 0
|
|
241
|
+
@font_only = 0
|
|
242
|
+
|
|
243
|
+
set_format_properties(params) unless params.empty?
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
#
|
|
247
|
+
# :call-seq:
|
|
248
|
+
# set_format_properties( :bold => 1 [, :color => 'red'..] )
|
|
249
|
+
# set_format_properties( font [, shade, ..])
|
|
250
|
+
# set_format_properties( :bold => 1, font, ...)
|
|
251
|
+
# *) font = { :color => 'red', :bold => 1 }
|
|
252
|
+
# shade = { :bg_color => 'green', :pattern => 1 }
|
|
253
|
+
#
|
|
254
|
+
# Convert hashes of properties to method calls.
|
|
255
|
+
#
|
|
256
|
+
# The properties of an existing Format object can be also be set by means
|
|
257
|
+
# of set_format_properties():
|
|
258
|
+
#
|
|
259
|
+
# format = workbook.add_format
|
|
260
|
+
# format.set_format_properties(:bold => 1, :color => 'red');
|
|
261
|
+
#
|
|
262
|
+
# However, this method is here mainly for legacy reasons. It is preferable
|
|
263
|
+
# to set the properties in the format constructor:
|
|
264
|
+
#
|
|
265
|
+
# format = workbook.add_format(:bold => 1, :color => 'red');
|
|
266
|
+
#
|
|
267
|
+
def set_format_properties(*properties) # :nodoc:
|
|
268
|
+
return if properties.empty?
|
|
269
|
+
properties.each do |property|
|
|
270
|
+
property.each do |key, value|
|
|
271
|
+
# Strip leading "-" from Tk style properties e.g. "-color" => 'red'.
|
|
272
|
+
key = key.sub(/^-/, '') if key.respond_to?(:to_str)
|
|
273
|
+
|
|
274
|
+
# Create a sub to set the property.
|
|
275
|
+
if value.respond_to?(:to_str) || !value.respond_to?(:+)
|
|
276
|
+
s = "set_#{key}('#{value}')"
|
|
277
|
+
else
|
|
278
|
+
s = "set_#{key}(#{value})"
|
|
279
|
+
end
|
|
280
|
+
eval s
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
#
|
|
286
|
+
# Return properties for an Style xf <alignment> sub-element.
|
|
287
|
+
#
|
|
288
|
+
def get_align_properties
|
|
289
|
+
align = [] # Attributes to return
|
|
290
|
+
|
|
291
|
+
# Check if any alignment options in the format have been changed.
|
|
292
|
+
if @text_h_align != 0 || @text_v_align != 0 || @indent != 0 ||
|
|
293
|
+
@rotation != 0 || @text_wrap != 0 || @shrink != 0 || @reading_order != 0
|
|
294
|
+
changed = 1
|
|
295
|
+
else
|
|
296
|
+
return
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Indent is only allowed for horizontal left, right and distributed. If it
|
|
300
|
+
# is defined for any other alignment or no alignment has been set then
|
|
301
|
+
# default to left alignment.
|
|
302
|
+
@text_h_align = 1 if @indent != 0 && ![1, 3, 7].include?(@text_h_align)
|
|
303
|
+
|
|
304
|
+
# Check for properties that are mutually exclusive.
|
|
305
|
+
@shrink = 0 if @text_wrap != 0
|
|
306
|
+
@shrink = 0 if @text_h_align == 4 # Fill
|
|
307
|
+
@shrink = 0 if @text_h_align == 5 # Justify
|
|
308
|
+
@shrink = 0 if @text_h_align == 7 # Distributed
|
|
309
|
+
@just_distrib = 0 if @text_h_align != 7 # Distributed
|
|
310
|
+
@just_distrib = 0 if @indent != 0
|
|
311
|
+
|
|
312
|
+
continuous = 'centerContinuous'
|
|
313
|
+
|
|
314
|
+
align << 'horizontal' << 'left' if @text_h_align == 1
|
|
315
|
+
align << 'horizontal' << 'center' if @text_h_align == 2
|
|
316
|
+
align << 'horizontal' << 'right' if @text_h_align == 3
|
|
317
|
+
align << 'horizontal' << 'fill' if @text_h_align == 4
|
|
318
|
+
align << 'horizontal' << 'justify' if @text_h_align == 5
|
|
319
|
+
align << 'horizontal' << continuous if @text_h_align == 6
|
|
320
|
+
align << 'horizontal' << 'distributed' if @text_h_align == 7
|
|
321
|
+
|
|
322
|
+
align << 'justifyLastLine' << 1 if @just_distrib != 0
|
|
323
|
+
|
|
324
|
+
# Property 'vertical' => 'bottom' is a default. It sets applyAlignment
|
|
325
|
+
# without an alignment sub-element.
|
|
326
|
+
align << 'vertical' << 'top' if @text_v_align == 1
|
|
327
|
+
align << 'vertical' << 'center' if @text_v_align == 2
|
|
328
|
+
align << 'vertical' << 'justify' if @text_v_align == 4
|
|
329
|
+
align << 'vertical' << 'distributed' if @text_v_align == 5
|
|
330
|
+
|
|
331
|
+
align << 'indent' << @indent if @indent != 0
|
|
332
|
+
align << 'textRotation' << @rotation if @rotation != 0
|
|
333
|
+
|
|
334
|
+
align << 'wrapText' << 1 if @text_wrap != 0
|
|
335
|
+
align << 'shrinkToFit' << 1 if @shrink != 0
|
|
336
|
+
|
|
337
|
+
align << 'readingOrder' << 1 if @reading_order == 1
|
|
338
|
+
align << 'readingOrder' << 2 if @reading_order == 2
|
|
339
|
+
|
|
340
|
+
return changed, align
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
#
|
|
344
|
+
# Return properties for an Excel XML <Protection> element.
|
|
345
|
+
#
|
|
346
|
+
def get_protection_properties
|
|
347
|
+
attributes = []
|
|
348
|
+
|
|
349
|
+
attributes << 'locked' << 0 if @locked == 0
|
|
350
|
+
attributes << 'hidden' << 1 unless @hidden == 0
|
|
351
|
+
|
|
352
|
+
attributes.empty? ? nil : attributes
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def set_bold(bold = 1)
|
|
356
|
+
@bold = (bold && bold != 0) ? 1 : 0
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def inspect
|
|
360
|
+
to_s
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
#
|
|
364
|
+
# Returns a unique hash key for the Format object.
|
|
365
|
+
#
|
|
366
|
+
def get_format_key
|
|
367
|
+
[get_font_key, get_border_key, get_fill_key, @num_format].join(':')
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
#
|
|
371
|
+
# Returns a unique hash key for a font. Used by Workbook.
|
|
372
|
+
#
|
|
373
|
+
def get_font_key
|
|
374
|
+
[
|
|
375
|
+
@bold,
|
|
376
|
+
@color,
|
|
377
|
+
@font_charset,
|
|
378
|
+
@font_family,
|
|
379
|
+
@font_outline,
|
|
380
|
+
@font_script,
|
|
381
|
+
@font_shadow,
|
|
382
|
+
@font_strikeout,
|
|
383
|
+
@font,
|
|
384
|
+
@italic,
|
|
385
|
+
@size,
|
|
386
|
+
@underline
|
|
387
|
+
].join(':')
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
#
|
|
391
|
+
# Returns a unique hash key for a border style. Used by Workbook.
|
|
392
|
+
#
|
|
393
|
+
def get_border_key
|
|
394
|
+
[
|
|
395
|
+
@bottom,
|
|
396
|
+
@bottom_color,
|
|
397
|
+
@diag_border,
|
|
398
|
+
@diag_color,
|
|
399
|
+
@diag_type,
|
|
400
|
+
@left,
|
|
401
|
+
@left_color,
|
|
402
|
+
@right,
|
|
403
|
+
@right_color,
|
|
404
|
+
@top,
|
|
405
|
+
@top_color
|
|
406
|
+
].join(':')
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
#
|
|
410
|
+
# Returns a unique hash key for a fill style. Used by Workbook.
|
|
411
|
+
#
|
|
412
|
+
def get_fill_key
|
|
413
|
+
[
|
|
414
|
+
@pattern,
|
|
415
|
+
@bg_color,
|
|
416
|
+
@fg_color
|
|
417
|
+
].join(':')
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
#
|
|
421
|
+
# Returns the index used by Worksheet->_XF()
|
|
422
|
+
#
|
|
423
|
+
def get_xf_index
|
|
424
|
+
if @xf_index
|
|
425
|
+
@xf_index
|
|
426
|
+
else
|
|
427
|
+
key = get_format_key
|
|
428
|
+
indices_href = @xf_format_indices
|
|
429
|
+
|
|
430
|
+
if indices_href[key]
|
|
431
|
+
indices_href[key]
|
|
432
|
+
else
|
|
433
|
+
index = 1 + indices_href.keys.size
|
|
434
|
+
indices_href[key] = index
|
|
435
|
+
@xf_index = index
|
|
436
|
+
index
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
#
|
|
442
|
+
# Returns the index used by Worksheet->_XF()
|
|
443
|
+
#
|
|
444
|
+
def get_dxf_index
|
|
445
|
+
if @dxf_index
|
|
446
|
+
@dxf_index
|
|
447
|
+
else
|
|
448
|
+
key = get_format_key
|
|
449
|
+
indices = @dxf_format_indices
|
|
450
|
+
|
|
451
|
+
if indices[key]
|
|
452
|
+
indices[key]
|
|
453
|
+
else
|
|
454
|
+
index = indices.size
|
|
455
|
+
indices[key] = index
|
|
456
|
+
@dxf_index = index
|
|
457
|
+
index
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
def get_color(color)
|
|
463
|
+
Format.get_color(color)
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
#
|
|
467
|
+
# Used in conjunction with the set_xxx_color methods to convert a color
|
|
468
|
+
# string into a number. Color range is 0..63 but we will restrict it
|
|
469
|
+
# to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15.
|
|
470
|
+
#
|
|
471
|
+
def self.get_color(color)
|
|
472
|
+
|
|
473
|
+
colors = {
|
|
474
|
+
:aqua => 0x0F,
|
|
475
|
+
:cyan => 0x0F,
|
|
476
|
+
:black => 0x08,
|
|
477
|
+
:blue => 0x0C,
|
|
478
|
+
:brown => 0x10,
|
|
479
|
+
:magenta => 0x0E,
|
|
480
|
+
:fuchsia => 0x0E,
|
|
481
|
+
:gray => 0x17,
|
|
482
|
+
:grey => 0x17,
|
|
483
|
+
:green => 0x11,
|
|
484
|
+
:lime => 0x0B,
|
|
485
|
+
:navy => 0x12,
|
|
486
|
+
:orange => 0x35,
|
|
487
|
+
:pink => 0x21,
|
|
488
|
+
:purple => 0x14,
|
|
489
|
+
:red => 0x0A,
|
|
490
|
+
:silver => 0x16,
|
|
491
|
+
:white => 0x09,
|
|
492
|
+
:yellow => 0x0D,
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if color.respond_to?(:to_str)
|
|
496
|
+
# Return RGB style colors for processing later.
|
|
497
|
+
return color if color =~ /^#[0-9A-F]{6}$/i
|
|
498
|
+
|
|
499
|
+
# Return the default color if undef,
|
|
500
|
+
return 0x00 unless color
|
|
501
|
+
|
|
502
|
+
# or the color string converted to an integer,
|
|
503
|
+
return colors[color.downcase.to_sym] if colors[color.downcase.to_sym]
|
|
504
|
+
|
|
505
|
+
# or the default color if string is unrecognised,
|
|
506
|
+
return 0x00 if color =~ /\D/
|
|
507
|
+
else
|
|
508
|
+
# or an index < 8 mapped into the correct range,
|
|
509
|
+
return color + 8 if color < 8
|
|
510
|
+
|
|
511
|
+
# or the default color if arg is outside range,
|
|
512
|
+
return 0x00 if color > 63
|
|
513
|
+
|
|
514
|
+
# or an integer in the valid range
|
|
515
|
+
return color
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
#
|
|
520
|
+
# Set cell alignment.
|
|
521
|
+
#
|
|
522
|
+
def set_align(location)
|
|
523
|
+
return unless location # No default
|
|
524
|
+
|
|
525
|
+
location.downcase!
|
|
526
|
+
|
|
527
|
+
set_text_h_align(1) if location == 'left'
|
|
528
|
+
set_text_h_align(2) if location == 'centre'
|
|
529
|
+
set_text_h_align(2) if location == 'center'
|
|
530
|
+
set_text_h_align(3) if location == 'right'
|
|
531
|
+
set_text_h_align(4) if location == 'fill'
|
|
532
|
+
set_text_h_align(5) if location == 'justify'
|
|
533
|
+
set_text_h_align(6) if location == 'center_across'
|
|
534
|
+
set_text_h_align(6) if location == 'centre_across'
|
|
535
|
+
set_text_h_align(6) if location == 'merge' # Legacy.
|
|
536
|
+
set_text_h_align(7) if location == 'distributed'
|
|
537
|
+
set_text_h_align(7) if location == 'equal_space' # S::PE.
|
|
538
|
+
set_text_h_align(7) if location == 'justify_distributed'
|
|
539
|
+
|
|
540
|
+
@just_distrib = 1 if location == 'justify_distributed'
|
|
541
|
+
|
|
542
|
+
set_text_v_align(1) if location == 'top'
|
|
543
|
+
set_text_v_align(2) if location == 'vcentre'
|
|
544
|
+
set_text_v_align(2) if location == 'vcenter'
|
|
545
|
+
set_text_v_align(3) if location == 'bottom'
|
|
546
|
+
set_text_v_align(4) if location == 'vjustify'
|
|
547
|
+
set_text_v_align(5) if location == 'vdistributed'
|
|
548
|
+
set_text_v_align(5) if location == 'vequal_space' # S::PE.
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
#
|
|
552
|
+
# Set vertical cell alignment. This is required by the set_properties() method
|
|
553
|
+
# to differentiate between the vertical and horizontal properties.
|
|
554
|
+
#
|
|
555
|
+
def set_valign(location)
|
|
556
|
+
set_align(location)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
#
|
|
560
|
+
# Implements the Excel5 style "merge".
|
|
561
|
+
#
|
|
562
|
+
def set_center_across(flag = 1)
|
|
563
|
+
set_text_h_align(6)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
#
|
|
567
|
+
# This was the way to implement a merge in Excel5. However it should have been
|
|
568
|
+
# called "center_across" and not "merge".
|
|
569
|
+
# This is now deprecated. Use set_center_across() or better merge_range().
|
|
570
|
+
#
|
|
571
|
+
def set_merge(merge = 1)
|
|
572
|
+
set_text_h_align(6)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
#
|
|
576
|
+
# Set cells borders to the same style
|
|
577
|
+
#
|
|
578
|
+
def set_border(style)
|
|
579
|
+
set_bottom(style)
|
|
580
|
+
set_top(style)
|
|
581
|
+
set_left(style)
|
|
582
|
+
set_right(style)
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
#
|
|
586
|
+
# Set cells border to the same color
|
|
587
|
+
#
|
|
588
|
+
def set_border_color(color)
|
|
589
|
+
set_bottom_color(color)
|
|
590
|
+
set_top_color(color)
|
|
591
|
+
set_left_color(color)
|
|
592
|
+
set_right_color(color)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
#
|
|
596
|
+
# Set the rotation angle of the text. An alignment property.
|
|
597
|
+
#
|
|
598
|
+
def set_rotation(rotation)
|
|
599
|
+
if rotation == 270
|
|
600
|
+
rotation = 255
|
|
601
|
+
elsif rotation >= -90 || rotation <= 90
|
|
602
|
+
rotation = -rotation + 90 if rotation < 0
|
|
603
|
+
else
|
|
604
|
+
raise "Rotation #{rotation} outside range: -90 <= angle <= 90"
|
|
605
|
+
rotation = 0
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
@rotation = rotation
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
#
|
|
612
|
+
# Set the properties for the hyperlink style. TODO. This doesn't currently
|
|
613
|
+
# work. Fix it when styles are supported.
|
|
614
|
+
#
|
|
615
|
+
def set_hyperlink
|
|
616
|
+
@hyperlink = 1
|
|
617
|
+
|
|
618
|
+
set_underline(1)
|
|
619
|
+
set_theme(10)
|
|
620
|
+
set_align('top')
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
def method_missing(name, *args) # :nodoc:
|
|
624
|
+
method = "#{name}"
|
|
625
|
+
|
|
626
|
+
# Check for a valid method names, i.e. "set_xxx_yyy".
|
|
627
|
+
method =~ /set_(\w+)/ or raise "Unknown method: #{method}\n"
|
|
628
|
+
|
|
629
|
+
# Match the attribute, i.e. "@xxx_yyy".
|
|
630
|
+
attribute = "@#{$1}"
|
|
631
|
+
|
|
632
|
+
# Check that the attribute exists
|
|
633
|
+
# ........
|
|
634
|
+
if method =~ /set\w+color$/ # for "set_property_color" methods
|
|
635
|
+
value = get_color(args[0])
|
|
636
|
+
else # for "set_xxx" methods
|
|
637
|
+
value = args[0].nil? ? 1 : args[0]
|
|
638
|
+
end
|
|
639
|
+
if value.respond_to?(:to_str) || !value.respond_to?(:+)
|
|
640
|
+
s = %Q!#{attribute} = "#{value.to_s}"!
|
|
641
|
+
else
|
|
642
|
+
s = %Q!#{attribute} = #{value.to_s}!
|
|
643
|
+
end
|
|
644
|
+
eval s
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
def bold?
|
|
648
|
+
return false unless @bold
|
|
649
|
+
return false if @bold == 0
|
|
650
|
+
true
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
def italic?
|
|
654
|
+
return false unless @italic
|
|
655
|
+
return false if @italic == 0
|
|
656
|
+
true
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
def strikeout?
|
|
660
|
+
return false unless @font_strikeout
|
|
661
|
+
return false if @font_strikeout == 0
|
|
662
|
+
true
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
def outline?
|
|
666
|
+
return false unless @font_outline
|
|
667
|
+
return false if @font_outline == 0
|
|
668
|
+
true
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
def shadow?
|
|
672
|
+
return false unless @font_shadow
|
|
673
|
+
return false if @font_shadow == 0
|
|
674
|
+
true
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
def underline?
|
|
678
|
+
return false unless @underline
|
|
679
|
+
return false if @underline == 0
|
|
680
|
+
true
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
end
|