thinreports 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/test.yml +31 -40
- data/.gitignore +1 -1
- data/CHANGELOG.md +25 -1
- data/Gemfile +11 -0
- data/{MIT-LICENSE → LICENSE.txt} +2 -0
- data/README.md +50 -66
- data/Rakefile +17 -11
- data/lib/thinreports/basic_report/core/errors.rb +62 -0
- data/lib/thinreports/basic_report/core/format/base.rb +91 -0
- data/lib/thinreports/basic_report/core/shape/base/interface.rb +42 -0
- data/lib/thinreports/basic_report/core/shape/base/internal.rb +53 -0
- data/lib/thinreports/basic_report/core/shape/basic/block_format.rb +15 -0
- data/lib/thinreports/basic_report/core/shape/basic/block_interface.rb +34 -0
- data/lib/thinreports/basic_report/core/shape/basic/block_internal.rb +36 -0
- data/lib/thinreports/basic_report/core/shape/basic/format.rb +24 -0
- data/lib/thinreports/basic_report/core/shape/basic/interface.rb +87 -0
- data/lib/thinreports/basic_report/core/shape/basic/internal.rb +28 -0
- data/lib/thinreports/{core → basic_report/core}/shape/basic.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/image_block/format.rb +14 -0
- data/lib/thinreports/basic_report/core/shape/image_block/interface.rb +25 -0
- data/lib/thinreports/basic_report/core/shape/image_block/internal.rb +19 -0
- data/lib/thinreports/{core → basic_report/core}/shape/image_block.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/list/format.rb +92 -0
- data/lib/thinreports/basic_report/core/shape/list/manager.rb +231 -0
- data/lib/thinreports/basic_report/core/shape/list/page.rb +112 -0
- data/lib/thinreports/basic_report/core/shape/list/page_state.rb +50 -0
- data/lib/thinreports/basic_report/core/shape/list/section_format.rb +37 -0
- data/lib/thinreports/basic_report/core/shape/list/section_interface.rb +51 -0
- data/lib/thinreports/basic_report/core/shape/list/section_internal.rb +33 -0
- data/lib/thinreports/{core → basic_report/core}/shape/list.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/manager/format.rb +33 -0
- data/lib/thinreports/basic_report/core/shape/manager/internal.rb +109 -0
- data/lib/thinreports/basic_report/core/shape/manager/target.rb +114 -0
- data/lib/thinreports/basic_report/core/shape/page_number/format.rb +32 -0
- data/lib/thinreports/basic_report/core/shape/page_number/interface.rb +31 -0
- data/lib/thinreports/basic_report/core/shape/page_number/internal.rb +57 -0
- data/lib/thinreports/{core → basic_report/core}/shape/page_number.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/stack_view/format.rb +29 -0
- data/lib/thinreports/basic_report/core/shape/stack_view/interface.rb +19 -0
- data/lib/thinreports/basic_report/core/shape/stack_view/internal.rb +24 -0
- data/lib/thinreports/basic_report/core/shape/stack_view/row_format.rb +41 -0
- data/lib/thinreports/{core → basic_report/core}/shape/stack_view.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/style/base.rb +149 -0
- data/lib/thinreports/basic_report/core/shape/style/basic.rb +24 -0
- data/lib/thinreports/basic_report/core/shape/style/graphic.rb +43 -0
- data/lib/thinreports/basic_report/core/shape/style/text.rb +122 -0
- data/lib/thinreports/basic_report/core/shape/text/format.rb +17 -0
- data/lib/thinreports/basic_report/core/shape/text/interface.rb +20 -0
- data/lib/thinreports/basic_report/core/shape/text/internal.rb +24 -0
- data/lib/thinreports/{core → basic_report/core}/shape/text.rb +6 -4
- data/lib/thinreports/basic_report/core/shape/text_block/format.rb +43 -0
- data/lib/thinreports/basic_report/core/shape/text_block/formatter/basic.rb +41 -0
- data/lib/thinreports/basic_report/core/shape/text_block/formatter/datetime.rb +25 -0
- data/lib/thinreports/basic_report/core/shape/text_block/formatter/number.rb +69 -0
- data/lib/thinreports/basic_report/core/shape/text_block/formatter/padding.rb +27 -0
- data/lib/thinreports/basic_report/core/shape/text_block/formatter.rb +38 -0
- data/lib/thinreports/basic_report/core/shape/text_block/interface.rb +37 -0
- data/lib/thinreports/basic_report/core/shape/text_block/internal.rb +75 -0
- data/lib/thinreports/{core → basic_report/core}/shape/text_block.rb +6 -4
- data/lib/thinreports/basic_report/core/shape.rb +44 -0
- data/lib/thinreports/basic_report/core/utils.rb +47 -0
- data/lib/thinreports/basic_report/generator/pdf/document/draw_shape.rb +108 -0
- data/lib/thinreports/basic_report/generator/pdf/document/draw_template_items.rb +71 -0
- data/lib/thinreports/basic_report/generator/pdf/document/font.rb +90 -0
- data/lib/thinreports/basic_report/generator/pdf/document/graphics/attributes.rb +149 -0
- data/lib/thinreports/basic_report/generator/pdf/document/graphics/basic.rb +137 -0
- data/lib/thinreports/basic_report/generator/pdf/document/graphics/image.rb +99 -0
- data/lib/thinreports/basic_report/generator/pdf/document/graphics/text.rb +180 -0
- data/lib/thinreports/basic_report/generator/pdf/document/graphics.rb +42 -0
- data/lib/thinreports/basic_report/generator/pdf/document/page.rb +96 -0
- data/lib/thinreports/basic_report/generator/pdf/document/parse_color.rb +51 -0
- data/lib/thinreports/basic_report/generator/pdf/document.rb +132 -0
- data/lib/thinreports/basic_report/generator/pdf/drawer/base.rb +50 -0
- data/lib/thinreports/basic_report/generator/pdf/drawer/list.rb +65 -0
- data/lib/thinreports/basic_report/generator/pdf/drawer/list_section.rb +51 -0
- data/lib/thinreports/basic_report/generator/pdf/drawer/page.rb +127 -0
- data/lib/thinreports/basic_report/generator/pdf/prawn_ext/calc_image_dimensions.rb +34 -0
- data/lib/thinreports/basic_report/generator/pdf/prawn_ext/width_of.rb +31 -0
- data/lib/thinreports/basic_report/generator/pdf.rb +66 -0
- data/lib/thinreports/basic_report/layout/base.rb +48 -0
- data/lib/thinreports/basic_report/layout/format.rb +67 -0
- data/lib/thinreports/basic_report/layout/legacy_schema.rb +383 -0
- data/lib/thinreports/basic_report/layout/version.rb +41 -0
- data/lib/thinreports/{layout.rb → basic_report/layout.rb} +6 -4
- data/lib/thinreports/basic_report/report/base.rb +173 -0
- data/lib/thinreports/basic_report/report/internal.rb +107 -0
- data/lib/thinreports/basic_report/report/page.rb +97 -0
- data/lib/thinreports/basic_report/report.rb +26 -0
- data/lib/thinreports/basic_report.rb +15 -0
- data/lib/thinreports/config.rb +1 -1
- data/lib/thinreports/section_report/builder/stack_view_builder.rb +0 -2
- data/lib/thinreports/section_report.rb +12 -0
- data/lib/thinreports/version.rb +1 -1
- data/lib/thinreports.rb +2 -13
- data/thinreports.gemspec +3 -7
- metadata +99 -157
- data/Dockerfile +0 -12
- data/gemfiles/prawn-2.2.gemfile +0 -5
- data/gemfiles/prawn-2.3.gemfile +0 -5
- data/gemfiles/prawn-2.4.gemfile +0 -5
- data/lib/thinreports/core/errors.rb +0 -60
- data/lib/thinreports/core/format/base.rb +0 -89
- data/lib/thinreports/core/shape/base/interface.rb +0 -40
- data/lib/thinreports/core/shape/base/internal.rb +0 -51
- data/lib/thinreports/core/shape/basic/block_format.rb +0 -13
- data/lib/thinreports/core/shape/basic/block_interface.rb +0 -32
- data/lib/thinreports/core/shape/basic/block_internal.rb +0 -34
- data/lib/thinreports/core/shape/basic/format.rb +0 -22
- data/lib/thinreports/core/shape/basic/interface.rb +0 -85
- data/lib/thinreports/core/shape/basic/internal.rb +0 -26
- data/lib/thinreports/core/shape/image_block/format.rb +0 -12
- data/lib/thinreports/core/shape/image_block/interface.rb +0 -23
- data/lib/thinreports/core/shape/image_block/internal.rb +0 -17
- data/lib/thinreports/core/shape/list/format.rb +0 -90
- data/lib/thinreports/core/shape/list/manager.rb +0 -229
- data/lib/thinreports/core/shape/list/page.rb +0 -110
- data/lib/thinreports/core/shape/list/page_state.rb +0 -48
- data/lib/thinreports/core/shape/list/section_format.rb +0 -35
- data/lib/thinreports/core/shape/list/section_interface.rb +0 -49
- data/lib/thinreports/core/shape/list/section_internal.rb +0 -31
- data/lib/thinreports/core/shape/manager/format.rb +0 -31
- data/lib/thinreports/core/shape/manager/internal.rb +0 -107
- data/lib/thinreports/core/shape/manager/target.rb +0 -112
- data/lib/thinreports/core/shape/page_number/format.rb +0 -30
- data/lib/thinreports/core/shape/page_number/interface.rb +0 -29
- data/lib/thinreports/core/shape/page_number/internal.rb +0 -55
- data/lib/thinreports/core/shape/stack_view/format.rb +0 -27
- data/lib/thinreports/core/shape/stack_view/interface.rb +0 -17
- data/lib/thinreports/core/shape/stack_view/internal.rb +0 -22
- data/lib/thinreports/core/shape/stack_view/row_format.rb +0 -39
- data/lib/thinreports/core/shape/style/base.rb +0 -146
- data/lib/thinreports/core/shape/style/basic.rb +0 -22
- data/lib/thinreports/core/shape/style/graphic.rb +0 -41
- data/lib/thinreports/core/shape/style/text.rb +0 -120
- data/lib/thinreports/core/shape/text/format.rb +0 -15
- data/lib/thinreports/core/shape/text/interface.rb +0 -18
- data/lib/thinreports/core/shape/text/internal.rb +0 -22
- data/lib/thinreports/core/shape/text_block/format.rb +0 -41
- data/lib/thinreports/core/shape/text_block/formatter/basic.rb +0 -39
- data/lib/thinreports/core/shape/text_block/formatter/datetime.rb +0 -23
- data/lib/thinreports/core/shape/text_block/formatter/number.rb +0 -67
- data/lib/thinreports/core/shape/text_block/formatter/padding.rb +0 -25
- data/lib/thinreports/core/shape/text_block/formatter.rb +0 -34
- data/lib/thinreports/core/shape/text_block/interface.rb +0 -35
- data/lib/thinreports/core/shape/text_block/internal.rb +0 -73
- data/lib/thinreports/core/shape.rb +0 -42
- data/lib/thinreports/core/utils.rb +0 -45
- data/lib/thinreports/generate.rb +0 -11
- data/lib/thinreports/generator/pdf/document/draw_shape.rb +0 -106
- data/lib/thinreports/generator/pdf/document/draw_template_items.rb +0 -69
- data/lib/thinreports/generator/pdf/document/font.rb +0 -88
- data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +0 -147
- data/lib/thinreports/generator/pdf/document/graphics/basic.rb +0 -135
- data/lib/thinreports/generator/pdf/document/graphics/image.rb +0 -98
- data/lib/thinreports/generator/pdf/document/graphics/text.rb +0 -178
- data/lib/thinreports/generator/pdf/document/graphics.rb +0 -40
- data/lib/thinreports/generator/pdf/document/page.rb +0 -94
- data/lib/thinreports/generator/pdf/document/parse_color.rb +0 -49
- data/lib/thinreports/generator/pdf/document.rb +0 -130
- data/lib/thinreports/generator/pdf/drawer/base.rb +0 -48
- data/lib/thinreports/generator/pdf/drawer/list.rb +0 -63
- data/lib/thinreports/generator/pdf/drawer/list_section.rb +0 -49
- data/lib/thinreports/generator/pdf/drawer/page.rb +0 -125
- data/lib/thinreports/generator/pdf/prawn_ext/calc_image_dimensions.rb +0 -32
- data/lib/thinreports/generator/pdf/prawn_ext/width_of.rb +0 -29
- data/lib/thinreports/generator/pdf.rb +0 -63
- data/lib/thinreports/layout/base.rb +0 -46
- data/lib/thinreports/layout/format.rb +0 -65
- data/lib/thinreports/layout/legacy_schema.rb +0 -381
- data/lib/thinreports/layout/version.rb +0 -39
- data/lib/thinreports/report/base.rb +0 -169
- data/lib/thinreports/report/internal.rb +0 -105
- data/lib/thinreports/report/page.rb +0 -95
- data/lib/thinreports/report.rb +0 -24
- data/lib/thinreports/section_report/pdf/renderer/headers_renderer.rb +0 -24
- /data/lib/thinreports/{core → basic_report/core}/shape/base.rb +0 -0
- /data/lib/thinreports/{core → basic_report/core}/shape/manager.rb +0 -0
- /data/lib/thinreports/{core → basic_report/core}/shape/style.rb +0 -0
- /data/lib/thinreports/{generator → basic_report/generator}/pdf/prawn_ext.rb +0 -0
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Thinreports
|
4
|
-
module Layout
|
5
|
-
class Base
|
6
|
-
EXT_NAME = 'tlf'
|
7
|
-
include Utils
|
8
|
-
|
9
|
-
class << self
|
10
|
-
# @param [String] filename
|
11
|
-
# @return [Thinreports::Layout::Format]
|
12
|
-
# @raise [Thinreports::Errors::InvalidLayoutFormat]
|
13
|
-
# @raise [Thinreports::Errors::IncompatibleLayoutFormat]
|
14
|
-
def load_format(filename)
|
15
|
-
filename += ".#{EXT_NAME}" unless filename =~ /\.#{EXT_NAME}$/
|
16
|
-
|
17
|
-
raise Thinreports::Errors::LayoutFileNotFound unless File.exist?(filename)
|
18
|
-
# Build format.
|
19
|
-
Thinreports::Layout::Format.build(filename)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
attr_reader :format
|
24
|
-
|
25
|
-
# @return [String]
|
26
|
-
attr_reader :filename
|
27
|
-
|
28
|
-
# @return [Symbol]
|
29
|
-
attr_reader :id
|
30
|
-
|
31
|
-
# @param [String] filename
|
32
|
-
# @param [Hash] options
|
33
|
-
# @option options [Symbol] :id (nil)
|
34
|
-
def initialize(filename, options = {})
|
35
|
-
@filename = filename
|
36
|
-
@format = self.class.load_format(filename)
|
37
|
-
@id = options[:id]
|
38
|
-
end
|
39
|
-
|
40
|
-
# @return [Boolean] Return the true if is default layout.
|
41
|
-
def default?
|
42
|
-
@id.nil?
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module Thinreports
|
6
|
-
module Layout
|
7
|
-
class Format < Core::Shape::Manager::Format
|
8
|
-
config_reader last_version: %w[version]
|
9
|
-
config_reader report_title: %w[title]
|
10
|
-
config_reader page_paper_type: %w[report paper-type],
|
11
|
-
page_width: %w[report width],
|
12
|
-
page_height: %w[report height],
|
13
|
-
page_orientation: %w[report orientation]
|
14
|
-
|
15
|
-
class << self
|
16
|
-
def build(filename)
|
17
|
-
schema = JSON.parse(read_file(filename))
|
18
|
-
schema_version = Layout::Version.new(schema['version'])
|
19
|
-
|
20
|
-
unless schema_version.compatible?
|
21
|
-
raise Errors::IncompatibleLayoutFormat.new(
|
22
|
-
filename, schema['version'],
|
23
|
-
Layout::Version.compatible_rules.join(' and ')
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
if schema_version.legacy?
|
28
|
-
warn '[DEPRECATION] Support for the layout file with old format' \
|
29
|
-
' that generated with Editor 0.8 or lower will be dropped in Thinreports 1.1.' \
|
30
|
-
' Please convert to new layout format using Thinreports Editor 0.9 or 1.0.'
|
31
|
-
schema = Layout::LegacySchema.new(schema).upgrade
|
32
|
-
end
|
33
|
-
|
34
|
-
new schema
|
35
|
-
end
|
36
|
-
|
37
|
-
def read_file(filename)
|
38
|
-
File.read(filename, encoding: 'UTF-8')
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize(*)
|
43
|
-
super
|
44
|
-
initialize_items(attributes['items'])
|
45
|
-
end
|
46
|
-
|
47
|
-
def user_paper_type?
|
48
|
-
page_paper_type == 'user'
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def initialize_items(item_schemas)
|
54
|
-
item_schemas.each do |item_schema|
|
55
|
-
id, type = item_schema.values_at 'id', 'type'
|
56
|
-
|
57
|
-
next if id.empty? && type != 'page-number'
|
58
|
-
|
59
|
-
item = Core::Shape::Format(type).new(item_schema)
|
60
|
-
shapes[item.id.to_sym] = item
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,381 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
require 'rexml/document'
|
5
|
-
|
6
|
-
module Thinreports
|
7
|
-
module Layout
|
8
|
-
class LegacySchema
|
9
|
-
include Utils
|
10
|
-
|
11
|
-
def initialize(legacy_schema)
|
12
|
-
@legacy_schema = legacy_schema
|
13
|
-
@legacy_svg = legacy_schema['svg'].dup
|
14
|
-
@legacy_item_schemas = extract_legacy_item_schemas(legacy_svg)
|
15
|
-
|
16
|
-
@legacy_svg = cleanup_svg(@legacy_svg)
|
17
|
-
end
|
18
|
-
|
19
|
-
def upgrade
|
20
|
-
config = legacy_schema['config']
|
21
|
-
page_config = config['page']
|
22
|
-
|
23
|
-
{
|
24
|
-
'version' => legacy_schema['version'],
|
25
|
-
'title' => legacy_schema['config']['title'],
|
26
|
-
'report' => {
|
27
|
-
'paper-type' => page_config['paper-type'],
|
28
|
-
'width' => page_config['width'].to_f,
|
29
|
-
'height' => page_config['height'].to_f,
|
30
|
-
'orientation' => page_config['orientation'],
|
31
|
-
'margin' => page_config.values_at(
|
32
|
-
'margin-top',
|
33
|
-
'margin-right',
|
34
|
-
'margin-bottom',
|
35
|
-
'margin-left'
|
36
|
-
).map(&:to_f)
|
37
|
-
},
|
38
|
-
'items' => item_schemas
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
attr_reader :legacy_schema, :legacy_svg, :legacy_item_schemas
|
43
|
-
|
44
|
-
def item_schemas
|
45
|
-
svg = REXML::Document.new(legacy_svg)
|
46
|
-
build_item_schemas_from_svg(svg.elements['/svg/g'])
|
47
|
-
end
|
48
|
-
|
49
|
-
def build_item_schemas_from_svg(svg_elements)
|
50
|
-
return [] unless svg_elements
|
51
|
-
|
52
|
-
items = []
|
53
|
-
|
54
|
-
svg_elements.each do |item_element|
|
55
|
-
item_attributes = item_element.attributes
|
56
|
-
|
57
|
-
items <<
|
58
|
-
case item_element.attributes['class']
|
59
|
-
when 's-text' then text_item_schema(item_attributes, extract_texts_from(item_element))
|
60
|
-
when 's-image' then image_item_schema(item_attributes)
|
61
|
-
when 's-rect' then rect_item_schema(item_attributes)
|
62
|
-
when 's-ellipse' then ellipse_item_schema(item_attributes)
|
63
|
-
when 's-line' then line_item_schema(item_attributes)
|
64
|
-
when 's-tblock' then text_block_item_schema(item_attributes)
|
65
|
-
when 's-iblock' then image_block_item_schema(item_attributes)
|
66
|
-
when 's-pageno' then page_number_item_schema(item_attributes)
|
67
|
-
when 's-list' then list_item_schema(item_element)
|
68
|
-
else raise 'Unknown item type'
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
items
|
73
|
-
end
|
74
|
-
|
75
|
-
def text_item_schema(attributes, texts)
|
76
|
-
{
|
77
|
-
'id' => attributes['x-id'],
|
78
|
-
'type' => Core::Shape::Text::TYPE_NAME,
|
79
|
-
'x' => attributes['x-left'].to_f,
|
80
|
-
'y' => attributes['x-top'].to_f,
|
81
|
-
'width' => attributes['x-width'].to_f,
|
82
|
-
'height' => attributes['x-height'].to_f,
|
83
|
-
'display' => display(attributes['x-display']),
|
84
|
-
'texts' => texts,
|
85
|
-
'style' => {
|
86
|
-
'font-family' => [attributes['font-family']],
|
87
|
-
'font-size' => attributes['font-size'].to_f,
|
88
|
-
'color' => attributes['fill'],
|
89
|
-
'font-style' => font_style(attributes),
|
90
|
-
'text-align' => text_align(attributes['text-anchor']),
|
91
|
-
'vertical-align' => vertical_align(attributes['x-valign']),
|
92
|
-
'line-height' => line_height(attributes['x-line-height']),
|
93
|
-
'letter-spacing' => letter_spacing(attributes['kerning'])
|
94
|
-
}
|
95
|
-
}
|
96
|
-
end
|
97
|
-
|
98
|
-
def rect_item_schema(attributes)
|
99
|
-
{
|
100
|
-
'id' => attributes['x-id'],
|
101
|
-
'type' => 'rect',
|
102
|
-
'x' => attributes['x'].to_f,
|
103
|
-
'y' => attributes['y'].to_f,
|
104
|
-
'width' => attributes['width'].to_f,
|
105
|
-
'height' => attributes['height'].to_f,
|
106
|
-
'display' => display(attributes['x-display']),
|
107
|
-
'border-radius' => attributes['rx'].to_i,
|
108
|
-
'style' => {
|
109
|
-
'border-width' => attributes['stroke-width'].to_f,
|
110
|
-
'border-color' => attributes['stroke'],
|
111
|
-
'border-style' => attributes['x-stroke-type'],
|
112
|
-
'fill-color' => attributes['fill']
|
113
|
-
}
|
114
|
-
}
|
115
|
-
end
|
116
|
-
|
117
|
-
def line_item_schema(attributes)
|
118
|
-
{
|
119
|
-
'id' => attributes['x-id'],
|
120
|
-
'type' => 'line',
|
121
|
-
'x1' => attributes['x1'].to_f,
|
122
|
-
'y1' => attributes['y1'].to_f,
|
123
|
-
'x2' => attributes['x2'].to_f,
|
124
|
-
'y2' => attributes['y2'].to_f,
|
125
|
-
'display' => display(attributes['x-display']),
|
126
|
-
'style' => {
|
127
|
-
'border-width' => attributes['stroke-width'].to_f,
|
128
|
-
'border-color' => attributes['stroke'],
|
129
|
-
'border-style' => attributes['x-stroke-type']
|
130
|
-
}
|
131
|
-
}
|
132
|
-
end
|
133
|
-
|
134
|
-
def ellipse_item_schema(attributes)
|
135
|
-
{
|
136
|
-
'id' => attributes['x-id'],
|
137
|
-
'type' => 'ellipse',
|
138
|
-
'cx' => attributes['cx'].to_f,
|
139
|
-
'cy' => attributes['cy'].to_f,
|
140
|
-
'rx' => attributes['rx'].to_f,
|
141
|
-
'ry' => attributes['ry'].to_f,
|
142
|
-
'display' => display(attributes['x-display']),
|
143
|
-
'style' => {
|
144
|
-
'border-width' => attributes['stroke-width'].to_f,
|
145
|
-
'border-color' => attributes['stroke'],
|
146
|
-
'border-style' => attributes['x-stroke-type'],
|
147
|
-
'fill-color' => attributes['fill']
|
148
|
-
}
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
def image_item_schema(attributes)
|
153
|
-
_, image_type, image_data = attributes['xlink:href'].match(%r{^data:(image/[a-z]+?);base64,(.+)}).to_a
|
154
|
-
|
155
|
-
{
|
156
|
-
'id' => attributes['x-id'],
|
157
|
-
'type' => 'image',
|
158
|
-
'x' => attributes['x'].to_f,
|
159
|
-
'y' => attributes['y'].to_f,
|
160
|
-
'width' => attributes['width'].to_f,
|
161
|
-
'height' => attributes['height'].to_f,
|
162
|
-
'display' => display(attributes['x-display']),
|
163
|
-
'data' => {
|
164
|
-
'mime-type' => image_type,
|
165
|
-
'base64' => image_data
|
166
|
-
}
|
167
|
-
}
|
168
|
-
end
|
169
|
-
|
170
|
-
def page_number_item_schema(attributes)
|
171
|
-
{
|
172
|
-
'id' => attributes['x-id'],
|
173
|
-
'type' => Core::Shape::PageNumber::TYPE_NAME,
|
174
|
-
'x' => attributes['x-left'].to_f,
|
175
|
-
'y' => attributes['x-top'].to_f,
|
176
|
-
'width' => attributes['x-width'].to_f,
|
177
|
-
'height' => attributes['x-height'].to_f,
|
178
|
-
'format' => attributes['x-format'],
|
179
|
-
'target' => attributes['x-target'],
|
180
|
-
'display' => display(attributes['x-display']),
|
181
|
-
'style' => {
|
182
|
-
'font-family' => [attributes['font-family']],
|
183
|
-
'font-size' => attributes['font-size'].to_f,
|
184
|
-
'color' => attributes['fill'],
|
185
|
-
'font-style' => font_style(attributes),
|
186
|
-
'text-align' => text_align(attributes['text-anchor']),
|
187
|
-
'overflow' => attributes['x-overflow']
|
188
|
-
}
|
189
|
-
}
|
190
|
-
end
|
191
|
-
|
192
|
-
def image_block_item_schema(attributes)
|
193
|
-
{
|
194
|
-
'id' => attributes['x-id'],
|
195
|
-
'type' => Core::Shape::ImageBlock::TYPE_NAME,
|
196
|
-
'x' => attributes['x-left'].to_f,
|
197
|
-
'y' => attributes['x-top'].to_f,
|
198
|
-
'width' => attributes['x-width'].to_f,
|
199
|
-
'height' => attributes['x-height'].to_f,
|
200
|
-
'display' => display(attributes['x-display']),
|
201
|
-
'style' => {
|
202
|
-
'position-x' => attributes['x-position-x'],
|
203
|
-
'position-y' => image_position_y(attributes['x-position-y'])
|
204
|
-
}
|
205
|
-
}
|
206
|
-
end
|
207
|
-
|
208
|
-
def text_block_item_schema(attributes)
|
209
|
-
text_format = {
|
210
|
-
'base' => attributes['x-format-base'],
|
211
|
-
'type' => attributes['x-format-type']
|
212
|
-
}
|
213
|
-
case text_format['type']
|
214
|
-
when 'datetime'
|
215
|
-
text_format['datetime'] = {
|
216
|
-
'format' => attributes['x-format-datetime-format']
|
217
|
-
}
|
218
|
-
when 'number'
|
219
|
-
text_format['number'] = {
|
220
|
-
'delimiter' => attributes['x-format-number-delimiter'],
|
221
|
-
'precision' => attributes['x-format-number-precision'].to_i
|
222
|
-
}
|
223
|
-
when 'padding'
|
224
|
-
text_format['padding'] = {
|
225
|
-
'length' => attributes['x-format-padding-length'].to_i,
|
226
|
-
'char' => attributes['x-format-padding-char'],
|
227
|
-
'direction' => attributes['x-format-padding-direction']
|
228
|
-
}
|
229
|
-
end
|
230
|
-
|
231
|
-
{
|
232
|
-
'id' => attributes['x-id'],
|
233
|
-
'type' => Core::Shape::TextBlock::TYPE_NAME,
|
234
|
-
'x' => attributes['x-left'].to_f,
|
235
|
-
'y' => attributes['x-top'].to_f,
|
236
|
-
'width' => attributes['x-width'].to_f,
|
237
|
-
'height' => attributes['x-height'].to_f,
|
238
|
-
'display' => display(attributes['x-display']),
|
239
|
-
'value' => attributes['x-value'],
|
240
|
-
'multiple-line' => attributes['x-multiple'] == 'true',
|
241
|
-
'format' => text_format,
|
242
|
-
'reference-id' => attributes['x-ref-id'],
|
243
|
-
'style' => {
|
244
|
-
'font-family' => [attributes['font-family']],
|
245
|
-
'font-size' => attributes['font-size'].to_f,
|
246
|
-
'color' => attributes['fill'],
|
247
|
-
'font-style' => font_style(attributes),
|
248
|
-
'text-align' => text_align(attributes['text-anchor']),
|
249
|
-
'vertical-align' => vertical_align(attributes['x-valign']),
|
250
|
-
'line-height' => line_height(attributes['x-line-height']),
|
251
|
-
'letter-spacing' => letter_spacing(attributes['kerning']),
|
252
|
-
'overflow' => attributes['x-overflow'],
|
253
|
-
'word-wrap' => attributes['x-word-wrap'] || ''
|
254
|
-
}
|
255
|
-
}
|
256
|
-
end
|
257
|
-
|
258
|
-
def list_item_schema(legacy_element)
|
259
|
-
legacy_schema = legacy_item_schemas[legacy_element.attributes['x-id']]
|
260
|
-
|
261
|
-
header = list_section_schema('header', legacy_element, legacy_schema)
|
262
|
-
detail = list_section_schema('detail', legacy_element, legacy_schema)
|
263
|
-
page_footer = list_section_schema('page-footer', legacy_element, legacy_schema)
|
264
|
-
footer = list_section_schema('footer', legacy_element, legacy_schema)
|
265
|
-
|
266
|
-
schema = {
|
267
|
-
'id' => legacy_schema['id'],
|
268
|
-
'type' => Core::Shape::List::TYPE_NAME,
|
269
|
-
'content-height' => legacy_schema['content-height'].to_f,
|
270
|
-
'auto-page-break' => legacy_schema['page-break'] == 'true',
|
271
|
-
'display' => display(legacy_schema['display']),
|
272
|
-
'header' => header,
|
273
|
-
'detail' => detail,
|
274
|
-
'page-footer' => page_footer,
|
275
|
-
'footer' => footer
|
276
|
-
}
|
277
|
-
|
278
|
-
page_footer['translate']['y'] += detail['height'] if page_footer['enabled']
|
279
|
-
|
280
|
-
if footer['enabled']
|
281
|
-
footer['translate']['y'] += detail['height']
|
282
|
-
footer['translate']['y'] += page_footer['height'] if page_footer['enabled']
|
283
|
-
end
|
284
|
-
schema
|
285
|
-
end
|
286
|
-
|
287
|
-
def list_section_schema(section_name, legacy_list_element, legacy_list_schema)
|
288
|
-
legacy_section_schema = legacy_list_schema[section_name]
|
289
|
-
return {} if legacy_section_schema.empty?
|
290
|
-
|
291
|
-
section_item_elements = legacy_list_element.elements["g[@class='s-list-#{section_name}']"]
|
292
|
-
|
293
|
-
section_schema = {
|
294
|
-
'height' => legacy_section_schema['height'].to_f,
|
295
|
-
'translate' => {
|
296
|
-
'x' => legacy_section_schema['translate']['x'].to_f,
|
297
|
-
'y' => legacy_section_schema['translate']['y'].to_f
|
298
|
-
},
|
299
|
-
'items' => build_item_schemas_from_svg(section_item_elements)
|
300
|
-
}
|
301
|
-
|
302
|
-
unless section_name == 'detail'
|
303
|
-
section_schema['enabled'] = legacy_list_schema["#{section_name}-enabled"] == 'true'
|
304
|
-
end
|
305
|
-
section_schema
|
306
|
-
end
|
307
|
-
|
308
|
-
def extract_texts_from(text_item_element)
|
309
|
-
[].tap do |texts|
|
310
|
-
text_item_element.each_element('text') { |e| texts << e.text }
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
def image_position_y(legacy_position_y)
|
315
|
-
case legacy_position_y
|
316
|
-
when 'top' then 'top'
|
317
|
-
when 'center' then 'middle'
|
318
|
-
when 'bottom' then 'bottom'
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
def display(legacy_display)
|
323
|
-
legacy_display == 'true'
|
324
|
-
end
|
325
|
-
|
326
|
-
def font_style(attributes)
|
327
|
-
style = []
|
328
|
-
style << 'bold' if attributes['font-weight'] == 'bold'
|
329
|
-
style << 'italic' if attributes['font-style'] == 'italic'
|
330
|
-
style << 'underline' if attributes['text-decoration'].include?('underline')
|
331
|
-
style << 'linethrough' if attributes['text-decoration'].include?('line-through')
|
332
|
-
style
|
333
|
-
end
|
334
|
-
|
335
|
-
def text_align(legacy_text_align)
|
336
|
-
case legacy_text_align
|
337
|
-
when 'start' then 'left'
|
338
|
-
when 'middle' then 'center'
|
339
|
-
when 'end' then 'right'
|
340
|
-
else 'left'
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
def vertical_align(legacy_vertical_align)
|
345
|
-
return '' unless legacy_vertical_align
|
346
|
-
|
347
|
-
case legacy_vertical_align
|
348
|
-
when 'top' then 'top'
|
349
|
-
when 'center' then 'middle'
|
350
|
-
when 'bottom' then 'bottom'
|
351
|
-
else 'top'
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
def line_height(legacy_line_height)
|
356
|
-
blank_value?(legacy_line_height) ? '' : legacy_line_height.to_f
|
357
|
-
end
|
358
|
-
|
359
|
-
def letter_spacing(legacy_letter_spacing)
|
360
|
-
case legacy_letter_spacing
|
361
|
-
when 'auto', '' then ''
|
362
|
-
else legacy_letter_spacing.to_f
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
def extract_legacy_item_schemas(svg)
|
367
|
-
items = {}
|
368
|
-
svg.scan(/<!--SHAPE(.*?)SHAPE-->/) do |(item_schema_json)|
|
369
|
-
item_schema = JSON.parse(item_schema_json)
|
370
|
-
items[item_schema['id']] = item_schema
|
371
|
-
end
|
372
|
-
items
|
373
|
-
end
|
374
|
-
|
375
|
-
def cleanup_svg(svg)
|
376
|
-
cleaned_svg = svg.gsub(/<!--SHAPE.*?SHAPE-->/, '')
|
377
|
-
cleaned_svg.gsub(/<!--LAYOUT(.*?)LAYOUT-->/) { $1 }
|
378
|
-
end
|
379
|
-
end
|
380
|
-
end
|
381
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Thinreports
|
4
|
-
module Layout
|
5
|
-
class Version
|
6
|
-
COMPATIBLE_RULES = ['>= 0.8.0', '< 1.0.0'].freeze
|
7
|
-
NEW_SCHEMA_FROM = '0.9.0'
|
8
|
-
|
9
|
-
class << self
|
10
|
-
def compatible_rules
|
11
|
-
COMPATIBLE_RULES
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(schema_version)
|
16
|
-
@schema_version = normalize_version(schema_version)
|
17
|
-
end
|
18
|
-
|
19
|
-
def compatible?
|
20
|
-
self.class.compatible_rules.all? do |rule|
|
21
|
-
op, ver = rule.split(' ')
|
22
|
-
schema_version.send(op.to_sym, normalize_version(ver))
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def legacy?
|
27
|
-
@schema_version < normalize_version(NEW_SCHEMA_FROM)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
attr_reader :schema_version
|
33
|
-
|
34
|
-
def normalize_version(version)
|
35
|
-
Gem::Version.create(version)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,169 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Thinreports
|
4
|
-
module Report
|
5
|
-
class Base
|
6
|
-
extend Forwardable
|
7
|
-
include Utils
|
8
|
-
|
9
|
-
class << self
|
10
|
-
# @param options (see #initialize)
|
11
|
-
# @option options (see #initialize)
|
12
|
-
# @yield [report]
|
13
|
-
# @yieldparam [Thinreports::Report::Base] report
|
14
|
-
# @return [Thinreports::Report::Base]
|
15
|
-
def create(options = {}, &block)
|
16
|
-
raise ArgumentError, '#create requires a block' unless block_given?
|
17
|
-
|
18
|
-
report = new(options)
|
19
|
-
call_block_in(report, &block)
|
20
|
-
report.finalize
|
21
|
-
|
22
|
-
report
|
23
|
-
end
|
24
|
-
|
25
|
-
# @param layout (see #initialize)
|
26
|
-
# @param filename (see #generate)
|
27
|
-
# @param security (see #generate)
|
28
|
-
# @param [Hash] report ({}) DEPRECATED. Options for Report.
|
29
|
-
# @param [Hash] generator ({}) DEPRECATED. Options for Generator.
|
30
|
-
# @yield (see .create)
|
31
|
-
# @yieldparam (see .create)
|
32
|
-
# @return [String]
|
33
|
-
def generate(layout: nil, filename: nil, security: nil, report: {}, generator: {}, &block)
|
34
|
-
raise ArgumentError, '#generate requires a block' unless block_given?
|
35
|
-
|
36
|
-
if report.any? || generator.any?
|
37
|
-
warn '[DEPRECATION] :report and :generator argument has been deprecated. ' \
|
38
|
-
'Use :layout and :filename, :security argument instead.'
|
39
|
-
end
|
40
|
-
|
41
|
-
layout ||= report[:layout]
|
42
|
-
filename ||= generator[:filename]
|
43
|
-
security ||= generator[:security]
|
44
|
-
|
45
|
-
report = create(layout: layout, &block)
|
46
|
-
report.generate(filename: filename, security: security)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [Thinreports::Report::Internal]
|
51
|
-
attr_reader :internal
|
52
|
-
|
53
|
-
# @return [Integer]
|
54
|
-
attr_reader :start_page_number
|
55
|
-
|
56
|
-
# @return [Thinreports::Report::Page]
|
57
|
-
def_delegator :internal, :page
|
58
|
-
|
59
|
-
# @return [Integer]
|
60
|
-
def_delegator :internal, :page_count
|
61
|
-
|
62
|
-
# @return [Array<Thinreports::Report::Page>]
|
63
|
-
def_delegator :internal, :pages
|
64
|
-
|
65
|
-
# @return [Thinreports::Layout::Base]
|
66
|
-
def_delegator :internal, :default_layout
|
67
|
-
|
68
|
-
# @param [Hash] options
|
69
|
-
# @option options [String, nil] :layout (nil)
|
70
|
-
def initialize(options = {})
|
71
|
-
@internal = Report::Internal.new(self, options)
|
72
|
-
@start_page_number = 1
|
73
|
-
end
|
74
|
-
|
75
|
-
# @yield [page]
|
76
|
-
# @yieldparam [Thinreports::Report::Page] page
|
77
|
-
# @example
|
78
|
-
# report.on_page_create do |page|
|
79
|
-
# page.item(:header_title).value = 'Title'
|
80
|
-
# end
|
81
|
-
def on_page_create(&block)
|
82
|
-
internal.page_create_handler = block
|
83
|
-
end
|
84
|
-
|
85
|
-
# @param [Integer] page_number
|
86
|
-
def start_page_number_from(page_number)
|
87
|
-
@start_page_number = page_number
|
88
|
-
end
|
89
|
-
|
90
|
-
# @param [String] layout filename of layout file
|
91
|
-
# @param [Hash] options
|
92
|
-
# @option options [Boolean] :default (true)
|
93
|
-
# @option options [Symbol] :id (nil)
|
94
|
-
# @example
|
95
|
-
# report.use_layout '/path/to/default_layout.tlf' # Default layout
|
96
|
-
# report.use_layout '/path/to/default_layout.tlf', default: true
|
97
|
-
# report.use_layout '/path/to/other_layout', id: :other_layout
|
98
|
-
def use_layout(layout, options = {})
|
99
|
-
internal.register_layout(layout, options)
|
100
|
-
end
|
101
|
-
|
102
|
-
# @example
|
103
|
-
# page = report.start_new_page
|
104
|
-
#
|
105
|
-
# report.start_new_page do |page|
|
106
|
-
# page.item(:text).value = 'value'
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
# report.use_layout 'foo.tlf', default: true
|
110
|
-
# report.use_layout 'bar.tlf', id: :bar
|
111
|
-
#
|
112
|
-
# report.start_new_page # Use 'foo.tlf'
|
113
|
-
# report.start_new_page layout: :bar # Use 'bar.tlf'
|
114
|
-
# report.start_new_page layout: 'boo.tlf' # Use 'boo.tlf'
|
115
|
-
# @param [Hash] options
|
116
|
-
# @option options [String, Symbol] :layout (nil)
|
117
|
-
# @option options [Boolean] :count (true)
|
118
|
-
# @yield [page]
|
119
|
-
# @yieldparam [Thinreports::Report::Page] page
|
120
|
-
# @return [Thinreports::Report::Page]
|
121
|
-
def start_new_page(options = {}, &block)
|
122
|
-
layout = internal.load_layout(options.delete(:layout))
|
123
|
-
|
124
|
-
raise Thinreports::Errors::NoRegisteredLayoutFound unless layout
|
125
|
-
|
126
|
-
page = internal.add_page(Report::Page.new(self, layout, options))
|
127
|
-
call_block_in(page, &block)
|
128
|
-
end
|
129
|
-
|
130
|
-
# @param [Hash] options
|
131
|
-
# @option options [Boolean] :count (true)
|
132
|
-
# @return [Thinreports::Report::BlankPage]
|
133
|
-
def add_blank_page(options = {})
|
134
|
-
internal.add_page(Report::BlankPage.new(options[:count]))
|
135
|
-
end
|
136
|
-
alias blank_page add_blank_page
|
137
|
-
|
138
|
-
# @param [Symbol, nil] id
|
139
|
-
# @return [Thinreports::Layout::Base]
|
140
|
-
def layout(id = nil)
|
141
|
-
if id
|
142
|
-
internal.layout_registry[id] ||
|
143
|
-
raise(Thinreports::Errors::UnknownLayoutId)
|
144
|
-
else
|
145
|
-
internal.default_layout
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# @param [String] filename
|
150
|
-
# @param [Hash] security (see http://prawnpdf.org/api-docs/2.0/Prawn/Document/Security.html#encrypt_document-instance_method)
|
151
|
-
# @return [String]
|
152
|
-
# @example Generate PDF data
|
153
|
-
# report.generate # => "%PDF-1.4...."
|
154
|
-
# @example Create a PDF file
|
155
|
-
# report.generate(filename: 'foo.pdf')
|
156
|
-
def generate(filename: nil, security: nil)
|
157
|
-
Thinreports::Generator::PDF.new(self, security: security).generate(filename)
|
158
|
-
end
|
159
|
-
|
160
|
-
# @see Thinreports::Core::Shape::Manager::Target#list
|
161
|
-
def list(id = nil, &block)
|
162
|
-
start_new_page if page.nil? || page.finalized?
|
163
|
-
page.list(id, &block)
|
164
|
-
end
|
165
|
-
|
166
|
-
def_delegators :internal, :finalize, :finalized?
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|