thinreports 0.10.0 → 0.12.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 +5 -5
- data/.github/CONTRIBUTING.md +2 -2
- data/.github/workflows/test.yml +51 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +49 -0
- data/Dockerfile +12 -0
- data/Gemfile +2 -1
- data/README.md +46 -21
- data/Rakefile +13 -29
- data/gemfiles/prawn-2.2.gemfile +5 -0
- data/gemfiles/prawn-2.3.gemfile +5 -0
- data/gemfiles/prawn-2.4.gemfile +5 -0
- data/lib/thinreports.rb +5 -0
- data/lib/thinreports/core/shape.rb +4 -3
- data/lib/thinreports/core/shape/base/interface.rb +0 -1
- data/lib/thinreports/core/shape/basic/format.rb +5 -0
- data/lib/thinreports/core/shape/image_block.rb +1 -1
- data/lib/thinreports/core/shape/list.rb +1 -1
- data/lib/thinreports/core/shape/list/manager.rb +1 -4
- data/lib/thinreports/core/shape/list/page.rb +2 -5
- data/lib/thinreports/core/shape/manager/internal.rb +0 -1
- data/lib/thinreports/core/shape/page_number.rb +1 -1
- data/lib/thinreports/core/shape/page_number/internal.rb +0 -1
- data/lib/thinreports/core/shape/stack_view.rb +17 -0
- data/lib/thinreports/core/shape/stack_view/format.rb +27 -0
- data/lib/thinreports/core/shape/stack_view/interface.rb +17 -0
- data/lib/thinreports/core/shape/stack_view/internal.rb +22 -0
- data/lib/thinreports/core/shape/stack_view/row_format.rb +39 -0
- data/lib/thinreports/core/shape/style/basic.rb +4 -1
- data/lib/thinreports/core/shape/text.rb +1 -1
- data/lib/thinreports/core/shape/text_block.rb +1 -1
- data/lib/thinreports/core/shape/text_block/formatter/number.rb +21 -9
- data/lib/thinreports/core/shape/text_block/internal.rb +0 -2
- data/lib/thinreports/core/utils.rb +6 -3
- data/lib/thinreports/generate.rb +11 -0
- data/lib/thinreports/generator/pdf/document/draw_shape.rb +31 -11
- data/lib/thinreports/generator/pdf/document/draw_template_items.rb +1 -2
- data/lib/thinreports/generator/pdf/document/font.rb +16 -10
- data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +0 -1
- data/lib/thinreports/generator/pdf/document/graphics/basic.rb +0 -1
- data/lib/thinreports/generator/pdf/document/graphics/image.rb +19 -1
- data/lib/thinreports/generator/pdf/document/graphics/text.rb +10 -8
- data/lib/thinreports/generator/pdf/document/page.rb +13 -4
- data/lib/thinreports/generator/pdf/drawer/list.rb +0 -1
- data/lib/thinreports/generator/pdf/prawn_ext/calc_image_dimensions.rb +1 -3
- data/lib/thinreports/generator/pdf/prawn_ext/width_of.rb +7 -7
- data/lib/thinreports/layout/base.rb +2 -4
- data/lib/thinreports/layout/format.rb +0 -1
- data/lib/thinreports/layout/legacy_schema.rb +2 -6
- data/lib/thinreports/layout/version.rb +1 -1
- data/lib/thinreports/report/internal.rb +4 -4
- data/lib/thinreports/report/page.rb +2 -7
- data/lib/thinreports/section_report/build.rb +32 -0
- data/lib/thinreports/section_report/builder/item_builder.rb +49 -0
- data/lib/thinreports/section_report/builder/report_builder.rb +82 -0
- data/lib/thinreports/section_report/builder/report_data.rb +13 -0
- data/lib/thinreports/section_report/builder/stack_view_builder.rb +55 -0
- data/lib/thinreports/section_report/builder/stack_view_data.rb +11 -0
- data/lib/thinreports/section_report/generate.rb +26 -0
- data/lib/thinreports/section_report/pdf/render.rb +23 -0
- data/lib/thinreports/section_report/pdf/renderer/draw_item.rb +68 -0
- data/lib/thinreports/section_report/pdf/renderer/group_renderer.rb +57 -0
- data/lib/thinreports/section_report/pdf/renderer/headers_renderer.rb +24 -0
- data/lib/thinreports/section_report/pdf/renderer/section_height.rb +100 -0
- data/lib/thinreports/section_report/pdf/renderer/section_renderer.rb +39 -0
- data/lib/thinreports/section_report/pdf/renderer/stack_view_renderer.rb +55 -0
- data/lib/thinreports/section_report/pdf/renderer/stack_view_row_renderer.rb +38 -0
- data/lib/thinreports/section_report/schema/loader.rb +28 -0
- data/lib/thinreports/section_report/schema/parser.rb +52 -0
- data/lib/thinreports/section_report/schema/report.rb +30 -0
- data/lib/thinreports/section_report/schema/section.rb +47 -0
- data/lib/thinreports/version.rb +1 -1
- data/thinreports.gemspec +11 -11
- metadata +48 -164
- data/.rubocop.yml +0 -41
- data/.travis.yml +0 -17
- data/examples/character_spacing/character_spacing.rb +0 -8
- data/examples/character_spacing/character_spacing.tlf +0 -293
- data/examples/dynamic_image/dynamic_image.rb +0 -31
- data/examples/dynamic_image/dynamic_image.tlf +0 -661
- data/examples/dynamic_image/img200x100.png +0 -0
- data/examples/dynamic_image/img50x50.png +0 -0
- data/examples/dynamic_style/dynamic_style.rb +0 -150
- data/examples/dynamic_style/dynamic_style.tlf +0 -1835
- data/examples/dynamic_style/dynamic_style_in_list.tlf +0 -344
- data/examples/dynamic_style/image.png +0 -0
- data/examples/eudc/eudc.rb +0 -20
- data/examples/eudc/eudc.tlf +0 -180
- data/examples/eudc/eudc.ttf +0 -0
- data/examples/helper.rb +0 -50
- data/examples/hidden_shapes/hidden_shapes.rb +0 -9
- data/examples/hidden_shapes/hidden_shapes.tlf +0 -449
- data/examples/list_events/list_events.rb +0 -32
- data/examples/list_events/list_events.tlf +0 -361
- data/examples/list_manual_generation/list_manual_generation.rb +0 -22
- data/examples/list_manual_generation/list_manual_generation.tlf +0 -132
- data/examples/list_page_number/list_page_number.rb +0 -17
- data/examples/list_page_number/list_page_number.tlf +0 -254
- data/examples/page_number/page_number.rb +0 -33
- data/examples/page_number/page_number.tlf +0 -215
- data/examples/palleted_png/palleted_png.png +0 -0
- data/examples/palleted_png/palleted_png.rb +0 -9
- data/examples/palleted_png/palleted_png.tlf +0 -47
- data/examples/password_setting/password_setting.rb +0 -10
- data/examples/password_setting/password_setting.tlf +0 -45
- data/examples/report_callbacks/report_callbacks.rb +0 -14
- data/examples/report_callbacks/report_callbacks.tlf +0 -147
- data/examples/single_line_tblock/single_line_tblock.rb +0 -13
- data/examples/single_line_tblock/single_line_tblock.tlf +0 -170
- data/examples/tblock_overflow/tblock_overflow.rb +0 -20
- data/examples/tblock_overflow/tblock_overflow.tlf +0 -538
- data/examples/tblock_styles/font_size.tlf +0 -383
- data/examples/tblock_styles/tblock_styles.rb +0 -43
- data/examples/tblock_styles/tblock_styles.tlf +0 -889
- data/examples/text_align/text_align.rb +0 -8
- data/examples/text_align/text_align.tlf +0 -241
- data/examples/typeB_page_size/B4_ISO.tlf +0 -45
- data/examples/typeB_page_size/B4_JIS.tlf +0 -45
- data/examples/typeB_page_size/typeB_page_size.rb +0 -17
- data/examples/word_wrap/word_wrap.rb +0 -26
- data/examples/word_wrap/word_wrap.tlf +0 -297
- data/test/data/font.ttf +0 -0
- data/test/data/image_normal.jpg +0 -0
- data/test/data/image_normal.png +0 -0
- data/test/data/image_normal_jpg_noext +0 -0
- data/test/data/image_normal_png_noext +0 -0
- data/test/data/image_pallete_based.png +0 -0
- data/test/data/legacy_layout/all-items.tlf +0 -1
- data/test/schema_helper.rb +0 -122
- data/test/test_helper.rb +0 -48
- data/test/tmp/.gitkeep +0 -0
- data/test/unit/core/format/test_base.rb +0 -152
- data/test/unit/core/shape/base/test_internal.rb +0 -87
- data/test/unit/core/shape/basic/test_block_format.rb +0 -23
- data/test/unit/core/shape/basic/test_block_interface.rb +0 -29
- data/test/unit/core/shape/basic/test_block_internal.rb +0 -55
- data/test/unit/core/shape/basic/test_format.rb +0 -37
- data/test/unit/core/shape/basic/test_interface.rb +0 -108
- data/test/unit/core/shape/basic/test_internal.rb +0 -55
- data/test/unit/core/shape/image_block/test_interface.rb +0 -24
- data/test/unit/core/shape/image_block/test_internal.rb +0 -31
- data/test/unit/core/shape/list/test_format.rb +0 -111
- data/test/unit/core/shape/list/test_manager.rb +0 -67
- data/test/unit/core/shape/list/test_page.rb +0 -82
- data/test/unit/core/shape/list/test_page_state.rb +0 -31
- data/test/unit/core/shape/list/test_section_format.rb +0 -36
- data/test/unit/core/shape/list/test_section_interface.rb +0 -75
- data/test/unit/core/shape/list/test_section_internal.rb +0 -50
- data/test/unit/core/shape/manager/test_format.rb +0 -38
- data/test/unit/core/shape/manager/test_internal.rb +0 -132
- data/test/unit/core/shape/manager/test_target.rb +0 -140
- data/test/unit/core/shape/page_number/test_format.rb +0 -55
- data/test/unit/core/shape/page_number/test_interface.rb +0 -33
- data/test/unit/core/shape/page_number/test_internal.rb +0 -81
- data/test/unit/core/shape/styles/test_base.rb +0 -191
- data/test/unit/core/shape/styles/test_basic.rb +0 -24
- data/test/unit/core/shape/styles/test_graphic.rb +0 -50
- data/test/unit/core/shape/styles/test_text.rb +0 -97
- data/test/unit/core/shape/text/test_format.rb +0 -44
- data/test/unit/core/shape/text/test_internal.rb +0 -20
- data/test/unit/core/shape/text_block/formatter/test_basic.rb +0 -24
- data/test/unit/core/shape/text_block/formatter/test_datetime.rb +0 -49
- data/test/unit/core/shape/text_block/formatter/test_number.rb +0 -76
- data/test/unit/core/shape/text_block/formatter/test_padding.rb +0 -77
- data/test/unit/core/shape/text_block/test_format.rb +0 -169
- data/test/unit/core/shape/text_block/test_formatter.rb +0 -28
- data/test/unit/core/shape/text_block/test_interface.rb +0 -63
- data/test/unit/core/shape/text_block/test_internal.rb +0 -128
- data/test/unit/core/test_shape.rb +0 -52
- data/test/unit/core/test_utils.rb +0 -68
- data/test/unit/generator/pdf/document/graphics/test_attributes.rb +0 -135
- data/test/unit/generator/pdf/document/graphics/test_basic.rb +0 -46
- data/test/unit/generator/pdf/document/graphics/test_image.rb +0 -46
- data/test/unit/generator/pdf/document/graphics/test_text.rb +0 -171
- data/test/unit/generator/pdf/document/test_font.rb +0 -84
- data/test/unit/generator/pdf/document/test_graphics.rb +0 -42
- data/test/unit/generator/pdf/document/test_page.rb +0 -122
- data/test/unit/generator/pdf/document/test_parse_color.rb +0 -30
- data/test/unit/generator/pdf/prawn_ext/test_calc_image_dimensions.rb +0 -41
- data/test/unit/generator/pdf/prawn_ext/test_width_of.rb +0 -22
- data/test/unit/generator/pdf/test_document.rb +0 -22
- data/test/unit/generator/test_pdf.rb +0 -26
- data/test/unit/layout/test_base.rb +0 -41
- data/test/unit/layout/test_format.rb +0 -100
- data/test/unit/layout/test_legacy_schema.rb +0 -574
- data/test/unit/layout/test_version.rb +0 -26
- data/test/unit/report/test_base.rb +0 -248
- data/test/unit/report/test_internal.rb +0 -206
- data/test/unit/test_config.rb +0 -36
- data/test/unit/test_layout.rb +0 -12
- data/test/unit/test_report.rb +0 -18
|
@@ -65,7 +65,6 @@ module Thinreports
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# @param [Hash] attrs
|
|
68
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
69
68
|
def with_graphic_styles(attrs, &block)
|
|
70
69
|
stroke = build_stroke_styles(attrs)
|
|
71
70
|
fill = build_fill_styles(attrs)
|
|
@@ -39,9 +39,16 @@ module Thinreports
|
|
|
39
39
|
# @param [Hash] options
|
|
40
40
|
# @option options [:left, :center, :right] :position_x (:left)
|
|
41
41
|
# @option options [:top, :center, :bottom] :position_y (:top)
|
|
42
|
+
# @option options [Numeric] :offset_x
|
|
43
|
+
# @option options [Numeric] :offset_y
|
|
42
44
|
def image_box(filename_or_io, x, y, w, h, options = {})
|
|
43
45
|
w, h = s2f(w, h)
|
|
44
|
-
|
|
46
|
+
|
|
47
|
+
computed_position = pos(
|
|
48
|
+
x + (options[:offset_x] || 0),
|
|
49
|
+
y + (options[:offset_y] || 0)
|
|
50
|
+
)
|
|
51
|
+
pdf.bounding_box(computed_position, width: w, height: h) do
|
|
45
52
|
pdf.image(
|
|
46
53
|
filename_or_io,
|
|
47
54
|
position: options[:position_x] || :left,
|
|
@@ -51,6 +58,17 @@ module Thinreports
|
|
|
51
58
|
end
|
|
52
59
|
end
|
|
53
60
|
|
|
61
|
+
def image_dimensions(filename_or_io, x, y, w, h, options = {})
|
|
62
|
+
w, h = s2f(w, h)
|
|
63
|
+
# XXX: Calling @private method
|
|
64
|
+
_pdf_obj, info = pdf.build_image_object(filename_or_io)
|
|
65
|
+
info.calc_image_dimensions(
|
|
66
|
+
position: options[:position_x] || :left,
|
|
67
|
+
vposition: options[:position_y] || :top,
|
|
68
|
+
auto_fit: [w, h]
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
54
72
|
def clean_temp_images
|
|
55
73
|
temp_image_registry.each_value do |image_path|
|
|
56
74
|
File.delete(image_path) if File.exist?(image_path)
|
|
@@ -22,7 +22,7 @@ module Thinreports
|
|
|
22
22
|
# @option attrs [Boolean] :single (false)
|
|
23
23
|
# @option attrs [:trancate, :shrink_to_fit, :expand] :overflow (:trancate)
|
|
24
24
|
# @option attrs [:none, :break_word] :word_wrap (:none)
|
|
25
|
-
def text_box(content, x, y, w, h, attrs = {})
|
|
25
|
+
def text_box(content, x, y, w, h, attrs = {}, &block)
|
|
26
26
|
w, h = s2f(w, h)
|
|
27
27
|
|
|
28
28
|
box_attrs = text_box_attrs(
|
|
@@ -35,12 +35,16 @@ module Thinreports
|
|
|
35
35
|
content = text_without_line_wrap(content) if attrs[:word_wrap] == :none
|
|
36
36
|
|
|
37
37
|
with_text_styles(attrs) do |built_attrs, font_styles|
|
|
38
|
-
|
|
39
|
-
[{ text: content, styles: font_styles }],
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
if block
|
|
39
|
+
block.call [{ text: content, styles: font_styles }],
|
|
40
|
+
built_attrs.merge(box_attrs)
|
|
41
|
+
else
|
|
42
|
+
pdf.formatted_text_box(
|
|
43
|
+
[{ text: content, styles: font_styles }],
|
|
44
|
+
built_attrs.merge(box_attrs)
|
|
45
|
+
)
|
|
46
|
+
end
|
|
42
47
|
end
|
|
43
|
-
# rubocop:disable Lint/HandleExceptions
|
|
44
48
|
rescue Prawn::Errors::CannotFit
|
|
45
49
|
# Nothing to do.
|
|
46
50
|
#
|
|
@@ -81,7 +85,6 @@ module Thinreports
|
|
|
81
85
|
# @yield [built_attrs, font_styles]
|
|
82
86
|
# @yieldparam [Hash] built_attrs The finalized attributes.
|
|
83
87
|
# @yieldparam [Array] font_styles The finalized styles.
|
|
84
|
-
# rubocop:disable Metrics/AbcSize
|
|
85
88
|
def with_text_styles(attrs, &block)
|
|
86
89
|
# When no color is given, do not draw.
|
|
87
90
|
return unless attrs.key?(:color) && attrs[:color] != 'none'
|
|
@@ -139,7 +142,6 @@ module Thinreports
|
|
|
139
142
|
# @yield [attributes, styles]
|
|
140
143
|
# @yieldparam [Hash] modified_attrs
|
|
141
144
|
# @yieldparam [Array] styles
|
|
142
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
143
145
|
def with_font_styles(attrs, font, &block)
|
|
144
146
|
# Building font styles.
|
|
145
147
|
styles = attrs.delete(:styles)
|
|
@@ -10,16 +10,13 @@ module Thinreports
|
|
|
10
10
|
}.freeze
|
|
11
11
|
|
|
12
12
|
# @param [Thinreports::Layout::Format] format
|
|
13
|
-
# rubocop:disable Metrics/AbcSize
|
|
14
13
|
def start_new_page(format)
|
|
15
14
|
format_id =
|
|
16
15
|
if change_page_format?(format)
|
|
17
16
|
pdf.start_new_page(new_basic_page_options(format))
|
|
18
17
|
@current_page_format = format
|
|
19
18
|
|
|
20
|
-
unless format_stamp_registry.include?(format.identifier)
|
|
21
|
-
create_format_stamp(format)
|
|
22
|
-
end
|
|
19
|
+
create_format_stamp(format) unless format_stamp_registry.include?(format.identifier)
|
|
23
20
|
format.identifier
|
|
24
21
|
else
|
|
25
22
|
pdf.start_new_page(new_basic_page_options(current_page_format))
|
|
@@ -29,6 +26,18 @@ module Thinreports
|
|
|
29
26
|
stamp(format_id.to_s)
|
|
30
27
|
end
|
|
31
28
|
|
|
29
|
+
def start_new_page_for_section_report(format)
|
|
30
|
+
@current_page_format = format
|
|
31
|
+
pdf.start_new_page(new_basic_page_options(current_page_format).merge(
|
|
32
|
+
top_margin: current_page_format.page_margin[0],
|
|
33
|
+
bottom_margin: current_page_format.page_margin[2]
|
|
34
|
+
))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def max_content_height
|
|
38
|
+
pdf.margin_box.height
|
|
39
|
+
end
|
|
40
|
+
|
|
32
41
|
def add_blank_page
|
|
33
42
|
pdf.start_new_page(pdf.page_count.zero? ? { size: 'A4' } : {})
|
|
34
43
|
end
|
|
@@ -20,9 +20,7 @@ module Thinreports
|
|
|
20
20
|
|
|
21
21
|
box_width, box_height = options.delete(:auto_fit)
|
|
22
22
|
|
|
23
|
-
if image_width > box_width || image_height > box_height
|
|
24
|
-
options[:fit] = [box_width, box_height]
|
|
25
|
-
end
|
|
23
|
+
options[:fit] = [box_width, box_height] if image_width > box_width || image_height > box_height
|
|
26
24
|
end
|
|
27
25
|
super(options)
|
|
28
26
|
end
|
|
@@ -4,16 +4,13 @@ module Thinreports
|
|
|
4
4
|
module Generator
|
|
5
5
|
module PrawnExt
|
|
6
6
|
module WidthOf
|
|
7
|
-
#
|
|
7
|
+
# This patch fixes the character_spacing effect on text width calculation.
|
|
8
8
|
#
|
|
9
|
-
# The original
|
|
10
|
-
#
|
|
11
|
-
# Width of Character is 1
|
|
12
|
-
# Width of Character Space is 1
|
|
9
|
+
# The original #width_of:
|
|
13
10
|
#
|
|
14
11
|
# width_of('abcd') #=> 4 + 4 = 8
|
|
15
12
|
#
|
|
16
|
-
#
|
|
13
|
+
# The #width_of in this patch:
|
|
17
14
|
#
|
|
18
15
|
# width_of('abcd') #=> 4 + 3 = 7
|
|
19
16
|
#
|
|
@@ -26,4 +23,7 @@ module Thinreports
|
|
|
26
23
|
end
|
|
27
24
|
end
|
|
28
25
|
|
|
29
|
-
Prawn
|
|
26
|
+
# Prawn v2.3 and later includes this patch by https://github.com/prawnpdf/prawn/pull/1117.
|
|
27
|
+
if Prawn::VERSION < '2.3.0'
|
|
28
|
+
Prawn::Document.prepend Thinreports::Generator::PrawnExt::WidthOf
|
|
29
|
+
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Thinreports
|
|
4
4
|
module Layout
|
|
5
5
|
class Base
|
|
6
|
-
EXT_NAME = 'tlf'
|
|
6
|
+
EXT_NAME = 'tlf'
|
|
7
7
|
include Utils
|
|
8
8
|
|
|
9
9
|
class << self
|
|
@@ -14,9 +14,7 @@ module Thinreports
|
|
|
14
14
|
def load_format(filename)
|
|
15
15
|
filename += ".#{EXT_NAME}" unless filename =~ /\.#{EXT_NAME}$/
|
|
16
16
|
|
|
17
|
-
unless File.exist?(filename)
|
|
18
|
-
raise Thinreports::Errors::LayoutFileNotFound
|
|
19
|
-
end
|
|
17
|
+
raise Thinreports::Errors::LayoutFileNotFound unless File.exist?(filename)
|
|
20
18
|
# Build format.
|
|
21
19
|
Thinreports::Layout::Format.build(filename)
|
|
22
20
|
end
|
|
@@ -5,7 +5,6 @@ require 'rexml/document'
|
|
|
5
5
|
|
|
6
6
|
module Thinreports
|
|
7
7
|
module Layout
|
|
8
|
-
# rubocop:disable Metrics/ClassLength
|
|
9
8
|
class LegacySchema
|
|
10
9
|
include Utils
|
|
11
10
|
|
|
@@ -17,7 +16,6 @@ module Thinreports
|
|
|
17
16
|
@legacy_svg = cleanup_svg(@legacy_svg)
|
|
18
17
|
end
|
|
19
18
|
|
|
20
|
-
# rubocop:disable Metrics/AbcSize
|
|
21
19
|
def upgrade
|
|
22
20
|
config = legacy_schema['config']
|
|
23
21
|
page_config = config['page']
|
|
@@ -48,7 +46,6 @@ module Thinreports
|
|
|
48
46
|
build_item_schemas_from_svg(svg.elements['/svg/g'])
|
|
49
47
|
end
|
|
50
48
|
|
|
51
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
52
49
|
def build_item_schemas_from_svg(svg_elements)
|
|
53
50
|
return [] unless svg_elements
|
|
54
51
|
|
|
@@ -107,6 +104,7 @@ module Thinreports
|
|
|
107
104
|
'width' => attributes['width'].to_f,
|
|
108
105
|
'height' => attributes['height'].to_f,
|
|
109
106
|
'display' => display(attributes['x-display']),
|
|
107
|
+
'border-radius' => attributes['rx'].to_i,
|
|
110
108
|
'style' => {
|
|
111
109
|
'border-width' => attributes['stroke-width'].to_f,
|
|
112
110
|
'border-color' => attributes['stroke'],
|
|
@@ -277,9 +275,7 @@ module Thinreports
|
|
|
277
275
|
'footer' => footer
|
|
278
276
|
}
|
|
279
277
|
|
|
280
|
-
if page_footer['enabled']
|
|
281
|
-
page_footer['translate']['y'] += detail['height']
|
|
282
|
-
end
|
|
278
|
+
page_footer['translate']['y'] += detail['height'] if page_footer['enabled']
|
|
283
279
|
|
|
284
280
|
if footer['enabled']
|
|
285
281
|
footer['translate']['y'] += detail['height']
|
|
@@ -33,9 +33,7 @@ module Thinreports
|
|
|
33
33
|
else
|
|
34
34
|
id = options[:id].to_sym
|
|
35
35
|
|
|
36
|
-
if layout_registry.key?(id)
|
|
37
|
-
raise ArgumentError, "Id :#{id} is already in use."
|
|
38
|
-
end
|
|
36
|
+
raise ArgumentError, "Id :#{id} is already in use." if layout_registry.key?(id)
|
|
39
37
|
layout_registry[id] = init_layout(layout, id)
|
|
40
38
|
end
|
|
41
39
|
end
|
|
@@ -74,7 +72,7 @@ module Thinreports
|
|
|
74
72
|
raise ArgumentError, 'Invalid argument for layout.'
|
|
75
73
|
end
|
|
76
74
|
|
|
77
|
-
@default_layout
|
|
75
|
+
@default_layout ||= layout
|
|
78
76
|
layout
|
|
79
77
|
end
|
|
80
78
|
|
|
@@ -98,6 +96,8 @@ module Thinreports
|
|
|
98
96
|
end
|
|
99
97
|
|
|
100
98
|
def init_layout(filename, id = nil)
|
|
99
|
+
filename = filename.to_path if filename.is_a?(Pathname)
|
|
100
|
+
|
|
101
101
|
Thinreports::Layout.new(filename, id: id)
|
|
102
102
|
end
|
|
103
103
|
end
|
|
@@ -64,7 +64,6 @@ module Thinreports
|
|
|
64
64
|
false
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
# rubocop:disable Metrics/AbcSize
|
|
68
67
|
def copy
|
|
69
68
|
new_page = self.class.new(report, layout, count: count?)
|
|
70
69
|
|
|
@@ -72,9 +71,7 @@ module Thinreports
|
|
|
72
71
|
new_shape = shape.copy(new_page)
|
|
73
72
|
new_page.manager.shapes[id] = new_shape
|
|
74
73
|
|
|
75
|
-
if new_shape.internal.type_of?(Core::Shape::List::TYPE_NAME)
|
|
76
|
-
new_page.manager.lists[id] = new_shape
|
|
77
|
-
end
|
|
74
|
+
new_page.manager.lists[id] = new_shape if new_shape.internal.type_of?(Core::Shape::List::TYPE_NAME)
|
|
78
75
|
end
|
|
79
76
|
new_page
|
|
80
77
|
end
|
|
@@ -85,9 +82,7 @@ module Thinreports
|
|
|
85
82
|
at = options[:at] || :create
|
|
86
83
|
|
|
87
84
|
# For list shapes.
|
|
88
|
-
if at == :create
|
|
89
|
-
manager.lists.values.each { |list| list.manager.finalize }
|
|
90
|
-
end
|
|
85
|
+
manager.lists.each_value { |list| list.manager.finalize } if at == :create
|
|
91
86
|
|
|
92
87
|
@finalized = true
|
|
93
88
|
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'schema/loader'
|
|
4
|
+
require_relative 'builder/report_builder'
|
|
5
|
+
|
|
6
|
+
module Thinreports
|
|
7
|
+
module SectionReport
|
|
8
|
+
class Build
|
|
9
|
+
def call(report_params)
|
|
10
|
+
schema = load_schema(report_params)
|
|
11
|
+
params = report_params[:params] || {}
|
|
12
|
+
|
|
13
|
+
Builder::ReportBuilder.new(schema).build(params)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def load_schema(report_params)
|
|
19
|
+
loader = Schema::Loader.new
|
|
20
|
+
|
|
21
|
+
case
|
|
22
|
+
when report_params[:layout_file]
|
|
23
|
+
loader.load_from_file(report_params[:layout_file])
|
|
24
|
+
when report_params[:layout_data]
|
|
25
|
+
loader.load_from_data(report_params[:layout_data])
|
|
26
|
+
else
|
|
27
|
+
raise Errors::LayoutFileNotFound
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'stack_view_builder'
|
|
4
|
+
|
|
5
|
+
module Thinreports
|
|
6
|
+
module SectionReport
|
|
7
|
+
module Builder
|
|
8
|
+
class ItemBuilder
|
|
9
|
+
Context = Struct.new(:parent_schema)
|
|
10
|
+
|
|
11
|
+
def initialize(item_schema, parent_schema)
|
|
12
|
+
@item = Core::Shape::Interface(nil, item_schema)
|
|
13
|
+
@parent_schema = parent_schema
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def build(item_params)
|
|
17
|
+
params = build_params(item_params)
|
|
18
|
+
|
|
19
|
+
item.visible(params[:display]) if params.key?(:display)
|
|
20
|
+
item.value(params[:value]) if params.key?(:value)
|
|
21
|
+
item.styles(params[:styles]) if params.key?(:styles)
|
|
22
|
+
|
|
23
|
+
if item.internal.format.attributes['type'] == Core::Shape::StackView::TYPE_NAME
|
|
24
|
+
StackViewBuilder.new(item).update(params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
item
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
attr_reader :item, :parent_schema
|
|
33
|
+
|
|
34
|
+
def build_params(params)
|
|
35
|
+
return {} unless params
|
|
36
|
+
|
|
37
|
+
case params
|
|
38
|
+
when Hash
|
|
39
|
+
params
|
|
40
|
+
when Proc
|
|
41
|
+
params.call(Context.new(parent_schema))
|
|
42
|
+
else
|
|
43
|
+
{ value: params }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'report_data'
|
|
4
|
+
require_relative 'item_builder'
|
|
5
|
+
|
|
6
|
+
module Thinreports
|
|
7
|
+
module SectionReport
|
|
8
|
+
module Builder
|
|
9
|
+
class ReportBuilder
|
|
10
|
+
def initialize(schema)
|
|
11
|
+
@schema = schema
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def build(params)
|
|
15
|
+
ReportData::Main.new(
|
|
16
|
+
schema,
|
|
17
|
+
build_groups(params[:groups])
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
attr_reader :schema
|
|
24
|
+
|
|
25
|
+
def build_groups(groups_params)
|
|
26
|
+
return [] unless groups_params
|
|
27
|
+
|
|
28
|
+
groups_params.map do |group_params|
|
|
29
|
+
ReportData::Group.new(
|
|
30
|
+
build_sections(:header, group_params[:headers] || {}),
|
|
31
|
+
build_detail_sections(group_params[:details] || []),
|
|
32
|
+
build_sections(:footer, group_params[:footers] || {})
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def build_sections(section_type, sections_params)
|
|
38
|
+
sections_schemas =
|
|
39
|
+
case section_type
|
|
40
|
+
when :header then schema.headers
|
|
41
|
+
when :footer then schema.footers
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
sections_schemas.each_with_object([]) do |(section_id, section_schema), sections|
|
|
45
|
+
section_params = sections_params[section_id.to_sym] || {}
|
|
46
|
+
next unless section_enabled?(section_schema, section_params)
|
|
47
|
+
|
|
48
|
+
items = build_items(section_schema, section_params[:items] || {})
|
|
49
|
+
sections << ReportData::Section.new(section_schema, items, section_params[:min_height])
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def build_detail_sections(details_params)
|
|
54
|
+
details_params.each_with_object([]) do |detail_params, details|
|
|
55
|
+
detail_id = detail_params[:id].to_sym
|
|
56
|
+
detail_schema = schema.details[detail_id]
|
|
57
|
+
|
|
58
|
+
next unless detail_schema
|
|
59
|
+
|
|
60
|
+
items = build_items(detail_schema, detail_params[:items] || {})
|
|
61
|
+
details << ReportData::Section.new(detail_schema, items, detail_params[:min_height])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def build_items(section_schema, items_params)
|
|
66
|
+
section_schema.items.each_with_object([]) do |item_schema, items|
|
|
67
|
+
item = ItemBuilder.new(item_schema, section_schema).build(items_params[item_schema.id&.to_sym])
|
|
68
|
+
items << item if item.visible?
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def section_enabled?(section_schema, section_params)
|
|
73
|
+
if section_params.key?(:display)
|
|
74
|
+
section_params[:display]
|
|
75
|
+
else
|
|
76
|
+
section_schema.display?
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|