diagrammatron 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32bd6ca5ad8db808b0b6c921ee0efe5b8e1a6befe4e535636f16ff98a22de139
4
- data.tar.gz: c00027483fc54a9fab024c1e42a4e10e27b797e52e3a9217319a50542926a894
3
+ metadata.gz: 393c2881f870f2371e5af2e9a33fcfac3f82d9c3da69f7f377d87606b7230557
4
+ data.tar.gz: '019f726f35066af4fc209d61a2adbf36de1c6393d0089924912ca6c0e73baef0'
5
5
  SHA512:
6
- metadata.gz: 7723bc76dfd7463a864319421074d8c17357f6c88a309efd81919c165ad836f876d48e062bf618b45e2b7fe779b1c564afaedfa6b105ae1fee9f84e5f52003d5
7
- data.tar.gz: ed23e22fd6476e33afb4360cce23cefb0373dbd2c763611d9f61d0a20a283fe2dcd7a4bac6f137d628020db86819aacdea6387c889e5821a3ed4b958a5a2a736
6
+ metadata.gz: 737105dcbe2c8dc6d636833079d2313be3b5f2c66d86d252127664948365b92f976622b65019e9b5ddd1f7b760f35a15fef9e30fdd749fae99441a31fb03bb8e
7
+ data.tar.gz: c091a6a5f862353afb8f730dbf8b35cf226c5627e6d352f1ad8366ca6d03cb338e61264c22876948806afdc0965f1df0ee81223f07750f61c73a8cd171ab0538
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 Ismo Kärkkäinen
1
+ Copyright (c) 2021-2023 Ismo Kärkkäinen
2
2
 
3
3
  The Universal Permissive License (UPL), Version 1.0
4
4
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021, 2022 Ismo Kärkkäinen
4
+ # Copyright © 2021-2023 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/common'
@@ -443,97 +443,11 @@ def segment_order(a, b)
443
443
  a[0].edge_index <=> b[0].edge_index
444
444
  end
445
445
 
446
- GapState = Struct.new(:order, :cross_count, :lut) do
447
- def fitness(segments, k)
448
- table = lut[k]
449
- crossings = 0
450
- order.each do |n|
451
- crossings += table[n]
452
- end
453
- cross_count + crossings
454
- end
455
- end
456
-
457
- def candidate_compare(a, b)
458
- d = a[1] <=> b[1]
459
- return d unless d == 0
460
- a[0] <=> b[0]
461
- end
462
-
463
- def candidate_order(lut, used)
464
- # Compute crossing sums for all remaining segments among themselves.
465
- cands = []
466
- lut.keys.each do |k|
467
- next if used.include? k
468
- total = 0
469
- lut.each_pair do |idx, v|
470
- total += v[k] unless used.include? idx
471
- end
472
- cands.push([k, total])
473
- end
474
- cands.sort! { |a, b| candidate_compare(a, b) }
475
- cands.map { |a| a[0] }
476
- end
477
-
478
- def depth_first_search(segments, state, best)
479
- if state.order.size == segments.size
480
- $stderr.puts state.order.join(', '), state.cross_count
481
- return GapState.new(state.order.clone, state.cross_count, state.lut)
482
- end
483
- cands = candidate_order(state.lut, state.order)
484
- cands.each do |k|
485
- c = state.fitness(segments, k)
486
- next if (best.nil? ? c + 1 : best.cross_count) <= c
487
- state.order.push(k)
488
- best = depth_first_search(segments, GapState.new(state.order, c, state.lut), best)
489
- state.order.pop
490
- end
491
- best
492
- end
493
-
494
446
  def zigzag_order(from_right_up_to_left, from_left_up_to_right)
495
- # Interleave the two sets.
447
+ # Eventually interleave the two sets, if it makes sense.
496
448
  out = []
497
449
  from_right_up_to_left.each { |x| out.push x }
498
450
  from_left_up_to_right.each { |x| out.push x }
