rsyntaxtree 1.1.4 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.tags +602 -51
  4. data/docs/_examples/000.md +4 -4
  5. data/docs/_examples/010.md +0 -1
  6. data/docs/_examples/029.md +56 -0
  7. data/docs/_examples/030.md +33 -0
  8. data/docs/_examples/031.md +20 -0
  9. data/docs/_examples/032.md +27 -0
  10. data/docs/_examples/033.md +26 -0
  11. data/docs/_examples/034.md +26 -0
  12. data/docs/_examples/035.md +34 -0
  13. data/docs/assets/img/000.png +0 -0
  14. data/docs/assets/img/001.png +0 -0
  15. data/docs/assets/img/002.png +0 -0
  16. data/docs/assets/img/003.png +0 -0
  17. data/docs/assets/img/004.png +0 -0
  18. data/docs/assets/img/005.png +0 -0
  19. data/docs/assets/img/006.png +0 -0
  20. data/docs/assets/img/007.png +0 -0
  21. data/docs/assets/img/008.png +0 -0
  22. data/docs/assets/img/009.png +0 -0
  23. data/docs/assets/img/010.png +0 -0
  24. data/docs/assets/img/011.png +0 -0
  25. data/docs/assets/img/012.png +0 -0
  26. data/docs/assets/img/013.png +0 -0
  27. data/docs/assets/img/014.png +0 -0
  28. data/docs/assets/img/015.png +0 -0
  29. data/docs/assets/img/016.png +0 -0
  30. data/docs/assets/img/017.png +0 -0
  31. data/docs/assets/img/018.png +0 -0
  32. data/docs/assets/img/020.png +0 -0
  33. data/docs/assets/img/021.png +0 -0
  34. data/docs/assets/img/023.png +0 -0
  35. data/docs/assets/img/024.png +0 -0
  36. data/docs/assets/img/025.png +0 -0
  37. data/docs/assets/img/026.png +0 -0
  38. data/docs/assets/img/027.png +0 -0
  39. data/docs/assets/img/028.png +0 -0
  40. data/docs/assets/img/029.png +0 -0
  41. data/docs/assets/img/030.png +0 -0
  42. data/docs/assets/img/031.png +0 -0
  43. data/docs/assets/img/032.png +0 -0
  44. data/docs/assets/img/033.png +0 -0
  45. data/docs/assets/img/034.png +0 -0
  46. data/docs/assets/img/035.png +0 -0
  47. data/docs/assets/svg/000.svg +41 -31
  48. data/docs/assets/svg/001.svg +9 -0
  49. data/docs/assets/svg/002.svg +9 -0
  50. data/docs/assets/svg/003.svg +9 -0
  51. data/docs/assets/svg/004.svg +9 -0
  52. data/docs/assets/svg/005.svg +9 -0
  53. data/docs/assets/svg/006.svg +9 -0
  54. data/docs/assets/svg/007.svg +9 -0
  55. data/docs/assets/svg/008.svg +9 -0
  56. data/docs/assets/svg/009.svg +9 -0
  57. data/docs/assets/svg/010.svg +19 -8
  58. data/docs/assets/svg/011.svg +9 -0
  59. data/docs/assets/svg/012.svg +9 -0
  60. data/docs/assets/svg/013.svg +9 -0
  61. data/docs/assets/svg/014.svg +9 -0
  62. data/docs/assets/svg/015.svg +9 -0
  63. data/docs/assets/svg/016.svg +9 -0
  64. data/docs/assets/svg/017.svg +9 -0
  65. data/docs/assets/svg/018.svg +9 -0
  66. data/docs/assets/svg/019.svg +9 -0
  67. data/docs/assets/svg/020.svg +9 -0
  68. data/docs/assets/svg/021.svg +9 -0
  69. data/docs/assets/svg/022.svg +9 -0
  70. data/docs/assets/svg/023.svg +9 -0
  71. data/docs/assets/svg/024.svg +9 -0
  72. data/docs/assets/svg/025.svg +9 -0
  73. data/docs/assets/svg/026.svg +9 -0
  74. data/docs/assets/svg/027.svg +9 -0
  75. data/docs/assets/svg/028.svg +9 -0
  76. data/docs/assets/svg/029.svg +132 -0
  77. data/docs/assets/svg/030.svg +82 -0
  78. data/docs/assets/svg/031.svg +42 -0
  79. data/docs/assets/svg/032.svg +92 -0
  80. data/docs/assets/svg/033.svg +80 -0
  81. data/docs/assets/svg/034.svg +97 -0
  82. data/docs/assets/svg/035.svg +80 -0
  83. data/docs/documentation.md +18 -5
  84. data/docs/documentation_ja.md +15 -3
  85. data/docs/examples.html +44 -41
  86. data/lib/rsyntaxtree/base_graph.rb +3 -6
  87. data/lib/rsyntaxtree/element.rb +1 -10
  88. data/lib/rsyntaxtree/markup_parser.rb +1 -1
  89. data/lib/rsyntaxtree/svg_graph.rb +86 -17
  90. data/lib/rsyntaxtree/version.rb +1 -1
  91. data/test/markup_parser_test.rb +2 -0
  92. metadata +23 -2
