rsyntaxtree 1.4.0 → 1.6.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.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +45 -3
  5. data/README.md +15 -2
  6. data/bin/rsyntaxtree +9 -5
  7. data/dev/generate_examples.rb +2 -0
  8. data/dev/region_shade_proposal.md +66 -0
  9. data/docs/_examples/010.md +1 -0
  10. data/docs/_examples/056.md +1 -3
  11. data/docs/_examples/057.md +34 -0
  12. data/docs/_examples/058.md +47 -0
  13. data/docs/_examples/059.md +54 -0
  14. data/docs/_examples/060.md +72 -0
  15. data/docs/_examples/061.md +97 -0
  16. data/docs/_examples/062.md +96 -0
  17. data/docs/_examples/063.md +53 -0
  18. data/docs/_examples/064.md +25 -0
  19. data/docs/_includes/escape_char_table.html +1 -0
  20. data/docs/assets/img/000.png +0 -0
  21. data/docs/assets/img/001.png +0 -0
  22. data/docs/assets/img/002.png +0 -0
  23. data/docs/assets/img/003.png +0 -0
  24. data/docs/assets/img/004.png +0 -0
  25. data/docs/assets/img/005.png +0 -0
  26. data/docs/assets/img/006.png +0 -0
  27. data/docs/assets/img/007.png +0 -0
  28. data/docs/assets/img/008.png +0 -0
  29. data/docs/assets/img/009.png +0 -0
  30. data/docs/assets/img/010.png +0 -0
  31. data/docs/assets/img/011.png +0 -0
  32. data/docs/assets/img/012.png +0 -0
  33. data/docs/assets/img/013.png +0 -0
  34. data/docs/assets/img/014.png +0 -0
  35. data/docs/assets/img/015.png +0 -0
  36. data/docs/assets/img/016.png +0 -0
  37. data/docs/assets/img/017.png +0 -0
  38. data/docs/assets/img/018.png +0 -0
  39. data/docs/assets/img/019.png +0 -0
  40. data/docs/assets/img/020.png +0 -0
  41. data/docs/assets/img/021.png +0 -0
  42. data/docs/assets/img/022.png +0 -0
  43. data/docs/assets/img/023.png +0 -0
  44. data/docs/assets/img/024.png +0 -0
  45. data/docs/assets/img/025.png +0 -0
  46. data/docs/assets/img/026.png +0 -0
  47. data/docs/assets/img/027.png +0 -0
  48. data/docs/assets/img/028.png +0 -0
  49. data/docs/assets/img/029.png +0 -0
  50. data/docs/assets/img/030.png +0 -0
  51. data/docs/assets/img/031.png +0 -0
  52. data/docs/assets/img/032.png +0 -0
  53. data/docs/assets/img/033.png +0 -0
  54. data/docs/assets/img/034.png +0 -0
  55. data/docs/assets/img/035.png +0 -0
  56. data/docs/assets/img/036.png +0 -0
  57. data/docs/assets/img/037.png +0 -0
  58. data/docs/assets/img/038.png +0 -0
  59. data/docs/assets/img/039.png +0 -0
  60. data/docs/assets/img/040.png +0 -0
  61. data/docs/assets/img/041.png +0 -0
  62. data/docs/assets/img/042.png +0 -0
  63. data/docs/assets/img/043.png +0 -0
  64. data/docs/assets/img/044.png +0 -0
  65. data/docs/assets/img/045.png +0 -0
  66. data/docs/assets/img/046.png +0 -0
  67. data/docs/assets/img/047.png +0 -0
  68. data/docs/assets/img/048.png +0 -0
  69. data/docs/assets/img/049.png +0 -0
  70. data/docs/assets/img/050.png +0 -0
  71. data/docs/assets/img/051.png +0 -0
  72. data/docs/assets/img/052.png +0 -0
  73. data/docs/assets/img/053.png +0 -0
  74. data/docs/assets/img/054.png +0 -0
  75. data/docs/assets/img/055.png +0 -0
  76. data/docs/assets/img/056.png +0 -0
  77. data/docs/assets/img/057.png +0 -0
  78. data/docs/assets/img/058.png +0 -0
  79. data/docs/assets/img/059.png +0 -0
  80. data/docs/assets/img/060.png +0 -0
  81. data/docs/assets/img/061.png +0 -0
  82. data/docs/assets/img/062.png +0 -0
  83. data/docs/assets/img/063.png +0 -0
  84. data/docs/assets/img/064.png +0 -0
  85. data/docs/assets/svg/000.svg +26 -26
  86. data/docs/assets/svg/001.svg +19 -19
  87. data/docs/assets/svg/002.svg +37 -37
  88. data/docs/assets/svg/003.svg +29 -29
  89. data/docs/assets/svg/004.svg +41 -41
  90. data/docs/assets/svg/005.svg +21 -21
  91. data/docs/assets/svg/006.svg +25 -25
  92. data/docs/assets/svg/007.svg +31 -31
  93. data/docs/assets/svg/008.svg +35 -35
  94. data/docs/assets/svg/009.svg +35 -35
  95. data/docs/assets/svg/010.svg +50 -52
  96. data/docs/assets/svg/011.svg +30 -30
  97. data/docs/assets/svg/012.svg +35 -35
  98. data/docs/assets/svg/013.svg +104 -104
  99. data/docs/assets/svg/014.svg +80 -80
  100. data/docs/assets/svg/015.svg +28 -28
  101. data/docs/assets/svg/016.svg +54 -54
  102. data/docs/assets/svg/017.svg +35 -35
  103. data/docs/assets/svg/018.svg +37 -37
  104. data/docs/assets/svg/019.svg +95 -95
  105. data/docs/assets/svg/020.svg +53 -53
  106. data/docs/assets/svg/021.svg +42 -42
  107. data/docs/assets/svg/022.svg +68 -68
  108. data/docs/assets/svg/023.svg +32 -32
  109. data/docs/assets/svg/024.svg +23 -23
  110. data/docs/assets/svg/025.svg +99 -99
  111. data/docs/assets/svg/026.svg +19 -19
  112. data/docs/assets/svg/027.svg +50 -50
  113. data/docs/assets/svg/028.svg +21 -21
  114. data/docs/assets/svg/029.svg +69 -69
  115. data/docs/assets/svg/030.svg +35 -35
  116. data/docs/assets/svg/031.svg +15 -15
  117. data/docs/assets/svg/032.svg +40 -41
  118. data/docs/assets/svg/033.svg +38 -38
  119. data/docs/assets/svg/034.svg +40 -40
  120. data/docs/assets/svg/035.svg +39 -39
  121. data/docs/assets/svg/036.svg +17 -17
  122. data/docs/assets/svg/037.svg +26 -26
  123. data/docs/assets/svg/038.svg +39 -39
  124. data/docs/assets/svg/039.svg +7 -7
  125. data/docs/assets/svg/040.svg +67 -67
  126. data/docs/assets/svg/041.svg +49 -49
  127. data/docs/assets/svg/042.svg +15 -15
  128. data/docs/assets/svg/043.svg +127 -127
  129. data/docs/assets/svg/044.svg +2 -2
  130. data/docs/assets/svg/045.svg +56 -56
  131. data/docs/assets/svg/046.svg +647 -647
  132. data/docs/assets/svg/047.svg +26 -26
  133. data/docs/assets/svg/048.svg +69 -69
  134. data/docs/assets/svg/049.svg +44 -44
  135. data/docs/assets/svg/050.svg +100 -100
  136. data/docs/assets/svg/051.svg +96 -96
  137. data/docs/assets/svg/052.svg +50 -50
  138. data/docs/assets/svg/053.svg +41 -41
  139. data/docs/assets/svg/054.svg +16 -15
  140. data/docs/assets/svg/055.svg +10 -9
  141. data/docs/assets/svg/056.svg +27 -29
  142. data/docs/assets/svg/057.svg +91 -0
  143. data/docs/assets/svg/058.svg +95 -0
  144. data/docs/assets/svg/059.svg +111 -0
  145. data/docs/assets/svg/060.svg +134 -0
  146. data/docs/assets/svg/061.svg +193 -0
  147. data/docs/assets/svg/062.svg +179 -0
  148. data/docs/assets/svg/063.svg +94 -0
  149. data/docs/assets/svg/064.svg +63 -0
  150. data/docs/documentation.md +44 -1
  151. data/docs/documentation_ja.md +43 -1
  152. data/lib/rsyntaxtree/base_graph.rb +114 -4
  153. data/lib/rsyntaxtree/element.rb +11 -3
  154. data/lib/rsyntaxtree/lsif_graph.rb +299 -0
  155. data/lib/rsyntaxtree/markup_parser.rb +17 -3
  156. data/lib/rsyntaxtree/string_parser.rb +6 -6
  157. data/lib/rsyntaxtree/svg_graph.rb +276 -95
  158. data/lib/rsyntaxtree/tikz_generator.rb +123 -4
  159. data/lib/rsyntaxtree/version.rb +1 -1
  160. data/lib/rsyntaxtree.rb +10 -1
  161. data/test/example_verify_test.rb +2 -0
  162. data/test/lsif_test.rb +304 -0
  163. data/test/markup_parser_test.rb +43 -0
  164. data/test/node_styling_test.rb +117 -0
  165. data/test/overlap_test.rb +122 -0
  166. data/test/tikz_test.rb +58 -0
  167. metadata +29 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e09c9414509d88c6bb4d1bc9b8acdb5384094e642a1fb4765c62a4ffe6a4ba0
