japanese-bookkeeping-svg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5c43657e693b2aaac4e582951f79a2fbfba17a12
4
+ data.tar.gz: ee57cdc74902eae050f8e17c81c0849383cd4473
5
+ SHA512:
6
+ metadata.gz: 6fcd45ddddde80a059aa62b2cce20f9c37a858fcf2f529e386b0b53261df0fd0f1c81359ebd78cdee78aa0dcd9cd492a04e53051f104de3043f9862d0b9238dc
7
+ data.tar.gz: cba1e8454b67643459862c6d4ba06d0151293604717e5500ffec1db8966ba237664d3f154a05fadc47dbc7a8159c50148f2c4bb962deeb255be23e71b001c9b1
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*.rb]
4
+ charset = utf-8
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ indent_style = space
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
@@ -0,0 +1,17 @@
1
+ # Editor
2
+ *~
3
+ .*.sw[a-z]
4
+
5
+ # Windows
6
+ Thumbs.db
7
+
8
+ # Mac OS X
9
+ .DS_Store
10
+
11
+ # Ruby
12
+ Gemfile.lock
13
+ .ruby-version
14
+ .rbenv-gemsets
15
+ .bundle
16
+ coverage/
17
+ pkg/
@@ -0,0 +1,8 @@
1
+ inherit_from:
2
+ - .rubocop_todo.yml
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
6
+
7
+ Style/BracesAroundHashParameters:
8
+ EnforcedStyle: context_dependent
@@ -0,0 +1,2 @@
1
+ Documentation:
2
+ Enabled: false
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ before_install: gem install bundler
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in japanese-bookkeeping-svg.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Tasuku SUENAGA a.k.a. gunyarakun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # japanese-bookkeeping-svg
2
+
3
+ Generate SVG files for Japanese style bookkeeping diagrams.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ gem install japanese-bookkeeping-svg
9
+ ```
10
+
11
+ 仕訳
12
+
13
+ ```ruby
14
+ require 'japanese-bookkeeping-svg'
15
+
16
+ File.open('journal.svg', 'w') do |file|
17
+ file.write JapaneseBookkeepingSVG.journalization(
18
+ debits={
19
+ 現金預金: 4000
20
+ },
21
+ credits={
22
+ 売上: 2000,
23
+ 売掛金: 2000
24
+ }
25
+ ).to_s
26
+ end
27
+ ```
28
+
29
+ T字勘定
30
+
31
+ ```ruby
32
+ require 'japanese-bookkeeping-svg'
33
+
34
+ File.open('t-accounts.svg', 'w') do |file|
35
+ file.write JapaneseBookkeepingSVG.t_accounts(
36
+ '現金預金',
37
+ debits={
38
+ 資本金: 10000
39
+ }
40
+ credits={
41
+ 仕入: 2000,
42
+ 普通預金: 1234,
43
+ 諸口: 3456,
44
+ 次月繰越: 3310
45
+ },
46
+ ).to_s
47
+ end
48
+ ```
49
+
50
+ ## License
51
+
52
+ ``japanese-bookkeeping-svg`` is distributed under the terms of the MIT license (see LICENSE.txt).
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task default: :test
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'japanese_bookkeeping_svg/gem_version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'japanese-bookkeeping-svg'
8
+ spec.version = JapaneseBookkeepingSVG::VERSION
9
+ spec.authors = ['Tasuku SUENAGA a.k.a. gunyarakun']
10
+ spec.email = ['tasuku-s-github@titech.ac']
11
+
12
+ spec.summary = 'Generate SVG images for Japanese bookkeeping'
13
+ spec.description = %(
14
+ A pure Ruby library to generate SVG images for Japanese bookkeeping.
15
+ ).strip.gsub(/\s+/, ' ')
16
+ spec.homepage = 'https://github.com/gunyarakun/japanese-bookkeeping-svg'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^test/})
21
+ end
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.11'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'minitest', '~> 5.0'
27
+ spec.add_development_dependency 'simplecov', '~> 0.11'
28
+ spec.add_development_dependency 'rubocop', '~> 0.40'
29
+ end
@@ -0,0 +1,98 @@
1
+ require_relative 'japanese_bookkeeping_svg/svg_generator'
2
+ require_relative 'japanese_bookkeeping_svg/gem_version'
3
+
4
+ module JapaneseBookkeepingSVG
5
+ @@line_height = SVGGenerator.convert_unit('1em') # rubocop:disable Style/ClassVars
6
+
7
+ def self.line_height
8
+ @@line_height
9
+ end
10
+
11
+ def self.value_style
12
+ {
13
+ 'text-anchor' => 'end'
14
+ }
15
+ end
16
+
17
+ def self.account_value(svg, x, y, journals, with_brackets) # rubocop:disable Metrics/MethodLength
18
+ key_style = {
19
+ 'textLength' => 125,
20
+ # 'xml:space' => 'preserve'
21
+ }
22
+ sum_value = 0
23
+ journals.map do |key, value|
24
+ y += line_height
25
+ svg.text(x, y, '(') if with_brackets
26
+ svg.text(x + 15, y, key.to_s, key_style)
27
+ svg.text(x + 150, y, ')') if with_brackets
28
+ svg.text(x + 290, y, delimited_number(value).to_s, value_style)
29
+ sum_value += value
30
+ end
31
+
32
+ [y, sum_value]
33
+ end
34
+
35
+ def self.journalization(debits, credits)
36
+ # TODO: check amount
37
+ SVGGenerator.new do
38
+ JapaneseBookkeepingSVG.account_value(self, 0, 0, debits, true)
39
+ JapaneseBookkeepingSVG.account_value(self, 300, 0, credits, true)
40
+ end
41
+ end
42
+
43
+ def self.t_accounts(account, debits, credits) # rubocop:disable Metrics/LineLength,Metrics/MethodLength,Metrics/AbcSize
44
+ # TODO: calc amount
45
+ line_height = SVGGenerator.convert_unit('1em')
46
+ SVGGenerator.new do
47
+ account_style = {
48
+ 'textLength' => 145,
49
+ 'text-anchor' => 'middle'
50
+ }
51
+ line_style = {
52
+ 'stroke' => 'black',
53
+ 'stroke-width' => 1
54
+ }
55
+
56
+ text(300, line_height, account, account_style)
57
+ t_start_y = line_height + 8
58
+ line(0, t_start_y, 600, t_start_y, line_style)
59
+
60
+ y = t_start_y + 5
61
+ debits_y, sum_debits = JapaneseBookkeepingSVG.account_value(self, 0, y, debits, false)
62
+ credits_y, sum_credits = JapaneseBookkeepingSVG.account_value(self, 300, y, credits, false)
63
+
64
+ if debits_y < credits_y
65
+ y = credits_y + 8
66
+ line(15, y, 140, debits_y + 8, line_style)
67
+ line(15, y, 300, y, line_style)
68
+ line(460, y, 600, y, line_style)
69
+ elsif debits_y > credits_y
70
+ y = debits_y + 8
71
+ line(160, y, 300, y, line_style)
72
+ line(315, y, 440, credits_y + 8, line_style)
73
+ line(315, y, 600, y, line_style)
74
+ else # eq
75
+ y = debits_y + 8
76
+ line(160, y, 300, y, line_style)
77
+ line(460, y, 600, y, line_style)
78
+ end
79
+
80
+ y += line_height + 3
81
+ text(290, y, JapaneseBookkeepingSVG.delimited_number(sum_debits).to_s, JapaneseBookkeepingSVG.value_style)
82
+ text(590, y, JapaneseBookkeepingSVG.delimited_number(sum_credits).to_s, JapaneseBookkeepingSVG.value_style)
83
+
84
+ y += 8
85
+ line(160, y, 300, y, line_style)
86
+ line(460, y, 600, y, line_style)
87
+ y += 3
88
+ line(160, y, 300, y, line_style)
89
+ line(460, y, 600, y, line_style)
90
+
91
+ line(300, t_start_y, 300, y, line_style)
92
+ end
93
+ end
94
+
95
+ def self.delimited_number(number)
96
+ number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, '\\1,')
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ module JapaneseBookkeepingSVG
2
+ VERSION = '0.0.1'.freeze unless defined? JapaneseBookkeepingSVG::Version
3
+ end
@@ -0,0 +1,117 @@
1
+ module JapaneseBookkeepingSVG
2
+ class SVGGenerator
3
+ def initialize(&block)
4
+ @output = []
5
+ @max_width = 0
6
+ @max_height = 0
7
+
8
+ return unless block
9
+ instance_exec(&block)
10
+ close
11
+ end
12
+
13
+ def close(width = @max_width, height = @max_height)
14
+ unshift_header(width, height)
15
+ push_footer
16
+ end
17
+
18
+ def to_s
19
+ @output.join("\n")
20
+ end
21
+
22
+ def line(x1, y1, x2, y2, style = {})
23
+ s = style.clone
24
+ attrs = ['stroke', 'stroke-width'].map do |attr|
25
+ if s.key?(attr)
26
+ %( #{attr}="#{s.delete attr}")
27
+ else
28
+ ''
29
+ end
30
+ end.join('')
31
+ @output << %(<line x1="#{x1}" y1="#{y1}" x2="#{x2}" y2="#{y2}"#{attrs}#{style_attr(s)} />)
32
+ update_max_width_and_height(x2, y2)
33
+ end
34
+
35
+ def text(x, y, text, style = {}) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
36
+ s = style.clone
37
+ max_width = self.class.convert_unit(s['textLength'])
38
+ attrs = ['font-family', 'font-size', 'text-anchor', 'textLength', 'xml:space'].map do |attr|
39
+ if s.key?(attr)
40
+ %( #{attr}="#{s.delete attr}")
41
+ else
42
+ ''
43
+ end
44
+ end.join('')
45
+
46
+ text_lines = []
47
+ text_lines << %(<text x="#{x}" y="#{y}"#{attrs}#{style_attr(s)}>)
48
+ max_width_em = 0
49
+ height_em = 0
50
+ dy = 0
51
+ text.each_line do |line|
52
+ line.chomp!
53
+ text_lines << %(<tspan x="#{x}" dy="#{dy}em">#{line}</tspan>)
54
+ dy = 1
55
+ max_width_em = line.size if line.size > max_width_em
56
+ height_em += 1
57
+ end
58
+ text_lines << '</text>'
59
+ @output << text_lines.join('')
60
+
61
+ max_width ||= self.class.convert_unit("#{max_width_em}em")
62
+ max_x = x + max_width
63
+ max_y = y + self.class.convert_unit("#{height_em}em")
64
+ update_max_width_and_height(max_x, max_y)
65
+ end
66
+
67
+ def self.convert_unit(length) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
68
+ return nil if length.nil?
69
+ m = /\A(\d+)(em|ex|px|in|cm|mm|pt|pc)?\z/.match(length.to_s)
70
+ raise ArgumentError, "Unknown length #{length}" unless m
71
+ v = m[1].to_i
72
+ return v if m[2].nil?
73
+ case m[2].intern
74
+ when :em, :ex
75
+ v * 16
76
+ when :px
77
+ v
78
+ when :in
79
+ v * 96
80
+ when :cm
81
+ (v * 96) / 2.54
82
+ when :mm
83
+ (v * 96) / 25.4
84
+ when :pt
85
+ (v * 4).fdiv(3)
86
+ when :pc
87
+ v * 16
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def update_max_width_and_height(width, height)
94
+ @max_width = [width, @max_width].max
95
+ @max_height = [height, @max_height].max
96
+ end
97
+
98
+ def style_attr(style)
99
+ return '' if style.empty?
100
+ ' style="' + style.map do |key, value|
101
+ "#{key}:#{value}"
102
+ end.join(' ') + '"'
103
+ end
104
+
105
+ def unshift_header(width, height)
106
+ @output.unshift(<<EOT.chomp)
107
+ <?xml version="1.0" standalone="no"?>
108
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
109
+ <svg width="#{width}" height="#{height}" version="1.1" xmlns="http://www.w3.org/2000/svg">
110
+ EOT
111
+ end
112
+
113
+ def push_footer
114
+ @output << '</svg>'
115
+ end
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: japanese-bookkeeping-svg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tasuku SUENAGA a.k.a. gunyarakun
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.40'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.40'
83
+ description: A pure Ruby library to generate SVG images for Japanese bookkeeping.
84
+ email:
85
+ - tasuku-s-github@titech.ac
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".editorconfig"
91
+ - ".gitignore"
92
+ - ".rubocop.yml"
93
+ - ".rubocop_todo.yml"
94
+ - ".travis.yml"
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - japanese-bookkeeping-svg.gemspec
100
+ - lib/japanese-bookkeeping-svg.rb
101
+ - lib/japanese_bookkeeping_svg/gem_version.rb
102
+ - lib/japanese_bookkeeping_svg/svg_generator.rb
103
+ homepage: https://github.com/gunyarakun/japanese-bookkeeping-svg
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.5.1
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Generate SVG images for Japanese bookkeeping
127
+ test_files: []