@@ -143,10 +143,22 @@ SVG形式を用いる場合,期待通りの表示を得るためには,ご
143
143
  - 方向(矢印)のあるパス(`----->`)
144
144
  - 両方向の矢印のあるパス(`<----->`)
145
145
 
146
- 樹形図の中でパスを表示したいとき,パスの両端をIDで指定します.パスIDをプラス(`+`)記号と共にノードのテキストの最後で指定してください(例:`+7`).
147
- プラス記号とパスIDの間に `>` 記号を入れると(例:`+>7`),パスの終端に矢印が付きます.
146
+ 樹形図の中でパスを表示したいとき,パスの両端を数字のIDで指定します。数字をプラス(`+`)記号と共にノードのテキストの最後で指定してください(例:`+7`).
147
+ プラス記号とID番号の間に `>` 記号を入れると(例:`+>7`),パスの終端に矢印が付きます.
148
148
 
149
- パスIDにはどのような数字を用いても構いませんが,必ず **2箇所** で同じIDを指定することが必要です.同じIDを2箇所以上で指定することはできません.
149
+ IDにはどのような数字を用いても構いませんが,必ず **2箇所** で同じIDを指定することが必要です.同じIDを3箇所以上で指定することはできません.
150
+
151
+ ### ノードからノードへの追加的なコネクターの描画(試験的機能)
152
+
153
+ パスの指定と類似した方式でノードからノードへのコネクターを追加することができます。追加的なコネクターは直線で描画されます(`polyline`にはなりません)。
154
+
155
+ 追加のコネクターは数字のIDで指定します,プラスとマイナスを連続させた(`+-`)後にIDを指定してください(例:`+-8`).マイナス記号とID番号の間に `>` 記号を入れると(例:`+->8`),コネクターの終端に矢印が付きます.
156
+
157
+ - 方向(矢印)のないコネクター(`-----`)
158
+ - 方向(矢印)のあるコネクター(`--▶--`)
159
+ - 両方向の矢印のあるコネクター(`-◀-▶-`)
160
+
161
+ IDにはどのような数字を用いても構いませんが,必ず **2箇所** で同じIDを指定することが必要です.同じIDを3箇所以上で指定することはできません.
150
162
 
151
163
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
152
164
  <script src="https://cdn.jsdelivr.net/npm/lightbox2@2.11.3/src/js/lightbox.js"></script>
data/docs/examples.html CHANGED
@@ -8,55 +8,58 @@ layout: default
8
8
  {% assign categories = all_examples | map: 'category' | join: ',' | split: ',' | group_by: category %}
9
9
  <ul>
10
10
  {%- for category in categories -%}
11
- <li><a href="#category-{{ category.name | slugify }}">{{ category.name }}</a> [{{category.size}}]</li>
11
+ {%- if category.name != "Test" -%}
12
+ <li><a href="#category-{{ category.name | slugify }}">{{ category.name }}</a> [{{category.size}}]</li>
13
+ {%- endif -%}
12
14
  {%- endfor -%}
13
15
  </ul>
14
16
 
15
17
  {%- for category in categories -%}