4
- data.tar.gz: c4f617a630db5edf5373ceeeb4c03b889cc84d548201a4746f448386db2efebe
3
+ metadata.gz: b1ba1c70fd18704ea011d4edb62af9cb18b0109852731faf08a0f8a24360acab
4
+ data.tar.gz: da6e7c971afc3e5b1b1dbea1f9e0955a511a71702c3869673a363106f45d9459
5
5
  SHA512:
6
- metadata.gz: 3d1e620f2662c43e3c1c66b55750ae252fa90e978ddfebed0fc5937cc8265014f3fc02aed3ee3627b4a2de264709c58e2e076884c1f0c869c8868db9dcf42237
7
- data.tar.gz: 7f6f5d8ccb8b0f3f50363e5e1809ec32461e677458ec4b53bfbe383ef48889ed6ff8f2fda1edfc47fafcf4747857fcf260a1007d083733e20aeb4eefaf987b00
6
+ metadata.gz: b5f0a68402ced555dd3ab07c1a3540225b6afe880f56385c2e9c419974bddbde31330cc78a9a2c8306c1692e7810a6bf57c1b35812af62135305241083daf011
7
+ data.tar.gz: 16268685b95ca4e98d566275b0f82d4f265b88c665ac6fee796837bfa8ceee36df45e708ec057e3dc0e62270e6bfcc9f4f599177608e7a9d7c76f314d67b1b08
data/.gitignore CHANGED
@@ -7,6 +7,7 @@ Gemfile.lock
7
7
  *.bak
