redmine_api_helper 0.3.35

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.

Potentially problematic release.


This version of redmine_api_helper might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +2 -0
  3. data/.gitignore +11 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +339 -0
  7. data/README.md +30 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/date_helper/date.rb +311 -0
  12. data/lib/odf_writer/bookmark.rb +110 -0
  13. data/lib/odf_writer/bookmark_reader.rb +77 -0
  14. data/lib/odf_writer/document.rb +371 -0
  15. data/lib/odf_writer/field.rb +174 -0
  16. data/lib/odf_writer/field_reader.rb +78 -0
  17. data/lib/odf_writer/image.rb +176 -0
  18. data/lib/odf_writer/image_reader.rb +76 -0
  19. data/lib/odf_writer/images.rb +89 -0
  20. data/lib/odf_writer/list_style.rb +336 -0
  21. data/lib/odf_writer/nested.rb +156 -0
  22. data/lib/odf_writer/odf_helper.rb +57 -0
  23. data/lib/odf_writer/parser/default.rb +691 -0
  24. data/lib/odf_writer/path_finder.rb +114 -0
  25. data/lib/odf_writer/section.rb +120 -0
  26. data/lib/odf_writer/section_reader.rb +61 -0
  27. data/lib/odf_writer/style.rb +483 -0
  28. data/lib/odf_writer/table.rb +135 -0
  29. data/lib/odf_writer/table_reader.rb +61 -0
  30. data/lib/odf_writer/template.rb +234 -0
  31. data/lib/odf_writer/text.rb +97 -0
  32. data/lib/odf_writer/text_reader.rb +77 -0
  33. data/lib/odf_writer/version.rb +29 -0
  34. data/lib/redmine_api_helper/api_helper.rb +333 -0
  35. data/lib/redmine_api_helper/args_helper.rb +106 -0
  36. data/lib/redmine_api_helper/attachments_api_helper.rb +52 -0
  37. data/lib/redmine_api_helper/define_api_helpers.rb +78 -0
  38. data/lib/redmine_api_helper/document_categories_api_helper.rb +38 -0
  39. data/lib/redmine_api_helper/groups_api_helper.rb +80 -0
  40. data/lib/redmine_api_helper/helpers.rb +50 -0
  41. data/lib/redmine_api_helper/issue_priorities_api_helper.rb +38 -0
  42. data/lib/redmine_api_helper/issue_relations_api_helper.rb +66 -0
  43. data/lib/redmine_api_helper/issue_statuses_api_helper.rb +36 -0
  44. data/lib/redmine_api_helper/issues_api_helper.rb +124 -0
  45. data/lib/redmine_api_helper/my_account_api_helper.rb +45 -0
  46. data/lib/redmine_api_helper/news_api_helper.rb +73 -0
  47. data/lib/redmine_api_helper/project_memberships_api_helper.rb +77 -0
  48. data/lib/redmine_api_helper/projects_api_helper.rb +73 -0
  49. data/lib/redmine_api_helper/roles_api_helper.rb +52 -0
  50. data/lib/redmine_api_helper/scripts_api_helper.rb +87 -0
  51. data/lib/redmine_api_helper/search_api_helper.rb +38 -0
  52. data/lib/redmine_api_helper/time_entries_api_helper.rb +73 -0
  53. data/lib/redmine_api_helper/time_entry_activities_api_helper.rb +38 -0
  54. data/lib/redmine_api_helper/trackers_api_helper.rb +38 -0
  55. data/lib/redmine_api_helper/users_api_helper.rb +73 -0
  56. data/lib/redmine_api_helper/version.rb +24 -0
  57. data/lib/redmine_api_helper/wiki_pages_api_helper.rb +66 -0
  58. data/lib/redmine_api_helper.rb +88 -0
  59. data/redmine_api_helper.gemspec +36 -0
  60. metadata +162 -0