16
- <hr />
17
- <h2 id="category-{{category.name | slugify }}"><b>{{ category.name }}</b></h2>
18
- {%- for example in all_examples -%}
19
- {% if example.category contains category.name %}
20
- <h3>{{ example.caption }}</h3>
21
- <div style='text-align:left;'>
22
- <button onclick="copyToClipBoard('text-{{ example.name }}')" style='margin: 20px 0; font-size: 0.85em;'>
23
- Copy to Clipboard
24
- </button>
25
- </div>
26
- <div class='grid'>
27
- <div style='margin-top: 0; margin-bottom: auto;'>
28
- <div id="text-{{example.name}}" style='max-height: 600px; overflow-y: auto; margin-bottom: 20px;'>
29
- {{ example.content | markdownify }}
30
- </div>
31
- <table style='line-height: 110%; font-size: 0.85em; margin-bottom: 20px;'>
32
- <thead></thead>
33
- <tbody>
34
- <tr><td>Category</td><td>{{ example.category}}</td></tr>
35
- <tr><td>Connector</td><td>{{ example.connector }}</td></tr>
36
- <tr><td>Polyline</td><td>{{ example.polyline }}</td></tr>
37
- <tr><td>Colorization</td><td>{{ example.colorization }}</td></tr>
38
- <tr><td>Radical Symmetirization</td><td>{{ example.symmetrization }}</td></tr>
39
- <tr><td>Font</td><td>{{ example.font }}</td></tr>
40
- {% if example.reference %}
41
- <tr><td>Reference</td><td>{{ example.reference }}</td></tr>
42
- {% endif %}
43
- </tbody>
44
- </table>
45
- </div>
46
- <div style='margin-top: 0; margin-bottom: auto;'>
47
- <a href='assets/img/{{ example.name }}.png' data-lightbox='{{ example.name }}'>
48
- <img src='assets/img/{{ example.name}}.png'/>
49
- </a>
50
- </div>
51
- </div>
52
- <div><a href="#examples">🔝</a></div>
53
- {% endif %}
54
- {%- endfor -%}
18
+ {%- if category.name != "Test" -%}
19
+ <hr />
20
+ <h2 id="category-{{category.name | slugify }}"><b>{{ category.name }}</b></h2>
21
+ {%- for example in all_examples -%}
22
+ {%- if example.category contains category.name -%}
23
+ <h3>{{ example.caption }}</h3>
24
+ <div style='text-align:left;'>
25
+ <button onclick="copyToClipBoard('text-{{ example.name }}')" style='margin: 20px 0; font-size: 0.85em;'>
26
+ Copy to Clipboard
27
+ </button>
28
+ </div>
29
+ <div class='grid'>
30
+ <div style='margin-top: 0; margin-bottom: auto;'>
31
+ <div id="text-{{example.name}}" style='max-height: 600px; overflow-y: auto; margin-bottom: 20px;'>
32
+ {{ example.content | markdownify }}
33
+ </div>
34
+ <table style='line-height: 110%; font-size: 0.85em; margin-bottom: 20px;'>
35
+ <thead></thead>
36
+ <tbody>
37
+ <tr><td>Category</td><td>{{ example.category}}</td></tr>
38
+ <tr><td>Connector</td><td>{{ example.connector }}</td></tr>
39
+ <tr><td>Polyline</td><td>{{ example.polyline }}</td></tr>
40
+ <tr><td>Colorization</td><td>{{ example.colorization }}</td></tr>
41
+ <tr><td>Radical Symmetirization</td><td>{{ example.symmetrization }}</td></tr>
42
+ <tr><td>Font</td><td>{{ example.font }}</td></tr>
43
+ {% if example.reference %}
44
+ <tr><td>Reference</td><td>{{ example.reference }}</td></tr>
45
+ {% endif %}
46
+ </tbody>
47
+ </table>
48
+ </div>
49
+ <div style='margin-top: 0; margin-bottom: auto;'>
50
+ <a href='assets/img/{{ example.name }}.png' data-lightbox='{{ example.name }}'>
51
+ <img src='assets/img/{{ example.name}}.png'/>
52
+ </a>
53
+ </div>
54
+ </div>
55
+ <div><a href="#examples">🔝</a></div>
56
+ {%- endif -%}
57
+ {%- endfor -%}
58
+ {%- endif -%}
55
59
  {%- endfor -%}
56
60
 
57
61
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
58
62
  <script src="https://cdn.jsdelivr.net/npm/lightbox2@2.11.3/src/js/lightbox.js"></script>
59
-
60
63
  <script>