499
- return out
500
- return segments if segments.size < 2
501
- # DFS. Fitness is how many end segments cross the placed segments.
502
- # Sort so that those that cross least when at start are first and vice versa.
503
- lut = {}
504
- segments.each_index do |k|
505
- crossings = Hash.new(0)
506
- lut[k] = crossings
507
- s = segments[k]
508
- prev = (s[1] == 1) ? s[2].range.max : s[2].range.min
509
- segments.each_index do |n|
510
- next if k == n
511
- other = segments[n]
512
- if other[2].range.min <= prev && prev <= other[2].range.max
513
- crossings[n] = crossings[n] + 1
514
- end
515
- v = (other[1] == 1) ? other[2].range.min : other[2].range.max
516
- if s[2].range.min <= v && v <= s[2].range.max
517
- crossings[n] = crossings[n] + 1
518
- end
519
- end
520
- end
521
- $stderr.puts segments.size, lut
522
- # Could take all crossings for k, sort, sum up to get minimum fitness for
523
- # used set size N ignoring what set has. Since real fitness can not be
524
- # lower, once minimal sum + cross_count exceeds best, we can not use that
525
- # segment in any later position and can cut off search.
526
- # Add to GapState after lut.
527
- # Also, coult set time budget for single search and terminate search.
528
- best = nil
529
- cands = candidate_order(lut, [])
530
- cands.each do |k|
531
- best = depth_first_search(segments, GapState.new([ k ], 0, lut), best)
532
- end
533
- out = []
534
- best.order.each do |k|
535
- out.push segments[k]
536
- end
537
451
  out
538
452
  end
539
453
 
@@ -717,10 +631,17 @@ def place_edges(work)
717
631
  end
718
632
  gaps.each_value do |direction|
719
633
  direction.each_value do |gap|
720
- gap.sort! { |a, b| segment_order(a, b) }
634
+ #gap.sort! { |a, b| segment_order(a, b) }
721
635
  gleft = gap.select { |a| a[1].zero? }
636
+ gleft.sort! { |a, b| segment_order(a, b) }
722
637
  gright = gap.select { |a| a[1] == 3 }
723
- gmiddle = zigzag_order(gap.select() { |a| a[1] == 1 }, gap.select() { |a| a[1] == 2 })
638
+ gright.sort! { |a, b| segment_order(a, b) }
639
+ gright.reverse!
640
+ grul = gap.select() { |a| a[1] == 1 }
641
+ grul.sort! { |a, b| segment_order(a, b) }
642
+ glur = gap.select() { |a| a[1] == 2 }
643
+ glur.sort! { |a, b| segment_order(a, b) }
644
+ gmiddle = zigzag_order(grul, glur)
724
645
  gmiddle.each do |s|
725
646
  s[1] = 1
726
647
  end
@@ -735,7 +656,7 @@ def place_edges(work)
735
656
  denominator = 1 + c[0]
736
657
  (1...c.size).each do |k|
737
658
  denominator += c[k]
738
- before[k] = c[k - 1] + before[k - 1]
659
+ before.push(c[k - 1] + before.last)
739
660
  end
740
661
  gap.each do |sg|
741
662
  sg[0].offset = c[sg[1]] + 1 - sg[0].offset if sg[1] > 1
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021, 2022 Ismo Kärkkäinen
4
+ # Copyright © 2021-2023 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/common'
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021, 2022 Ismo Kärkkäinen
4
+ # Copyright © 2021-2023 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/common'
@@ -78,8 +78,12 @@ end
78
78
 
79
79
  class Styles
80
80
  def base_styles(m, styles, group)
81
- d = styles.dig(group, 'default') || {}
82
- m['default'] = m.fetch('default', {}).merge(d)
81
+ d = styles.dig(group, 'default')
82
+ if d.nil?
83
+ d = m.fetch('default', {}) if d.nil?
84
+ else
85
+ m['default'] = m.fetch('default', {}).merge(d)
86
+ end
83
87
  styles.fetch(group, {}).each_pair do |name, values|
84
88
  s = d.clone
85
89
  s.merge!(values) unless name == 'default'
@@ -98,13 +102,16 @@ class Styles
98
102
  styles = item.fetch('style', [ 'default' ])
99
103
  styles = [ styles ] unless styles.is_a?(Array)
100
104
  s = {}
105
+ found = false
101
106
  styles.each do |name|
102
107
  ns = mapping.fetch(name, nil)
103
- raise "No such #{type_name} style: #{name} in #{mapping.keys.join(', ')}" if ns.nil?
108
+ next if ns.nil?
109
+ found = true
104
110
  s.merge! ns
105
111
  end
112
+ s.merge!(mapping['default']) unless found # Merge default at least.
106
113
  # Keep values specified explicitly.