@@ -0,0 +1,176 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ require 'rack/mime' # needed for Rack::Mime
23
+
24
+ module ODFWriter
25
+
26
+ ########################################################################################
27
+ #
28
+ # Image: replace images
29
+ #
30
+ ########################################################################################
31
+ class Image < Field
32
+
33
+ ######################################################################################
34
+ #
35
+ # constants
36
+ #
37
+ ######################################################################################
38
+ IMAGE_DIR_NAME = "Pictures"
39
+
40
+ ######################################################################################
41
+ #
42
+ # replace!
43
+ #
44
+ ######################################################################################
45
+ def replace!(doc, manifest, template, item=nil )
46
+
47
+ image_data = value(item)
48
+
49
+ if image_data = is_image?(image_data)
50
+
51
+ # find placeholder image
52
+ nodes = find_image_nodes( doc )
53
+ return if nodes.blank?
54
+
55
+ # find manifest
56
+ man = manifest.xpath("//manifest:manifest") rescue nil
57
+ return if man.blank?
58
+
59
+ # each placeholder image
60
+ nodes.each do |node|
61
+
62
+ # create unique filename for image in .odt file
63
+ path = ::File.join(IMAGE_DIR_NAME, "#{SecureRandom.hex(20).upcase}#{::File.extname(image_data[:filename])}")
64
+ mime = Rack::Mime.mime_type(File.extname(image_data[:filename]))
65
+
66
+ # set path and mime type of placeholder image
67
+ node.attribute('href').value = path
68
+ if node.attribute('mime-type').present?
69
+ node.attribute('mime-type').value = mime
70
+ else
71
+ node.set_attribute('mime-type', mime)
72
+ end
73
+
74
+ # set width and height of placeholder image
75
+ parent = node.parent
76
+ if parent.name == "frame"
77
+ width = parent.attribute('width').value
78
+ height = parent.attribute('height').value
79
+ parent.attribute('height').value = recalc_height(:x => image_data[:width], :y => image_data[:height], :newx => width, :newy => height)
80
+ end
81
+
82
+ # add image to .odt file
83
+ add_image_file( image_data[:bytes], path, mime, doc, man, template )
84
+
85
+ end
86
+ end
87
+
88
+ end #def
89
+
90
+ def self.unique_image_names(doc)
91
+ nodes = doc.xpath("//draw:frame[@draw:name='#{@name}']")
92
+ padding = Math.log10(nodes.length).to_i + 1 if nodes.present?
93
+ nodes.each_with_index do |node, i|
94
+ num = "%.#{padding}i" % i
95
+ node.attribute('name').value = "IMAGE_#{num}_" + node.attribute('name').value
96
+ end
97
+ end #def
98
+
99
+ ######################################################################################
100
+ #
101
+ # private
102
+ #
103
+ ######################################################################################
104
+ private
105
+
106
+ ######################################################################################
107
+ # is_image?
108
+ ######################################################################################
109
+ def is_image?(obj)
110
+ case obj
111
+ when Hash
112
+ if (obj.keys.map(&:to_sym) &
113
+ [:filename, :width, :height, :bytes]).length == 4
114
+ obj.symbolize_keys
115
+ end
116
+ else
117
+ if obj.respond_to?(:filename) &&
118
+ obj.respond_to?(:width) &&
119
+ obj.respond_to?(:height) &&
120
+ obj.respond_to?(:bytes)
121
+ {:filename => obj.filename,
122
+ :width => obj.width,
123
+ :height => obj.height,
124
+ :bytes => obj.bytes }
125
+ end
126
+ end
127
+ end #def
128
+
129
+ ######################################################################################
130
+ # find_image_nodes
131
+ ######################################################################################
132
+ def find_image_nodes(doc)
133
+ doc.xpath(".//draw:frame[@draw:name='#{@name}']/draw:image")
134
+ end #def
135
+
136
+ ######################################################################################
137
+ # recalc_height
138
+ ######################################################################################
139
+ def recalc_height(nums)
140
+
141
+ numericals = {}
142
+ dimensions = {}
143
+
144
+ #remove dimensions like 'px' or 'cm' or 'in' or 'pt'
145
+ [:x, :y, :newx, :newy].each do |v|
146
+ num = nums[v].to_s.match(/[0-9.]+/)
147
+ numericals[v] = num[0].to_f if num
148
+ dimensions[v] = nums[v].to_s.gsub(/\A[0-9.]+/, "")
149
+ end
150
+
151
+ if [:x, :y, :newx, :newy].all?{|i| numericals[i].present? }
152
+ y = numericals[:newx] / numericals[:x] * numericals[:y]
153
+ end
154
+
155
+ y ? "#{'%.3f'%y}#{dimensions[:newy]}" : nums[:newy]
156
+
157
+ end #def
158
+
159
+ ######################################################################################
160
+ # add_image_file
161
+ ######################################################################################
162
+ def add_image_file(bytes, path, mime, doc, manifest, template )
163
+
164
+ file_entry = Nokogiri::XML::Node.new('manifest:file-entry', doc)
165
+ file_entry.set_attribute('manifest:full-path', path)
166
+ file_entry.set_attribute('manifest:media-type', mime)
167
+ manifest.children.after file_entry
168
+
169
+ template.output_stream.put_next_entry(path)
170
+ template.output_stream.write bytes
171
+
172
+ end #def
173
+
174
+
175
+ end #class
176
+ end #module
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # ImageReader: find all images and set name
27
+ #
28
+ ########################################################################################
29
+ class ImageReader
30
+
31
+ attr_accessor :name
32
+
33
+ ######################################################################################
34
+ #
35
+ # initialize
36
+ #
37
+ ######################################################################################
38
+ def initialize(opts)
39
+ @name = opts[:name]
40
+ end #def
41
+
42
+ ######################################################################################
43
+ #
44
+ # get_paths: limit to paths with ancestors 'text '(content.xml) and master-styles (styles.xml)
45
+ #
46
+ ######################################################################################
47
+ def paths( root, doc)
48
+
49
+ # find nodes with matching field elements matching [BOOKMARK] pattern
50
+ nodes = doc.xpath("//draw:frame[draw:image]").select{|node| scan(node).present? }
51
+
52
+ # find path for each field
53
+ paths = nil
54
+ nodes.each do |node|
55
+ leaf = {:images => scan(node)}
56
+ paths = PathFinder.trail(node, leaf, :root => root, :paths => paths)
57
+ end #each
58
+ paths.to_h
59
+
60
+ end #def
61
+
62
+ ######################################################################################
63
+ # private
64
+ ######################################################################################
65
+
66
+ private
67
+
68
+ def scan(node)
69
+ if name
70
+ node.attr("draw:name") == name.upcase ? [node.attr("draw:name")] : []
71
+ else
72
+ [node.attr("draw:name")]
73
+ end
74
+ end #def
75
+ end #class
76
+ end #module
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # Images: replace images
27
+ #
28
+ ########################################################################################
29
+ module Images
30
+
31
+ ######################################################################################
32
+ #
33
+ # constants
34
+ #
35
+ ######################################################################################
36
+ IMAGE_DIR_NAME = "Pictures"
37
+
38
+ ######################################################################################
39
+ #
40
+ # find_image_name_matches
41
+ #
42
+ ######################################################################################
43
+ def find_image_name_matches(content)
44
+
45
+ @images.each_pair do |image_name, img_data|
46
+ if node = content.xpath("//draw:frame[@draw:name='#{image_name}']/draw:image").first
47
+ placeholder_path = node.attribute('href').value
48
+ @image_names_replacements[path] = ::File.join(IMAGE_DIR_NAME, ::File.basename(placeholder_path))
49
+ end
50
+ end
51
+
52
+ end #def
53
+
54
+ ######################################################################################
55
+ #
56
+ # include_image_files
57
+ #
58
+ ######################################################################################
59
+ def include_image_files(file)
60
+
61
+ return if @images.empty?
62
+
63
+ @image_names_replacements.each_pair do |path, template_image|
64
+
65
+ file.output_stream.put_next_entry(template_image)
66
+ file.output_stream.write ::File.read(path)
67
+
68
+ end
69
+
70
+ end #def
71
+
72
+ ######################################################################################
73
+ #
74
+ # avoid_duplicate_image_names
75
+ #
76
+ ######################################################################################
77
+ # newer versions of LibreOffice can't open files with duplicates image names
78
+ def avoid_duplicate_image_names(content)
79
+
80
+ nodes = content.xpath("//draw:frame[@draw:name]")
81
+
82
+ nodes.each_with_index do |node, i|
83
+ node.attribute('name').value = "pic_#{i}"
84
+ end
85
+
86
+ end #def
87
+
88
+ end #class
89
+ end #module
@@ -0,0 +1,336 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Ruby Gem to create a self populating Open Document Format (.odf) text file.
4
+ #
5
+ # Copyright 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+ #
21
+
22
+ module ODFWriter
23
+
24
+ ########################################################################################
25
+ #
26
+ # ListStyle: add style for ul, ol up to 6 levels deep
27
+ #
28
+ ########################################################################################
29
+ class ListStyle
30
+
31
+ ######################################################################################
32
+ #
33
+ # initialize
34
+ #
35
+ ######################################################################################
36
+ def initialize( *list_styles )
37
+ @list_styles = *list_styles
38
+ @font = {}
39
+ end #def
40
+
41
+ ######################################################################################
42
+ #
43
+ # add_list_style
44
+ #
45
+ ######################################################################################
46
+ def add_list_style( doc )
47
+
48
+ ns = doc.collect_namespaces
49
+ automatic_styles = doc.at("//office:automatic-styles", ns)
50
+ font_declarations = doc.at("//office:font-face-decls", ns)
51
+
52
+
53
+
54
+ @list_styles.each do |list_style|
55
+
56
+ automatic_styles << create_list( doc, list_style ) if automatic_styles.present?
57
+
58
+ if @font.present?
59
+ font_declarations << create_font( doc, @font ) if font_declarations.present?
60
+ end
61
+ end
62
+ end #def
63
+
64
+ ######################################################################################
65
+ #
66
+ # private
67
+ #
68
+ ######################################################################################
69
+ private
70
+
71
+ def create_font( doc, font )
72
+ node = Nokogiri::XML::Node.new('style:font-face', doc)
73
+ node["style:name"] = font[:font_name]
74
+ node["svg:font-family"] = font[:font_family]
75
+ node["style:font-family-generic"] = font[:font_family_generic]
76
+ node["style:font-pitch"] = font[:font_pitch]
77
+ node
78
+ end #def
79
+
80
+ def create_list( doc, list_style )
81
+
82
+ node = Nokogiri::XML::Node.new('text:list-style', doc)
83
+
84
+ #
85
+ # common properties
86
+ #
87
+ case list_style
88
+
89
+ when :ul
90
+ node['style:name'] = "ul"
91
+
92
+ #
93
+ # Level 1
94
+ #
95
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
96
+ list_bullet['text:level'] = "1"
97
+ list_bullet['text:bullet-char'] = "•"
98
+ node << list_bullet
99
+
100
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
101
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
102
+ list_bullet << list_level
103
+
104
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
105
+ list_label['text:label-followed-by'] = "listtab"
106
+ list_label['text:list-tab-stop-position'] = "1cm"
107
+ list_label['fo:text-indent'] = "-0.5cm"
108
+ list_label['fo:margin-left'] = "1cm"
109
+ list_level << list_label
110
+
111
+ #
112
+ # Level 2
113
+ #
114
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
115
+ list_bullet['text:level'] = "2"
116
+ list_bullet['text:bullet-char'] = "◦"
117
+ node << list_bullet
118
+
119
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
120
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
121
+ list_bullet << list_level
122
+
123
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
124
+ list_label['text:label-followed-by'] = "listtab"
125
+ list_label['text:list-tab-stop-position'] = "1.5cm"
126
+ list_label['fo:text-indent'] = "-0.5cm"
127
+ list_label['fo:margin-left'] = "1.5cm"
128
+ list_level << list_label
129
+
130
+ #
131
+ # Level 3
132
+ #
133
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
134
+ list_bullet['text:level'] = "3"
135
+ list_bullet['text:bullet-char'] = "▪"
136
+ node << list_bullet
137
+
138
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
139
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
140
+ list_bullet << list_level
141
+
142
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
143
+ list_label['text:label-followed-by'] = "listtab"
144
+ list_label['text:list-tab-stop-position'] = "2cm"
145
+ list_label['fo:text-indent'] = "-0.5cm"
146
+ list_label['fo:margin-left'] = "2cm"
147
+ list_level << list_label
148
+
149
+ #
150
+ # Level 4
151
+ #
152
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
153
+ list_bullet['text:level'] = "4"
154
+ list_bullet['text:bullet-char'] = "•"
155
+ node << list_bullet
156
+
157
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
158
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
159
+ list_bullet << list_level
160
+
161
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
162
+ list_label['text:label-followed-by'] = "listtab"
163
+ list_label['text:list-tab-stop-position'] = "2.5cm"
164
+ list_label['fo:text-indent'] = "-0.5cm"
165
+ list_label['fo:margin-left'] = "2.5cm"
166
+ list_level << list_label
167
+
168
+ #
169
+ # Level 5
170
+ #
171
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
172
+ list_bullet['text:level'] = "5"
173
+ list_bullet['text:bullet-char'] = "◦"
174
+ node << list_bullet
175
+
176
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
177
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
178
+ list_bullet << list_level
179
+
180
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
181
+ list_label['text:label-followed-by'] = "listtab"
182
+ list_label['text:list-tab-stop-position'] = "3cm"
183
+ list_label['fo:text-indent'] = "-0.5cm"
184
+ list_label['fo:margin-left'] = "3cm"
185
+ list_level << list_label
186
+
187
+ #
188
+ # Level 6
189
+ #
190
+ list_bullet = Nokogiri::XML::Node.new('text:list-level-style-bullet', doc)
191
+ list_bullet['text:level'] = "6"
192
+ list_bullet['text:bullet-char'] = "▪"
193
+ node << list_bullet
194
+
195
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
196
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
197
+ list_bullet << list_level
198
+
199
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
200
+ list_label['text:label-followed-by'] = "listtab"
201
+ list_label['text:list-tab-stop-position'] = "3.5cm"
202
+ list_label['fo:text-indent'] = "-0.5cm"
203
+ list_label['fo:margin-left'] = "3.5cm"
204
+ list_level << list_label
205
+
206
+ when :ol
207
+ node['style:name'] = "ol"
208
+
209
+ #
210
+ # Level 1
211
+ #
212
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
213
+ list_number['text:level'] = "1"
214
+ list_number['style:num-suffix'] = "."
215
+ list_number['style:num-format'] = "1"
216
+ node << list_number
217
+
218
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
219
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
220
+ list_number << list_level
221
+
222
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
223
+ list_label['text:label-followed-by'] = "listtab"
224
+ list_label['text:list-tab-stop-position'] = "1cm"
225
+ list_label['fo:text-indent'] = "-0.5cm"
226
+ list_label['fo:margin-left'] = "1cm"
227
+ list_level << list_label
228
+
229
+ #
230
+ # Level 2
231
+ #
232
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
233
+ list_number['text:level'] = "2"
234
+ list_number['style:num-suffix'] = "."
235
+ list_number['style:num-format'] = "1"
236
+ node << list_number
237
+
238
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
239
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
240
+ list_number << list_level
241
+
242
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
243
+ list_label['text:label-followed-by'] = "listtab"
244
+ list_label['text:list-tab-stop-position'] = "1.5cm"
245
+ list_label['fo:text-indent'] = "-0.5cm"
246
+ list_label['fo:margin-left'] = "1.5cm"
247
+ list_level << list_label
248
+
249
+ #
250
+ # Level 3
251
+ #
252
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
253
+ list_number['text:level'] = "3"
254
+ list_number['style:num-suffix'] = "."
255
+ list_number['style:num-format'] = "1"
256
+ node << list_number
257
+
258
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
259
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
260
+ list_number << list_level
261
+
262
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
263
+ list_label['text:label-followed-by'] = "listtab"
264
+ list_label['text:list-tab-stop-position'] = "2cm"
265
+ list_label['fo:text-indent'] = "-0.5cm"
266
+ list_label['fo:margin-left'] = "2cm"
267
+ list_level << list_label
268
+
269
+ #
270
+ # Level 4
271
+ #
272
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
273
+ list_number['text:level'] = "4"
274
+ list_number['style:num-suffix'] = "."
275
+ list_number['style:num-format'] = "1"
276
+ node << list_number
277
+
278
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
279
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
280
+ list_number << list_level
281
+
282
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
283
+ list_label['text:label-followed-by'] = "listtab"
284
+ list_label['text:list-tab-stop-position'] = "2.5cm"
285
+ list_label['fo:text-indent'] = "-0.5cm"
286
+ list_label['fo:margin-left'] = "2.5cm"
287
+ list_level << list_label
288
+
289
+ #
290
+ # Level 5
291
+ #
292
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
293
+ list_number['text:level'] = "5"
294
+ list_number['style:num-suffix'] = "."
295
+ list_number['style:num-format'] = "1"
296
+ node << list_number
297
+
298
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
299
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
300
+ list_number << list_level
301
+
302
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
303
+ list_label['text:label-followed-by'] = "listtab"
304
+ list_label['text:list-tab-stop-position'] = "3cm"
305
+ list_label['fo:text-indent'] = "-0.5cm"
306
+ list_label['fo:margin-left'] = "3cm"
307
+ list_level << list_label
308
+
309
+ #
310
+ # Level 6
311
+ #
312
+ list_number = Nokogiri::XML::Node.new('text:list-level-style-number', doc)
313
+ list_number['text:level'] = "6"
314
+ list_number['style:num-suffix'] = "."
315
+ list_number['style:num-format'] = "1"
316
+ node << list_number
317
+
318
+ list_level = Nokogiri::XML::Node.new('style:list-level-properties', doc)
319
+ list_level['text:list-level-position-and-space-mode'] = "label-alignment"
320
+ list_number << list_level
321
+
322
+ list_label = Nokogiri::XML::Node.new('style:list-level-label-alignment', doc)
323
+ list_label['text:label-followed-by'] = "listtab"
324
+ list_label['text:list-tab-stop-position'] = "3.5cm"
325
+ list_label['fo:text-indent'] = "-0.5cm"
326
+ list_label['fo:margin-left'] = "3.5cm"
327
+ list_level << list_label
328
+
329
+ end
330
+
331
+ node
332
+
333
+ end #def
334
+
335
+ end #class
336
+ end #module