61
64
  function copyToClipBoard(id){
62
65
  var copyText = document.getElementById(id).innerText;
@@ -20,10 +20,12 @@ module RSyntaxTree
20
20
  @col_node = "blue"
21
21
  @col_leaf = "green"
22
22
  @col_path = "purple"
23
+ @col_extra = "red"
23
24
  else
24
25
  @col_node = "black"
25
26
  @col_leaf = "black"
26
27
  @col_path = "black"
28
+ @col_extra = "black"
27
29
  end
28
30
 
29
31
  @col_bg = "none"
@@ -79,13 +81,11 @@ module RSyntaxTree
79
81
 
80
82
  vertical_indent = if !target.triangle &&
81
83
  (@leafstyle == "nothing" || @leafstyle == "none") &&
82
- ETYPE_LEAF == target.type &&
83
- parent.children.size == 1
84
+ ETYPE_LEAF == target.type && parent.children.size == 1
84
85
  parent.vertical_indent + parent.content_height
85
86
  else
86
87
  parent.vertical_indent + parent.content_height + @global[:height_connector]
87
88
  end
88
-
89
89
  target.vertical_indent = vertical_indent
90
90
  end
91
91
 
@@ -185,8 +185,6 @@ module RSyntaxTree
185
185
  triangle_to_parent(parent, child)
186
186
  elsif ETYPE_LEAF != child.type
187
187
  line_to_parent(parent, child)
188
- elsif ETYPE_LEAF == child.type
189
- child.vertical_indent = parent.vertical_indent + parent.content_height + @global[:height_connector] / 2
190
188
  end
191
189
  end
192
190
  else
@@ -239,7 +237,6 @@ module RSyntaxTree
239
237
  end
240
238
 
241
239
  offset_l = (top.horizontal_indent - get_leftmost) + @global[:h_gap_between_nodes]
242
- # offset_r = top.width / 2 - offset_l - @global[:h_gap_between_nodes:
243
240
 
244
241
  @element_list.get_elements.each do |e|
245
242
  e.horizontal_indent += offset_l
@@ -20,7 +20,6 @@ module RSyntaxTree
20
20
  @id = id # Unique element id
21
21
  @parent = parent # Parent element id
22
22
  @children = [] # Child element ids
23
- @type = type # Element type
24
23
  @level = level # Element level in the tree (0=top etc...)
25
24
  @width = 0 # Width of the part of the tree including itself and it governs
26
25
  @content_width = 0 # Width of the content
@@ -28,7 +27,7 @@ module RSyntaxTree
28
27
  @vertical_indent = 0 # Drawing offset
29
28
  content = content.strip
30
29
 
31
- @path = if /.+?\^?((?:\+>?\d+)+)\^?\z/m =~ content
30
+ @path = if /.+?\^?((?:\+-?>?\d+)+)\^?\z/m =~ content
32
31
  $1.sub(/\A\+/, "").split("+")
33
32
  else
34
33
  []
@@ -78,14 +77,6 @@ module RSyntaxTree
78
77
  fontsize = decoration.include?(:subscript) || decoration.include?(:superscript) ? fontsize * SUBSCRIPT_CONST : fontsize
79
78
  style = decoration.include?(:italic) || decoration.include?(:bolditalic) ? :italic : :normal
80
79
  weight = decoration.include?(:bold) || decoration.include?(:bolditalic) ? :bold : :normal
81
-
82
- # e[:cjk] = false
83
- # if e[:decoration].include?(:math)
84
- # font = @fontset[:math]
85
- # elsif text.contains_cjk?
86
- # font = @fontset[:cjk]
87
- # e[:cjk] = true
88
- # elsif decoration.include? :bolditalic
89
80
  font = if decoration.include? :bolditalic
90
81
  @fontset[:bolditalic]
91
82
  elsif decoration.include? :bold
@@ -13,7 +13,7 @@ class MarkupParser < Parslet::Parser
13
13
  rule(:brackets) { str('#') }
14
14
  rule(:triangle) { str('^') }
15
15
 
16
- rule(:path) { (str('+') >> str('>').maybe >> match('\d').repeat(1)).as(:path) }
16
+ rule(:path) { (str('+') >> str('-').maybe >> str('>').maybe >> match('\d').repeat(1)).as(:path) }
17
17
  rule(:escaped) { str('\\') >> match('[#<>{}\\^+*_=~\|\n\-]').as(:chr) }
18
18
  rule(:non_escaped) { ((match('[#<>{}\\^+*_=~\|\-]') | str('\\n')).absent? >> any).as(:chr) }
19
19
  rule(:text) { (escaped | non_escaped).repeat(1).as(:text) }
@@ -49,8 +49,9 @@ module RSyntaxTree
49
49
  y2 = @height + @margin
50
50
  extra_lines = @extra_lines.join("\n")
51
51
 
52
+ as = @global[:h_gap_between_nodes] / 4 * 0.8
52
53
  as2 = @global[:h_gap_between_nodes] / 2 * 0.8
53
- as = as2 / 2
54
+ as4 = @global[:h_gap_between_nodes]
54
55
 
55
56
  header = <<~HDR
56
57
  <?xml version="1.0" standalone="no"?>
@@ -60,6 +61,15 @@ module RSyntaxTree
60
61
  <marker id="arrow" markerUnits="strokeWidth" markerWidth="#{as2}" markerHeight="#{as2}" viewBox="0 0 #{as2} #{as2}" refX="#{as}" refY="0">
61
62
  <polyline fill="none" stroke="#{@col_path}" stroke-width="1" points="0,#{as2},#{as},0,#{as2},#{as2}" />
62
63
  </marker>
64
+ <marker id="arrowForward" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="#{as2}" markerHeight="#{as2}" orient="auto-start-reverse">
65
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="#{@col_extra}"/>
66
+ </marker>
67
+ <marker id="arrowBackward" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="#{as2}" markerHeight="#{as2}" orient="auto">
68
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="#{@col_extra}"/>
69
+ </marker>
70
+ <marker id="arrowBothways" viewBox="0 0 30 10" refX="15" refY="5" markerWidth="#{as4}" markerHeight="#{as4}" orient="auto">
71
+ <path d="M 0 5 L 10 0 L 10 5 L 20 5 L 20 0 L 30 5 L 20 10 L 20 5 L 10 5 L 10 10 z" fill="#{@col_extra}"/>
72
+ </marker>
63
73
  <pattern id="hatchBlack" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
64
74
  <line x1="0" y="0" x2="0" y2="10" stroke="black" stroke-width="4"></line>
65
75
  </pattern>
@@ -85,9 +95,13 @@ module RSyntaxTree
85
95
  end
86
96
  end
87
97
 
98
+ def draw_direct_line(s_x, s_y, t_x, t_y, s_arrow = false, t_arrow = false)
99
+ @extra_lines << generate_connector(s_x, s_y, t_x, t_y, @col_extra, false, s_arrow, t_arrow)
100
+ end
101
+
88
102
  def draw_a_path(s_x, s_y, t_x, t_y, target_arrow = :none)
89
103
  x_spacing = @global[:h_gap_between_nodes] * 1.25
90
- y_spacing = @global[:height_connector] * 0.65
104
+ y_spacing = @global[:height_connector] * 0.75
91
105
 
92
106
  ymax = [s_y, t_y].max
93
107
  new_y = if ymax < @height
@@ -112,14 +126,11 @@ module RSyntaxTree
112
126
  @visited_x[t_x] = 1
113
127
  end
114
128
 
115
- s_y += @global[:h_gap_between_nodes] / 2
116
- t_y += @global[:h_gap_between_nodes] / 2
117
- new_y += @global[:h_gap_between_nodes] / 2
118
-
119
129
  dashed = true if target_arrow == :none
120
130
 
121
131
  case target_arrow
122
132
  when :single
133
+ @extra_lines << generate_line(new_s_x, s_y, new_s_x, new_y, @col_path, dashed)
123
134
  @extra_lines << generate_line(new_s_x, s_y, new_s_x, new_y, @col_path, dashed)
124
135
  @extra_lines << generate_line(new_s_x, new_y, new_t_x, new_y, @col_path, dashed)
125
136
  @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path, dashed, true)