8
8
  *.~
9
9
  *.log
10
+ *.gem
10
11
  log/
11
12
  logs/
12
13
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 4.0.0
1
+ 4.0.1
data/CHANGELOG.md CHANGED
@@ -1,21 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.0] - 2026-06
4
+
5
+ ### Added
6
+ - Region shade (`%` prefix): paints a semi-transparent plane behind the whole
7
+ subtree a node governs, for marking c-command/binding domains and cognitive
8
+ grammar dominions. Color reuses the `@color:` syntax; bare `%` uses light gray.
9
+ Each plane has a darker same-color border for visibility on white. An explicit
10
+ shade color is always honored (consistent with `@color:` node text); use bare
11
+ `%` for a gray monochrome shade. Works in both TTB and LTR layouts and across
12
+ SVG/PNG/PDF/JPG/GIF.
13
+ - Region shade support in TikZ export (via `forest` `fit to=tree`) and in LSIF
14
+ node `style.region`. TikZ region colors (names and hex, including SVG/CSS
15
+ names like `lightblue` that xcolor lacks) are emitted as explicit RGB so the
16
+ output compiles.
17
+ - `\%` escape for a literal leading percent sign.
18
+ - Typographic apostrophe: a straight ASCII apostrophe (`'`) in a label is now
19
+ rendered as a curly apostrophe (`’`, U+2019) for smarter typography, e.g. the
20
+ X-bar prime in `T'`. Applied to all fonts and measured before layout so
21
+ spacing stays correct.
22
+ - Example 064: region shade for a c-command domain.
23
+
24
+ ### Changed
25
+ - LSIF output version bumped to `0.3.0` (adds node `style.region`).
26
+
27
+ ### Fixed
28
+ - Region shade on the root/topmost node no longer clipped by the canvas: the
29
+ SVG viewBox now grows to include region planes that extend past the tree.
30
+
31
+ ## [1.5.0] - 2026-04
32
+
33
+ ### Added
34
+ - Left-to-right tree layout (`-d ltr` / `--direction ltr`)
35
+ - LSIF `geometry.direction` field for layout direction
36
+ - LTR-aware path drawing (movement arrows route rightward in ⊃ shape)
37
+ - LTR-aware line-type connections (direct lines between nodes)
38
+ - Examples 058-063: LTR versions of classification trees and vP-shell with paths
39
+
40
+ ### Fixed
41
+ - Node label overlap when adjacent subtrees have long labels
42
+
43
+ ### Improved
44
+ - TTB path bulge proportional to endpoint distance (reduced excess)
45
+
3
46
  ## [1.4.0] - 2026-01
4
47
 
5
48
  ### Added
49
+ - LSIF (Linguistic Structure Interchange Format) JSON output (`-f lsif`)
6
50
  - Per-node coloring with `@color:` syntax (named colors and hex colors)
7
51
  - Penn Treebank format support with escaped parentheses (`\(`, `\)`)
8
52
  - Standard input support for piping tree data
9
53
  - Configuration file support (`.rsyntaxtreerc`)
10
54
  - Config file validation with helpful error messages
11
55
 
12
- ### Fixed
13
- - Triangle connector now correctly draws from parent to child (not child to grandchild)
14
-
15
56
  ### Documentation
16
57
  - Added TikZ output limitations section
17
58
  - Improved README with Features section
18
59
  - Added examples for per-node coloring (054, 055, 056)
60
+ - Added example 057: Subscript and superscript demo
19
61
 
20
62
  ## [1.3.2] - 2024
21
63
 