107
- item.merge!(s) {|key, existing, from_template| existing }
114
+ item.merge!(s) { |key, existing, from_template| existing || from_template }
108
115
  end
109
116
 
110
117
  def apply_node_styles(node)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021, 2022 Ismo Kärkkäinen
4
+ # Copyright © 2021-2023 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
7
  require_relative '../lib/common'
@@ -21,11 +21,15 @@ def add_field(doc, field_name, content)
21
21
  end
22
22
 
23
23
  def missing(doc)
24
- %w[template].each do |key|
24
+ %w[template styles].each do |key|
25
25
  next if doc.key? key
26
26
  next if doc.key? "base64#{key}"
27
27
  return aargh("#{key} is missing", 4)
28
28
  end
29
+ %w[node edge diagram].each do |key|
30
+ v = doc.dig('styles', key, 'default')
31
+ return aargh("styles #{key} default is missing", 4) if v.nil?
32
+ end
29
33
  nil
30
34
  end
31
35
 
@@ -50,15 +54,24 @@ def main
50
54
  Pairs all parameter field-names with content-files contents, starting with
51
55
  either given root YAML file or with an empty root.
52
56
 
53
- Any field name either in root document or in parameters is trusted to be
54
- base-64 encoded without further checking.
55
-
56
57
  Outputs a YAML-file that case be used with diagrammatron-render as a template.
57
58
  All fields are base64-encoded for safety. diagrammatron-render will decode
58
59
  them and rename the fields by removing the base64 prefix.
59
60
 
60
- Presence of "defaults", "sizes", and "template" fields is checked for.
61
+ Root document is expected to have at least the following:
62
+ styles:
63
+ node:
64
+ defaults: {}
65
+ edge:
66
+ defaults: {}
67
+ diagram:
68
+ defaults: {}
69
+
70
+ Presence of "template" field is checked for.
61
71
  Extra fields are not restricted in any manner.
72
+
73
+ Any field name in parameters starting with "base64" is trusted to be base-64
74
+ encoded without further checking.
62
75
  )
63
76
  exit 0
64
77
  end
@@ -29,4 +29,4 @@ styles:
29
29
  default:
30
30
  stroke_width: 2
31
31
  stroke: "#000000"