@@ -362,37 +373,54 @@ module RSyntaxTree
362
373
  end
363
374
 
364
375
  def draw_paths
376
+ paths = []
365
377
  path_pool_target = {}
366
378
  path_pool_other = {}
367
379
  path_pool_source = {}
368
380
  path_flags = []
369
- # elist = @element_list.get_elements.reverse
381
+
382
+ line_pool = {}
383
+ line_flags = []
384
+
370
385
  elist = @element_list.get_elements
371
386
 
372
387
  elist.each do |element|
388
+ x0 = element.horizontal_indent - @global[:h_gap_between_nodes]
373
389
  x1 = element.horizontal_indent + element.content_width / 2
374
- y1 = element.vertical_indent + element.content_height
375
- y1 += @global[:height_connector_to_text] if element.enclosure != :none
390
+ x2 = element.horizontal_indent + element.content_width + @global[:h_gap_between_nodes]
391
+ y0 = element.vertical_indent + @global[:height_connector_to_text] / 2
392
+ y1 = element.vertical_indent + element.content_height + @global[:h_gap_between_nodes] * 1.5
376
393
  et = element.path
377
394
  et.each do |tr|
378
- if /\A>(\d+)\z/ =~ tr
395
+ if /\A-(>)?(\d+)\z/ =~ tr
396
+ arrow = $1
397
+ tr = $2
398
+ if line_pool[tr]
399
+ line_pool[tr] << { x: { left: x0, center: x1, right: x2 }, y: { top: y0, center: y0 + (y1 - y0) / 2, bottom: y1 }, arrow: arrow }
400
+ else
401
+ line_pool[tr] = [{ x: { left: x0, center: x1, right: x2 }, y: { top: y0, center: y0 + (y1 - y0) / 2, bottom: y1 }, arrow: arrow }]
402
+ end
403
+ line_flags << tr
404
+ elsif /\A>(\d+)\z/ =~ tr
379
405
  tr = $1