data/README.md CHANGED
@@ -48,6 +48,14 @@ Supports named colors (`red`, `blue`, `green`, etc.) and hex colors (`@#FF5733:`
48
48
 
49
49
  Combine with colors: `[#@red:NP text]`, `[^@blue:VP phrase]`
50
50
 
51
+ ### Region Shade
52
+
53
+ Shade the whole subtree a node governs with a semi-transparent plane — useful for c-command/binding domains and cognitive grammar dominions. Prefix the node with `%`; the color reuses the `@color:` syntax (bare `%` is gray):
54
+
55
+ ```text
56
+ [TP [DP everyone] [%@lightblue:T' [T will] [VP praise it]]]
57
+ ```
58
+
51
59
  ### Path Drawing
52
60
 
53
61
  Connect nodes with lines or arrows:
@@ -58,7 +66,7 @@ Connect nodes with lines or arrows:
58
66
 
59
67
  ### Multiple Output Formats
60
68
 
61
- Generate trees in PNG, SVG, PDF, JPG, or GIF format.
69
+ Generate trees in PNG, SVG, PDF, JPG, GIF, or LSIF (JSON) format.
62
70
 
63
71
  ## Web Interface
64
72
 
@@ -143,13 +151,14 @@ Usage:
143
151
  | Option | Description | Default |
144
152
  |--------|-------------|---------|
145
153
  | `-o, --outdir` | Output directory | `./` |
146
- | `-f, --format` | Output format: png, gif, jpg, pdf, svg | `png` |
154
+ | `-f, --format` | Output format: png, gif, jpg, pdf, svg, lsif | `png` |
147
155
  | `-l, --leafstyle` | Leaf style: auto, triangle, bar, nothing | `auto` |
148
156
  | `-n, --fontstyle` | Font style: sans, serif, cjk, mono | `sans` |
149
157
  | `-s, --fontsize` | Font size: 8-26 | `16` |
150
158
  | `-c, --color` | Color mode: modern, traditional, off | `modern` |
151
159
  | `-y, --symmetrize` | Symmetrical tree: on, off | `off` |
152
160
  | `-p, --polyline` | Polyline connectors: on, off | `off` |
161
+ | `-d, --direction` | Tree layout direction: ttb, ltr | `ttb` |
153
162
 
154
163
  Run `rsyntaxtree -h` for the full list of options.
155
164
 
@@ -193,6 +202,10 @@ Please use the following BibTeX entry when citing RSyntaxTree:
193
202
  }