32
- base64template: PD94bWwgdmVyc2lvbj0iMS4wIj8+CjwlPQp3LCBoaCA9ICRyZW5kZXIuZGltZW5zaW9ucwpoaCArPSAkcmVuZGVyLmRvYy5kaWcoJ2RpYWdyYW0nLCAnaGVpZ2h0X21hcmdpbicpCgpvdXQgPSBbCiAgJSg8c3ZnIHdpZHRoPSIje3cgKyAkcmVuZGVyLmRvYy5kaWcoJ2RpYWdyYW0nLCAnd2lkdGhfbWFyZ2luJyl9IiBoZWlnaHQ9IiN7aGh9IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiPikKXQokcmVuZGVyLmRvYy5mZXRjaCgnbm9kZXMnLCBbXSkuZWFjaCBkbyB8bm9kZXwKICB3ID0gbm9kZVsndyddLnRvX2kKICBoID0gbm9kZVsnaCddLnRvX2kKICB4ID0gbm9kZVsneG8nXS50b19pCiAgeSA9IGhoIC0gbm9kZVsneW8nXS50b19pIC0gaAogIG5vZGVzdHlsZSA9ICUoZmlsbD0iI3tub2RlWydmaWxsJ119IiBzdHJva2U9IiN7bm9kZVsnc3Ryb2tlJ119IiBzdHJva2Utd2lkdGg9IiN7bm9kZVsnc3Ryb2tlX3dpZHRoJ119IikKICBvdXQucHVzaCglKDxyZWN0ICN7bm9kZXN0eWxlfSBoZWlnaHQ9IiN7aH0iIHdpZHRoPSIje3d9IiB4PSIje3h9IiB5PSIje3l9Ii8+KSkKICB4ICs9IG5vZGVbJ3dpZHRoX21hcmdpbiddCiAgZnMgPSBub2RlWydmb250X3NpemUnXQogIGxoID0gZnMgKiAoMSArIG5vZGVbJ2ZvbnRfbGluZV9zcGFjaW5nJ10pCiAgeSArPSBub2RlWydoZWlnaHRfbWFyZ2luJ10gKyBmcyAqIG5vZGVbJ2ZvbnRfYXNjZW5kJ10gIyBCYXNlbGluZSBmb3IgZmlyc3QgbGluZS4KICB1cmwgPSBub2RlLmZldGNoKCd1cmwnLCBuaWwpCiAgdXJsLmVuY29kZSEoOnhtbCA9PiA6YXR0cikgdW5sZXNzIHVybC5uaWw/CiAgeTAgPSB5CiAgdGV4dHN0eWxlID0gJShmaWxsPSIje25vZGVbJ2ZvbnRfZmlsbCddfSIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IiN7ZnN9IiBzdHJva2U9IiN7bm9kZVsnZm9udF9maWxsJ119IiBzdHJva2Utd2lkdGg9IjAiIHhtbDpzcGFjZT0icHJlc2VydmUiKQogIGxpbmtzdHlsZSA9ICUoZmlsbD0iI3tub2RlWyd1cmxfZmlsbCddfSIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IiN7ZnN9IiBzdHJva2U9IiN7bm9kZVsndXJsX2ZpbGwnXX0iIHN0cm9rZS13aWR0aD0iMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIpCiAgbm9kZVsndGV4dCddLmVhY2ggZG8gfGxpbmV8CiAgICBsaW5lLmVuY29kZSEoOnhtbCA9PiA6dGV4dCkKICAgIGlmIHVybC5uaWw/CiAgICAgIG91dC5wdXNoKCUoPHRleHQgI3t0ZXh0c3R5bGV9IHg9IiN7eH0iIHk9IiN7eTB9Ij4je2xpbmV9PC90ZXh0PikpCiAgICBlbHNlCiAgICAgIG91dC5wdXNoKCUoPGEgeGxpbms6aHJlZj0je3VybH0gdGFyZ2V0PSJfcGFyZW50Ij48dGV4dCAje2xpbmtzdHlsZX0geD0iI3t4fSIgeT0iI3t5MH0iPiN7bGluZX08L3RleHQ+PC9hPikpCiAgICBlbmQKICAgIHkwICs9IGxoICMgU2hpZnQgYmFzZWxpbmUgYnkgZnVsbCBsaW5lICsgc3BhY2luZyBoZWlnaHQuCiAgZW5kCmVuZAokcmVuZGVyLmRvYy5mZXRjaCgnZWRnZXMnLCBbXSkuZWFjaCBkbyB8ZWRnZXwKICBsaW5lc3R5bGUgPSAlKGZpbGw9Im5vbmUiIHN0cm9rZT0iI3tlZGdlWydzdHJva2UnXX0iIHN0cm9rZS13aWR0aD0iI3tlZGdlWydzdHJva2Vfd2lkdGgnXX0iKQogIHBhdGggPSBlZGdlLmZldGNoKCdwYXRoJywgbmlsKQogIG5leHQgaWYgcGF0aC5uaWw/CiAgcGF0aC5lYWNoIGRvIHxwfAogICAgcFsneG8nXSA9IHBbJ3hvJ10udG9faS50b19zCiAgICBwWyd5byddID0gKGhoIC0gcFsneW8nXSkudG9faS50b19zCiAgZW5kCiAgaWYgcGF0aC5zaXplID09IDIKICAgIG91dC5wdXNoKCUoPGxpbmUgI3tsaW5lc3R5bGV9IHgxPSIje3BhdGhbMF1bJ3hvJ119IiB4Mj0iI3twYXRoWzFdWyd4byddfSIgeTE9IiN7cGF0aFswXVsneW8nXX0iIHkyPSIje3BhdGhbMV1bJ3lvJ119Ii8+KSkKICBlbHNlCiAgICBwdHMgPSBwYXRoLm1hcCB7IHxwfCAiI3twWyd4byddfSwje3BbJ3lvJ119IiB9CiAgICBvdXQucHVzaCglKDxwb2x5bGluZSAje2xpbmVzdHlsZX0gcG9pbnRzPSIje3B0cy5qb2luKCcgJyl9Ii8+KSkKICBlbmQKZW5kCm91dC5qb2luKCJcbiIpCiU+Cjwvc3ZnPgo=
32
+ base64template: PD94bWwgdmVyc2lvbj0iMS4wIj8+CjwlPQp3LCBoaCA9ICRyZW5kZXIuZGltZW5zaW9ucwpoaCArPSAkcmVuZGVyLmRvYy5kaWcoJ2RpYWdyYW0nLCAnaGVpZ2h0X21hcmdpbicpCgpvdXQgPSBbCiAgJSg8c3ZnIHdpZHRoPSIje3cgKyAkcmVuZGVyLmRvYy5kaWcoJ2RpYWdyYW0nLCAnd2lkdGhfbWFyZ2luJyl9IiBoZWlnaHQ9IiN7aGh9IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiPikKXQokcmVuZGVyLmRvYy5mZXRjaCgnZWRnZXMnLCBbXSkuZWFjaCBkbyB8ZWRnZXwKICBsaW5lc3R5bGUgPSAlKGZpbGw9Im5vbmUiIHN0cm9rZT0iI3tlZGdlWydzdHJva2UnXX0iIHN0cm9rZS13aWR0aD0iI3tlZGdlWydzdHJva2Vfd2lkdGgnXX0iKQogIHBhdGggPSBlZGdlLmZldGNoKCdwYXRoJywgbmlsKQogIG5leHQgaWYgcGF0aC5uaWw/CiAgcGF0aC5lYWNoIGRvIHxwfAogICAgcFsneG8nXSA9IHBbJ3hvJ10udG9faS50b19zCiAgICBwWyd5byddID0gKGhoIC0gcFsneW8nXSkudG9faS50b19zCiAgZW5kCiAgaWYgcGF0aC5zaXplID09IDIKICAgIG91dC5wdXNoKCUoPGxpbmUgI3tsaW5lc3R5bGV9IHgxPSIje3BhdGhbMF1bJ3hvJ119IiB4Mj0iI3twYXRoWzFdWyd4byddfSIgeTE9IiN7cGF0aFswXVsneW8nXX0iIHkyPSIje3BhdGhbMV1bJ3lvJ119Ii8+KSkKICBlbHNlCiAgICBwdHMgPSBwYXRoLm1hcCB7IHxwfCAiI3twWyd4byddfSwje3BbJ3lvJ119IiB9CiAgICBvdXQucHVzaCglKDxwb2x5bGluZSAje2xpbmVzdHlsZX0gcG9pbnRzPSIje3B0cy5qb2luKCcgJyl9Ii8+KSkKICBlbmQKZW5kCiRyZW5kZXIuZG9jLmZldGNoKCdub2RlcycsIFtdKS5lYWNoIGRvIHxub2RlfAogIHcgPSBub2RlWyd3J10udG9faQogIGggPSBub2RlWydoJ10udG9faQogIHggPSBub2RlWyd4byddLnRvX2kKICB5ID0gaGggLSBub2RlWyd5byddLnRvX2kgLSBoCiAgbm9kZXN0eWxlID0gJShmaWxsPSIje25vZGVbJ2ZpbGwnXX0iIHN0cm9rZT0iI3tub2RlWydzdHJva2UnXX0iIHN0cm9rZS13aWR0aD0iI3tub2RlWydzdHJva2Vfd2lkdGgnXX0iKQogIG91dC5wdXNoKCUoPHJlY3QgI3tub2Rlc3R5bGV9IGhlaWdodD0iI3tofSIgd2lkdGg9IiN7d30iIHg9IiN7eH0iIHk9IiN7eX0iLz4pKQogIHggKz0gbm9kZVsnd2lkdGhfbWFyZ2luJ10KICBmcyA9IG5vZGVbJ2ZvbnRfc2l6ZSddCiAgbGggPSBmcyAqICgxICsgbm9kZVsnZm9udF9saW5lX3NwYWNpbmcnXSkKICB5ICs9IG5vZGVbJ2hlaWdodF9tYXJnaW4nXSArIGZzICogbm9kZVsnZm9udF9hc2NlbmQnXSAjIEJhc2VsaW5lIGZvciBmaXJzdCBsaW5lLgogIHVybCA9IG5vZGUuZmV0Y2goJ3VybCcsIG5pbCkKICB1cmwuZW5jb2RlISg6eG1sID0+IDphdHRyKSB1bmxlc3MgdXJsLm5pbD8KICB5MCA9IHkKICB0ZXh0c3R5bGUgPSAlKGZpbGw9IiN7bm9kZVsnZm9udF9maWxsJ119IiBmb250LWZhbWlseT0ic2VyaWYiIGZvbnQtc2l6ZT0iI3tmc30iIHN0cm9rZT0iI3tub2RlWydmb250X2ZpbGwnXX0iIHN0cm9rZS13aWR0aD0iMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIpCiAgbGlua3N0eWxlID0gJShmaWxsPSIje25vZGVbJ3VybF9maWxsJ119IiBmb250LWZhbWlseT0ic2VyaWYiIGZvbnQtc2l6ZT0iI3tmc30iIHN0cm9rZT0iI3tub2RlWyd1cmxfZmlsbCddfSIgc3Ryb2tlLXdpZHRoPSIwIiB4bWw6c3BhY2U9InByZXNlcnZlIikKICBub2RlWyd0ZXh0J10uZWFjaCBkbyB8bGluZXwKICAgIGxpbmUuZW5jb2RlISg6eG1sID0+IDp0ZXh0KQogICAgaWYgdXJsLm5pbD8KICAgICAgb3V0LnB1c2goJSg8dGV4dCAje3RleHRzdHlsZX0geD0iI3t4fSIgeT0iI3t5MH0iPiN7bGluZX08L3RleHQ+KSkKICAgIGVsc2UKICAgICAgb3V0LnB1c2goJSg8YSB4bGluazpocmVmPSN7dXJsfSB0YXJnZXQ9Il9wYXJlbnQiPjx0ZXh0ICN7bGlua3N0eWxlfSB4PSIje3h9IiB5PSIje3kwfSI+I3tsaW5lfTwvdGV4dD48L2E+KSkKICAgIGVuZAogICAgeTAgKz0gbGggIyBTaGlmdCBiYXNlbGluZSBieSBmdWxsIGxpbmUgKyBzcGFjaW5nIGhlaWdodC4KICBlbmQKZW5kCm91dC5qb2luKCJcbiIpCiU+Cjwvc3ZnPgo=
data/template/svg_1.1.erb CHANGED
@@ -6,6 +6,21 @@ hh += $render.doc.dig('diagram', 'height_margin')
6
6
  out = [
7
7
  %(<svg width="#{w + $render.doc.dig('diagram', 'width_margin')}" height="#{hh}" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">)
8
8
  ]
9
+ $render.doc.fetch('edges', []).each do |edge|
10
+ linestyle = %(fill="none" stroke="#{edge['stroke']}" stroke-width="#{edge['stroke_width']}")
11
+ path = edge.fetch('path', nil)
12
+ next if path.nil?
13
+ path.each do |p|
14
+ p['xo'] = p['xo'].to_i.to_s
15
+ p['yo'] = (hh - p['yo']).to_i.to_s
16
+ end
17
+ if path.size == 2
18
+ out.push(%(<line #{linestyle} x1="#{path[0]['xo']}" x2="#{path[1]['xo']}" y1="#{path[0]['yo']}" y2="#{path[1]['yo']}"/>))
19
+ else
20
+ pts = path.map { |p| "#{p['xo']},#{p['yo']}" }
21
+ out.push(%(<polyline #{linestyle} points="#{pts.join(' ')}"/>))
22
+ end
23
+ end
9
24
  $render.doc.fetch('nodes', []).each do |node|
10
25
  w = node['w'].to_i
11
26
  h = node['h'].to_i
@@ -32,21 +47,6 @@ $render.doc.fetch('nodes', []).each do |node|
32
47
  y0 += lh # Shift baseline by full line + spacing height.
33
48
  end
34
49
  end
35
- $render.doc.fetch('edges', []).each do |edge|
36
- linestyle = %(fill="none" stroke="#{edge['stroke']}" stroke-width="#{edge['stroke_width']}")
37
- path = edge.fetch('path', nil)
38
- next if path.nil?
39
- path.each do |p|
40
- p['xo'] = p['xo'].to_i.to_s
41
- p['yo'] = (hh - p['yo']).to_i.to_s
42
- end
43
- if path.size == 2
44
- out.push(%(<line #{linestyle} x1="#{path[0]['xo']}" x2="#{path[1]['xo']}" y1="#{path[0]['yo']}" y2="#{path[1]['yo']}"/>))
45
- else
46
- pts = path.map { |p| "#{p['xo']},#{p['yo']}" }
47
- out.push(%(<polyline #{linestyle} points="#{pts.join(' ')}"/>))
48
- end
49
- end
50
50
  out.join("\n")
51
51
  %>
52
52
  </svg>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diagrammatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismo Kärkkäinen