380
406
  if path_pool_target[tr]
381
407
  path_pool_target[tr] << [x1, y1]
382
408
  else
383
409
  path_pool_target[tr] = [[x1, y1]]
384
410
  end
411
+ path_flags << tr
385
412
  elsif path_pool_source[tr]
386
413
  if path_pool_other[tr]
387
414
  path_pool_other[tr] << [x1, y1]
388
415
  else
389
416
  path_pool_other[tr] = [[x1, y1]]
390
417
  end
418
+ path_flags << tr
391
419
  else
392
420
  path_pool_source[tr] = [x1, y1]
421
+ path_flags << tr
393
422
  end
394
- path_flags << tr
395
- raise RSTError, "Error: input text contains a path having more than two ends:\n > #{tr}" if path_flags.tally.any? { |_k, v| v > 2 }
423
+ raise RSTError, "Error: input text contains a path having more than two ends:\n > #{tr}" if path_flags.tally.any? { |_k, v| v > 2 } || line_flags.tally.any? { |_k, v| v > 2 }
396
424
  end
397
425
  end
398
426
 
@@ -400,7 +428,6 @@ module RSyntaxTree
400
428
  raise RSTError, "Error: input text contains a path having only one end:\n > #{k}" if v == 1
401
429
  end
402
430
 
403
- paths = []
404
431
  path_pool_source.each do |k, v|
405
432
  path_flags.delete(k)
406
433
  if (targets = path_pool_target[k])
@@ -423,12 +450,54 @@ module RSyntaxTree
423
450
  end
424
451
 
425
452
  paths.each do |t|
426
- draw_a_path(t[:x1], t[:y1] + @global[:height_connector_to_text] / 2,
427
- t[:x2], t[:y2] + @global[:height_connector_to_text] / 2,
428
- t[:arrow])
453
+ draw_a_path(t[:x1], t[:y1], t[:x2], t[:y2], t[:arrow])
429
454
  end
430
455
 