194
203
  ```
195
204
 
205
+ ## Related Blog Posts
206
+
207
+ - [RSyntaxTree tag on yohasebe.com](https://yohasebe.com/tags/rsyntaxtree/)
208
+
196
209
  ## Author
197
210
 
198
211
  Yoichiro Hasebe (<yohasebe@gmail.com>)
data/bin/rsyntaxtree CHANGED
@@ -12,7 +12,7 @@ require_relative '../lib/rsyntaxtree/format_converter'
12
12
  CONFIG_VALIDATORS = {
13
13
  outdir: ->(v) { FileTest.directory?(v) ? nil : "must be an existing directory path" },
14
14
  outfilename: ->(v) { v.is_a?(String) ? nil : "must be a string" },
15
- format: ->(v) { /\A(png|jpg|gif|pdf|svg)\z/ =~ v.to_s ? nil : "must be png, jpg, gif, pdf, or svg" },
15
+ format: ->(v) { /\A(png|jpg|gif|pdf|svg|lsif)\z/ =~ v.to_s ? nil : "must be png, jpg, gif, pdf, svg, or lsif" },
16
16
  leafstyle: ->(v) { /\A(auto|triangle|bar|nothing)\z/ =~ v.to_s ? nil : "must be auto, triangle, bar, or nothing" },
17
17
  fontstyle: ->(v) { /\A(sans|serif|cjk|mono)\z/ =~ v.to_s ? nil : "must be sans, serif, cjk, or mono" },
18
18
  font: ->(v) { v.nil? || File.exist?(v) ? nil : "must be path to an existing ttf font" },
@@ -23,7 +23,8 @@ CONFIG_VALIDATORS = {
23
23
  symmetrize: ->(v) { /\A(on|off|true|false)\z/ =~ v.to_s ? nil : "must be on or off" },
24
24
  transparent: ->(v) { /\A(on|off|true|false)\z/ =~ v.to_s ? nil : "must be on or off" },
25
25
  polyline: ->(v) { /\A(on|off|true|false)\z/ =~ v.to_s ? nil : "must be on or off" },
26
- hide_default_connectors: ->(v) { /\A(on|off|true|false)\z/ =~ v.to_s ? nil : "must be on or off" }
26
+ hide_default_connectors: ->(v) { /\A(on|off|true|false)\z/ =~ v.to_s ? nil : "must be on or off" },
27
+ direction: ->(v) { /\A(ttb|ltr)\z/ =~ v.to_s ? nil : "must be ttb or ltr" }
27
28
  }.freeze
28
29
 
29
30
  # Validate configuration and return errors/warnings
@@ -97,7 +98,7 @@ opts = Optimist.options do
97
98
 
98
99
  opt :outdir, "Output directory", default: "./"
99
100
  opt :outfilename, "Output file base name", default: "syntree"
100
- opt :format, "Output format: png, jpg, gif, pdf, or svg", default: "png"
101
+ opt :format, "Output format: png, jpg, gif, pdf, svg, or lsif", default: "png"
101
102
  opt :leafstyle, "visual style of tree leaves: auto, triangle, bar, or nothing", default: "auto"
102
103
  opt :fontstyle, "Font style (available when ttf font is specified): sans, serif, cjk, mono", default: "sans"
103
104
  opt :font, "Path to a ttf font used to generate tree (optional)", type: String
@@ -109,11 +110,13 @@ opts = Optimist.options do
109
110
  opt :transparent, "Make background transparent: on or off", default: "off"
110
111
  opt :polyline, "draw polyline connectors: on or off", default: "off"
111
112
  opt :hide_default_connectors, "make default connectors transparent: on or off", default: "off"
113
+ opt :direction, "Tree layout direction: ttb (top-to-bottom) or ltr (left-to-right)", default: "ttb"
112
114
  opt :help, "This is a custom help message", short: :h
113
115
  end
114
116
 
115
117
  Optimist.die :outdir, "must be an exsting directory path" unless FileTest.directory?(opts[:outdir])
116
- Optimist.die :format, "must be png, pdf, or svg" unless /\A(png|jpg|gif|pdf|svg)\z/ =~ opts[:format]
118
+ Optimist.die :direction, "must be ttb or ltr" unless /\A(ttb|ltr)\z/ =~ opts[:direction]
119
+ Optimist.die :format, "must be png, pdf, svg, or lsif" unless /\A(png|jpg|gif|pdf|svg|lsif)\z/ =~ opts[:format]
117
120
  Optimist.die :leafstyle, "must be auto, triangle, bar, or nothing" unless /\A(auto|triangle|bar|nothing)\z/ =~ opts[:leafstyle]
118
121
  Optimist.die :fontstyle, "must be sans, serif, cjk, or mono" unless /\A(sans|serif|cjk|mono)\z/ =~ opts[:fontstyle]
119
122
  Optimist.die :font, "must be path to an existing ttf font" if opts[:font] && !File.exist?(opts[:font])
@@ -170,7 +173,8 @@ begin
170
173
  rsg = RSyntaxTree::RSGenerator.new(string_opts)
171
174
  ext = string_opts[:format]
172
175
  outfilename = string_opts[:outfilename] || "syntree"
173
- filepath = File.expand_path(string_opts[:outdir]) + "/#{outfilename}." + ext
176
+ file_ext = ext == "lsif" ? "lsif.json" : ext
177
+ filepath = File.expand_path(string_opts[:outdir]) + "/#{outfilename}.#{file_ext}"
174
178
  draw_method = "draw_#{ext}"
175
179
  output = rsg.send(draw_method)
176
180
  File.binwrite(filepath, output)
@@ -54,6 +54,8 @@ Dir.glob("*.md", base: examples_dir).map do |md|
54
54
  opts[:symmetrize] = value
55
55
  when "connector"
56
56
  opts[:leafstyle] = value
57
+ when "direction"
58
+ opts[:direction] = value
57
59
  when "font"
58
60
  opts[:fontstyle] = case value
59
61
  when /mono/i
@@ -0,0 +1,66 @@
1
+ # 提案:領域シェード(部分木をまたぐ網掛け)機能
2
+
3
+ 作成: 2026-06-25 / 動機: 容認度研究プロジェクト(2026-accdeptability)で、c-command 領域・束縛領域・認知文法の dominion を「面」で示したい。現状の囲み(`#`/`##`/`###`)は**ノードのラベルのみ**で、部分木全体を囲めない。
4
+
5
+ ## 現行マークアップ仕様の要約(1.5.0、`markup_parser.rb` の `lines` 規則より)
6
+
7
+ ノードラベルの構造(順序固定):
8
+ `^`(三角) → 囲み `#`|`##`|`###` → `@色:` → 本文(装飾) … → 末尾に移動パス `+1`/`+>1`/`+<1`
9
+
10
+ - 囲み: `#`角括弧 / `##`矩形 / `###`二重矩形(**ノードのみ**)
11
+ - 色: `@name:` / `@#hex:`
12
+ - 移動パス: `+` `-`? (`>`|`<`)? digits(複数可)
13
+ - インライン装飾: `**bold**` `*italic*` `***bi***` / `=overline=` `-underline-` `~through~` / `__sup__` `_sub_` `___small___` / 図形 `|box|` `{circle}` `||` `{}` `|/|` `{/}` `--` `->` `<-` `<->` / 太線囲み `*〈shape〉*` / 区切り線 `---` `===` / `\n` / エスケープ `\`
14
+
15
+ 使用済み記号: `# ^ @ : + - > < * = ~ _ | { } [ ] ( ) \` +数字。
16
+ **未使用(衝突なし): `% & ! ? $ ;`**
17
+
18
+ ## 設計(決定: 案A、`%` を採用)
19
+
20
+ - **記法**: `[%@yellow:VP …]` → `%` が「領域シェード ON」、色は既存 `@色:` を流用。
21
+ - `lines` 規則に region 用プレフィックス(`%`)を `triangle`/`enclosure` と並べて追加(`%`.maybe.as(:region))。
22
+ - 色は既存 color_spec を再利用(重複文法を作らない)。`%` 単独なら既定色(薄いグレー)。
23
+ - **意味論**: 当該ノードが支配する**部分木全体**の背後に半透明矩形を描く。
24
+ - 範囲: x = ノードの left 〜 left+width(element は支配範囲幅 `@width` を保持)、y = ノードの y 〜 子孫の最大 y。
25
+ - z-order: 最背面(ツリー線・ラベルの下)。
26
+ - **バックエンド**: `svg_graph.rb`(rect fill-opacity)、`tikz_generator.rb`(\fill[opacity])、png 経路(rmagick)。の3つに描画を追加。
27
+
28
+ ## 触るファイル(見積り: 中)
29
+ - `markup_parser.rb`: `region` トークン追加、`parse` の results に `:region` 追加。
30
+ - `element.rb`: `region`/`region_color` 属性、子孫の y/x 範囲(bounding box)算出ヘルパ。
31
+ - `base_graph.rb` / `svg_graph.rb` / `tikz_generator.rb`: 最背面シェード描画。
32
+ - `string_parser.rb`: ノード属性として region を伝播(必要なら)。
33
+ - ドキュメント(`docs/documentation.md` ほか)・examples 追加。
34
+
35
+ ## 注意
36
+ - 隣接シェードが重なる場合の色合成(複数領域の入れ子)。半透明なら自然に重なる。
37
+ - LTR レイアウトでも bounding box 算出が成立するか確認。
38
+ - 実装は容認度研究のノート群が一段落してから着手(研究が主)。
39
+
40
+ ---
41
+
42
+ ## 実装記録(2026-06-25 完了)
43
+
44
+ 実装済み。設計(案A、`%` 採用)どおり。主な判断と差分:
45
+
46
+ - **色の意味論を明確化**: `%@色:` の色は**領域シェードの色**に束縛し、ノードのテキスト/線色とは独立させた。文法上は `region = '%' >> color_spec?` とし、その後ろに従来の `color_spec?` を別途残した。よって `%@yellow:@blue:VP` = 黄色の面+青のラベル。`%` 単独は既定の薄いグレー(`#888888` / opacity 0.18)。
47
+ - **PNG/PDF/JPG/GIF は SVG 由来**(`rsyntaxtree.rb` の `draw_png`/`draw_pdf` は `draw_svg` を経由、JPG/GIF は PNG 経由)。よって SVG に rect を入れるだけで全ラスタ/ベクタ形式に波及。提案の「png 経路(rmagick)に描画追加」は現状実装と乖離していたため**不要**と判断し、rmagick への直接描画は行っていない。
48
+ - **z-order**: 白背景 rect の直後・`@tree_data` の前に挿入(`@region_shades` バッファ)。transparent モードでも先頭に挿入。
49
+ - **bounding box**: `base_graph.rb#subtree_bounds(id)` を新設。レイアウト確定後(`finalize_ltr` 後)の `horizontal_indent`/`vertical_indent`/`content_*` を再帰で集約。node の `content_height` は `draw_element` 内で再計算されるため、シェード収集は `parse_list` 完了後(`svg_data` 内 `collect_region_shades`)に実行。TTB/LTR 両対応を確認済み。
50
+ - **TikZ**: `forest` の `fit to=tree` を背景レイヤー(`\scoped[on background layer]`)で使用。standalone 出力時のみ `\usetikzlibrary{backgrounds,fit}` を自動付加。HEX 色は `{rgb,255:...}` へ変換。**未確定事項**: 当環境に LaTeX 未インストールのため `fit to=tree` の実コンパイル検証は未実施。要、実機での確認。
51
+ - **LSIF**: node の `style.region`(`{color: ...}` または `null`)を追加。指定色の意図を記録し、白黒化(下記)は描画側のみ。
52
+ - **視認性改良(追加要望対応)**: 白地で薄い面が見にくい問題に対し、各面へ**同色だが不透明度を上げたボーダー**を付与(fill-opacity 0.2 / stroke-opacity 0.55、stroke-width=線幅+LINE_SCALING)。色名・HEX 問わず「濃い同系色ボーダー」になり暗色計算不要。TikZ も `draw=色, draw opacity` を付与。
53
+ - **白黒モードの色の扱い**: 当初「color オフ時はグレー強制」としたが、シェードも色指定可能で `@color:`(文字色は白黒でも色を honor)と非対称になるため、ユーザー判断で**「明示色は常に尊重・素の % のみ既定グレー・モード依存なし」**に確定。白黒図にしたい場合は素の % を使う。
54
+
55
+ ## 懸念対応(concerns 反映、2回目)
56
+
57
+ `/concerns` レビューで挙げた点を全て対応(TDD)。
58
+
59
+ - **TikZ 色名互換**: SVG は任意の CSS 色名を解釈できるが xcolor は限定的(`lightblue` 等が未定義→コンパイル不可)。`tikz_generator.rb` に **CSS 拡張色名148色テーブル `CSS_COLORS`** を追加し、色名・hex(3桁短縮含む)を**インライン rgb 式 `{rgb,255:...}` に解決**。未知名のみ素通し(best effort)。例064の `lightblue` も解決される。
60
+ - **上辺クリップ**: ルート/最上位ノードに領域を付けると面の上辺が viewBox(miny=0)外で切れていた。`collect_region_shades` で領域の和集合境界 `@region_bounds`(pad+ストローク半分込み)を記録し、`svg_data` で **viewBox/背景 rect/幅高さを領域込みに拡張**。
61
+ - **LSIF version**: `0.2.0`→`0.3.0`(`style.region` 追加の additive 変更を明示)。
62
+ - **`\%` エスケープ**: `markup_parser` の `escaped` 文字クラスに `%` 追加+`string_parser#get_next_token` の特殊文字 regex に `%` を追加(`\%` を `\%` のまま保持)。先頭リテラル `%` が出せるように。escape 表(`escape_char_table.html`)も更新。
63
+ - **未対応のまま**: TikZ `fit to=tree` の実 LaTeX コンパイル検証(環境に LaTeX 無し)。O(n²)(全ノード region 時のみ、実害なし)。symmetrize モードの明示テストは無し。
64
+ - テスト: 240 runs / 0 failures。
65
+ - **後方互換**: 先頭 `%` を予約。既存 examples に先頭 `%` の使用はなく破壊なし。`%` のエスケープ(`\%`)は未対応(必要になれば `escaped` ルールに `%` を追加)。
66
+ - **触ったファイル**: `markup_parser.rb`, `element.rb`, `base_graph.rb`, `svg_graph.rb`, `tikz_generator.rb`, `lsif_graph.rb`, tests(`markup_parser_test`/`node_styling_test`/`tikz_test`), `docs/_examples/064.md`, `docs/documentation.md`, `docs/documentation_ja.md`, `CHANGELOG.md`。`string_parser.rb` は変更不要だった(`%` は通常文字として透過)。
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: "010"
3
+ caption: "vP-shell with movement paths"
3
4
  category: "Generative Grammar"