431
- paths.size
456
+ line_pool.each do |_k, v|
457
+ a = v[0]
458
+ b = v[1]
459
+
460
+ if a[:y][:top] > b[:y][:bottom]
461
+ draw_direct_line(a[:x][:center], a[:y][:top], b[:x][:center], b[:y][:bottom], a[:arrow], b[:arrow])
462
+ elsif b[:y][:top] > a[:y][:bottom]
463
+ draw_direct_line(a[:x][:center], a[:y][:bottom], b[:x][:center], b[:y][:top], a[:arrow], b[:arrow])
464
+ elsif a[:x][:center] < b[:x][:center]
465
+ draw_direct_line(a[:x][:right], a[:y][:center], b[:x][:left], b[:y][:center], a[:arrow], b[:arrow])
466
+ else
467
+ draw_direct_line(b[:x][:right], b[:y][:center], a[:x][:left], a[:y][:center], b[:arrow], a[:arrow])
468
+ end
469
+ end
470
+ paths.size + line_pool.keys.size
471
+ end
472
+
473
+ def generate_connector(x1, y1, x2, y2, col, dashed = false, s_arrow = false, t_arrow = false, stroke_width = 1)
474
+ string = if s_arrow && t_arrow
475
+ "marker-mid='url(#arrowBothways)' "
476
+ elsif s_arrow
477
+ "marker-mid='url(#arrowForward)' "
478
+ elsif t_arrow
479
+ "marker-mid='url(#arrowBackward)' "
480
+ else
481
+ ""
482
+ end
483
+ dasharray = dashed ? "stroke-dasharray='8 8'" : ""
484
+ swidth = FONT_SCALING * stroke_width
485
+
486
+ if s_arrow || t_arrow
487
+ x_mid = if x2 > x1
488
+ x1 + (x2 - x1) / 2
489
+ else
490
+ x1 - (x1 - x2) / 2
491
+ end
492
+ y_mid = if y2 > y1
493
+ y1 + (y2 - y1) / 2
494
+ else
495
+ y1 - (y1 - y2) / 2
496
+ end
497
+ "<path d='M#{x1},#{y1} L#{x_mid},#{y_mid} L#{x2}, #{y2}' style='fill: none; stroke: #{col}; stroke-width:#{swidth}' #{dasharray} #{string}/>"
498
+ else
499
+ "<line x1='#{x1}' y1='#{y1}' x2='#{x2}' y2='#{y2}' style='fill: none; stroke: #{col}; stroke-width:#{swidth}' #{dasharray} #{string}/>"
500
+ end
432
501
  end
433
502
 
434
503
  def generate_line(x1, y1, x2, y2, col, dashed = false, arrow = false, stroke_width = 1)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSyntaxTree
4
- VERSION = "1.1.4"
4
+ VERSION = "1.2.1"
5
5
  end
@@ -29,6 +29,8 @@ class MarkupParserTest < Minitest::Test
29
29
  # {:path=>"+12"@0}
30
30
  @parser.path.parse('+>34')
31
31
  # {:path=>"+>34"@0}d
32
+ @parser.path.parse('+-87')
33
+ # {:path=>"+-87"@0}d
32
34
  end
33
35
 
34
36
  def test_rule_escaped
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsyntaxtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoichiro Hasebe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-29 00:00:00.000000000 Z
11
+ date: 2023-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optimist
@@ -141,6 +141,13 @@ files:
141
141
  - docs/_examples/026.md
142
142
  - docs/_examples/027.md
143
143
  - docs/_examples/028.md
144
+ - docs/_examples/029.md
145
+ - docs/_examples/030.md
146
+ - docs/_examples/031.md
147
+ - docs/_examples/032.md
148
+ - docs/_examples/033.md
149
+ - docs/_examples/034.md
150
+ - docs/_examples/035.md
144
151
  - docs/_includes/box_and_circle_table.html
145
152
  - docs/_includes/escape_char_table.html
146
153
  - docs/_includes/social_media_links.html
@@ -175,6 +182,13 @@ files:
175
182
  - docs/assets/img/026.png
176
183
  - docs/assets/img/027.png
177
184
  - docs/assets/img/028.png
185
+ - docs/assets/img/029.png
186
+ - docs/assets/img/030.png
187
+ - docs/assets/img/031.png
188
+ - docs/assets/img/032.png
189
+ - docs/assets/img/033.png
190
+ - docs/assets/img/034.png
191
+ - docs/assets/img/035.png
178
192
  - docs/assets/img/elements/circle.png
179
193
  - docs/assets/img/elements/circle_abc.png
180
194
  - docs/assets/img/elements/circle_bold.png
@@ -220,6 +234,13 @@ files:
220
234
  - docs/assets/svg/026.svg
221
235
  - docs/assets/svg/027.svg
222
236
  - docs/assets/svg/028.svg
237
+ - docs/assets/svg/029.svg
238
+ - docs/assets/svg/030.svg
239
+ - docs/assets/svg/031.svg
240
+ - docs/assets/svg/032.svg
241
+ - docs/assets/svg/033.svg
242
+ - docs/assets/svg/034.svg
243
+ - docs/assets/svg/035.svg
223
244
  - docs/documentation.md
224
245
  - docs/documentation_ja.md
225
246
  - docs/examples.html