4
5
  polyline: "off"
5
6
  color: "modern"
@@ -13,9 +13,7 @@ font: "Noto Sans"
13
13
  ---
14
14
  ```
15
15
  [S
16
- [#@red:NP
17
- [^@blue:N the quick brown fox]
18
- ]
16
+ [#@red:NP the quick brown fox]
19
17
  [#@green:VP
20
18
  [V jumps]
21
19
  [PP
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: "057"
3
+ color: "on"
4
+ caption: "Subscript and superscript"
5
+ category: "Miscellaneous"
6
+ polyline: "off"
7
+ symmetrization: "off"
8
+ connector: "auto"
9
+ connector_height: "2.0"
10
+ linewidth: "1"
11
+ hide_default_connectors: "off"
12
+ font: "Noto Serif"
13
+ ---
14
+ ```
15
+ [TP
16
+ [DP_i_ John]
17
+ [T'
18
+ [T__0__ pres]
19
+ [VP
20
+ [V believes]
21
+ [TP
22
+ [DP_i_ himself]
23
+ [T'
24
+ [T__0__ to]
25
+ [VP
26
+ [V be]
27
+ [AP smart]
28
+ ]
29
+ ]
30
+ ]
31
+ ]
32
+ ]
33
+ ]
34
+ ```
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: "058"
3
+ caption: "Types of meaning (left-to-right)"
4
+ color: "off"
5
+ category: "Pragmatics"
6
+ polyline: "on"
7
+ symmetrization: "off"
8
+ connector: "bar"
9
+ connector_height: "1.5"
10
+ linewidth: "1"
11
+ hide_default_connectors: "off"
12
+ font: "Noto Serif"
13
+ direction: "ltr"
14
+ reference: "Zufferey, Moeschler, and Reboul 2014"
15
+ ---
16
+ ```
17
+ [Types<>of<>meaning
18
+ [conventional
19
+ [semantic
20
+ [entailment]
21
+ [presupposition]
22
+ ]
23
+ [pragmatic
24
+ [conventional\
25
+ implicature]
26
+ ]
27
+ ]
28
+ [non\-conventional
29
+ [explicit
30
+ [explicature]
31
+ ]
32
+ [implicit
33
+ [conventional
34
+ [generalized\
35
+ implicature]
36
+ [particularized\
37
+ implicature]
38
+ ]
39
+ [non\-\
40
+ conventional
41
+ [pragmatic\
42
+ presupposition]
43
+ ]
44
+ ]
45
+ ]
46
+ ]
47
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: "059"
3
+ caption: "Major clause constructions of English (left-to-right)"
4
+ color: "off"
5
+ category: "Construction Grammar"
6
+ polyline: "on"
7
+ symmetrization: "off"
8
+ connector: "bar"
9
+ connector_height: "1.5"
10
+ linewidth: "1"
11
+ hide_default_connectors: "off"
12
+ font: "Noto Serif"
13
+ direction: "ltr"
14
+ reference: "Hoffmann 2022: 220"
15
+ ---
16
+ ```
17
+ [Major<>clause<>construction
18
+ [Declarative<>clause<>cxn
19
+ [*He<>was<>tired.*\
20
+ *He<>made<>mistakes.*]
21
+ ]
22
+ [Interrogative<>cxn
23
+ [Yes/No
24
+ [interrogative<>cxn
25
+ [*Was<>he<>tired?*\
26
+ *Did<>he<>make<>mistakes?*]
27
+ ]
28
+ ]
29
+ [WH\-interrogative<>cxn
30
+ [WH\-subject<>interrogative<>cxn
31
+ [*Who<>was<>tired?*]
32
+ ]
33
+ [WH\-nonsubject<>interrogative<>cxn
34
+ [*What<>was<>he?*\
35
+ *What<>did<>he<>make?*]
36
+ ]
37
+ ]
38
+ ]
39
+ [WH\-exclamative<>cxn
40
+ [*How<>tired<>he<>was!*\
41
+ *What<>mistakes<>he<>made!*]
42
+ ]
43
+ [Imperative<>cxn]
44
+ [Relative<>clause<>cxn
45
+ [WH\-subject<>relative<>clause<>cxn
46
+ [*The<>emails,<>which<>arrived<>overnight<>...*]
47
+ ]
48
+ [WH\-nonsubject<>relative<>clause<>cxn
49
+ [*A<>pilot<>shouldn't<>be<>tired,<>which<>Ben<>was.*\
50
+ *The<>mistakes<>that<>he<>made<>...*]
51
+ ]
52
+ ]
53
+ ]
54
+ ```
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: "060"
3
+ caption: "Conjunctive adjuncts: elaboration (left-to-right)"
4
+ color: "modern"
5
+ category: "Functional Grammar"
6
+ polyline: "on"
7
+ symmetrization: "off"
8
+ connector: "bar"
9
+ connector_height: "1.0"
10
+ linewidth: "1"
11
+ hide_default_connectors: "off"
12
+ font: "Noto Sans"
13
+ direction: "ltr"
14
+ reference: "Halliday (2014: 612-614)"
15
+ ---
16
+ ```
17
+ [conjunctive<>adjuncts
18
+ [elaboration
19
+ [apposition
20
+ [expository
21
+ [in<>other<>words\
22
+ that<>is<>(to<>say)\
23
+ I<>mean<>(to<>say)\
24
+ to<>put<>it<>another<>way]
25
+ ]
26
+ [exemplifying
27
+ [for<>example\
28
+ for<>instanace\
29
+ thus\
30
+ to<>illustrate]
31
+ ]
32
+ ]
33
+ [clarification
34
+ [corrective
35
+ [or<>rather\
36
+ at<>least\
37
+ to<>be<>more<>precise]
38
+ ]
39
+ [distractive
40
+ [by<>the<>way\
41
+ incidentally]
42
+ ]
43
+ [dismissive
44
+ [in<>any<>case\
45
+ anyway\
46
+ leaving<>that<>aside]
47
+ ]
48
+ [particularizing
49
+ [in<>particular\
50
+ more<>especially]
51
+ ]
52
+ [resumptive
53
+ [as<>I<>wasy<>saying\
54
+ to<>resume\
55
+ to<>get<>back<>to<>the<>point]
56
+ ]
57
+ [summative
58
+ [in<>short\
59
+ to<>sum<>up\
60
+ in<>conclusion\
61
+ briefly]
62
+ ]
63
+ [verifactive
64
+ [actually\
65
+ as<>a<>matter<>of<>fact\
66
+ in<>fact\
67
+ indeed]
68
+ ]
69
+ ]
70
+ ]
71
+ ]
72
+ ```
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: "061"
3
+ caption: "Conjunctive adjuncts: enhancement 1 (left-to-right)"
4
+ color: "modern"
5
+ category: "Functional Grammar"
6
+ polyline: "on"
7
+ symmetrization: "off"
8
+ connector: "bar"
9
+ connector_height: "1.0"
10
+ linewidth: "1"
11
+ hide_default_connectors: "off"
12
+ font: "Noto Sans"
13
+ direction: "ltr"
14
+ reference: "Halliday 2014: 612-614"
15
+ ---
16
+ ```
17
+ [conjunctive<>adjuncts
18
+ [enhancement<>(1)
19
+ [temporal
20
+ [simple
21
+ [following
22
+ [then\
23
+ next\
24
+ afterwards\
25
+ first<>...<>then]
26
+ ]
27
+ [simultaneous
28
+ [just<>then\
29
+ at<>the<>same<>time]
30
+ ]
31
+ [preceding
32
+ [before<>that\
33
+ hitherto\
34
+ previously]
35
+ ]
36
+ [conclusive
37
+ [in<>the<>end\
38
+ finally]
39
+ ]
40
+ ]
41
+ [complex
42
+ [immediate
43
+ [at<>once\
44
+ thereupon\
45
+ straightaway]
46
+ ]
47
+ [interrupted
48
+ [soon\
49
+ after<>a<>while]
50
+ ]
51
+ [repetitive
52
+ [next<>time\
53
+ on<>another<>occasion]
54
+ ]
55
+ [specific
56
+ [next<>day\
57
+ an<>hour<>later\
58
+ that<>morning]
59
+ ]
60
+ [durative
61
+ [meanwhile\
62
+ all<>that<>time]
63
+ ]
64
+ [terminal
65
+ [until<>then\
66
+ up<>to<>that<>point]
67
+ ]
68
+ [punctiliar
69
+ [at<>this<>point]
70
+ ]
71
+ ]
72
+ [simple<>internal
73
+ [following
74
+ [next\
75
+ secondly\
76
+ my<>next<>pooitn<>is\
77
+ first<>...<>next]
78
+ ]
79
+ [simultaneous
80
+ [at<>this<>point\
81
+ here\
82
+ now]
83
+ ]
84
+ [preceding
85
+ [hitherto\
86
+ up<>to<>now]
87
+ ]
88
+ [conclusive
89
+ [lastly\
90
+ last<>of<>all\
91
+ finally]
92
+ ]
93
+ ]
94
+ ]
95
+ ]
96
+ ]
97
+ ```