rsyntaxtree 1.3.2 → 1.4.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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +6 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +115 -52
- data/bin/rsyntaxtree +107 -19
- data/docs/_examples/054.md +22 -0
- data/docs/_examples/055.md +24 -0
- data/docs/_examples/056.md +27 -0
- data/docs/assets/img/054.png +0 -0
- data/docs/assets/img/055.png +0 -0
- data/docs/assets/img/056.png +0 -0
- data/docs/assets/svg/054.svg +50 -0
- data/docs/assets/svg/055.svg +53 -0
- data/docs/assets/svg/056.svg +73 -0
- data/docs/documentation.md +89 -0
- data/docs/documentation_ja.md +90 -1
- data/lib/rsyntaxtree/base_graph.rb +5 -5
- data/lib/rsyntaxtree/element.rb +3 -2
- data/lib/rsyntaxtree/elementlist.rb +3 -5
- data/lib/rsyntaxtree/format_converter.rb +65 -0
- data/lib/rsyntaxtree/markup_parser.rb +13 -2
- data/lib/rsyntaxtree/string_parser.rb +1 -1
- data/lib/rsyntaxtree/svg_graph.rb +9 -2
- data/lib/rsyntaxtree/tikz_generator.rb +131 -0
- data/lib/rsyntaxtree/utils.rb +1 -1
- data/lib/rsyntaxtree/version.rb +1 -1
- data/lib/rsyntaxtree.rb +42 -24
- data/rsyntaxtree.gemspec +2 -0
- data/syntree.svg +41 -0
- data/test/cli_test.rb +262 -0
- data/test/format_converter_test.rb +129 -0
- data/test/node_styling_test.rb +239 -0
- data/test/tikz_test.rb +89 -0
- metadata +51 -6
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
3
|
+
<svg width="359.2" height="605.25" viewBox="-15.200000000000001, 0, 374.4, 616.5" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<defs>
|
|
5
|
+
<marker id="arrow" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
6
|
+
<path d="M 0 0 L 10 5 L 0 10" fill="#CC79A7"/>
|
|
7
|
+
</marker>
|
|
8
|
+
<marker id="arrowBackward" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
9
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#CC79A7"/>
|
|
10
|
+
</marker>
|
|
11
|
+
<marker id="arrowForward" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
12
|
+
<path d="M 10 0 L 0 5 L 10 10 z" fill="#CC79A7"/>
|
|
13
|
+
</marker>
|
|
14
|
+
<marker id="arrowBothways" markerUnits="userSpaceOnUse" viewBox="0 0 30 10" refX="15" refY="5" markerWidth="45.6" markerHeight="15.200000000000001" orient="auto">
|
|
15
|
+
<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="#CC79A7"/>
|
|
16
|
+
</marker>
|
|
17
|
+
<pattern id="hatchBlack" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
18
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="black" stroke-width="4"></line>
|
|
19
|
+
</pattern>
|
|
20
|
+
<pattern id="hatchForNode" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
21
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="#0072B2" stroke-width="4"></line>
|
|
22
|
+
</pattern>
|
|
23
|
+
<pattern id="hatchForLeaf" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
24
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="#009E73" stroke-width="4"></line>
|
|
25
|
+
</pattern>
|
|
26
|
+
</defs>
|
|
27
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='180.2' y='67.5'><tspan x='180.2' y='67.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">S</tspan>
|
|
28
|
+
</text>
|
|
29
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='75.09999999999998' y='238.5'><tspan x='75.09999999999998' y='238.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">NP</tspan>
|
|
30
|
+
</text>
|
|
31
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='15.199999999999989' y='409.5'><tspan x='15.199999999999989' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">Det</tspan>
|
|
32
|
+
</text>
|
|
33
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #E63946; storoke-width: 0; font-size: 32px;' x='16.69999999999999' y='580.5'><tspan x='16.69999999999999' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">the</tspan>
|
|
34
|
+
</text>
|
|
35
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='139.5' y='409.5'><tspan x='139.5' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">N</tspan>
|
|
36
|
+
</text>
|
|
37
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #457B9D; storoke-width: 0; font-size: 32px;' x='129.0' y='580.5'><tspan x='129.0' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">cat</tspan>
|
|
38
|
+
</text>
|
|
39
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='262.8' y='238.5'><tspan x='262.8' y='238.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">VP</tspan>
|
|
40
|
+
</text>
|
|
41
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='271.8' y='409.5'><tspan x='271.8' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">V</tspan>
|
|
42
|
+
</text>
|
|
43
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #2A9D8F; storoke-width: 0; font-size: 32px;' x='234.8' y='580.5'><tspan x='234.8' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">sleeps</tspan>
|
|
44
|
+
</text>
|
|
45
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='96.59999999999998' y1='182.25' x2='189.2' y2='95.625' />
|
|
46
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='281.8' y1='182.25' x2='189.2' y2='95.625' />
|
|
47
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='41.69999999999999' y1='353.25' x2='96.59999999999998' y2='266.625' />
|
|
48
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='151.5' y1='353.25' x2='96.59999999999998' y2='266.625' />
|
|
49
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='41.69999999999999' y1='524.25' x2='41.69999999999999' y2='437.625' />
|
|
50
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='151.5' y1='524.25' x2='151.5' y2='437.625' />
|
|
51
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='281.8' y1='353.25' x2='281.8' y2='266.625' />
|
|
52
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='281.8' y1='524.25' x2='281.8' y2='437.625' />
|
|
53
|
+
</svg>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
3
|
+
<svg width="912.0000000000001" height="776.25" viewBox="-15.200000000000001, 0, 927.2000000000002, 787.5" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<defs>
|
|
5
|
+
<marker id="arrow" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
6
|
+
<path d="M 0 0 L 10 5 L 0 10" fill="#CC79A7"/>
|
|
7
|
+
</marker>
|
|
8
|
+
<marker id="arrowBackward" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
9
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#CC79A7"/>
|
|
10
|
+
</marker>
|
|
11
|
+
<marker id="arrowForward" markerUnits="userSpaceOnUse" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="15.200000000000001" markerHeight="15.200000000000001" orient="auto">
|
|
12
|
+
<path d="M 10 0 L 0 5 L 10 10 z" fill="#CC79A7"/>
|
|
13
|
+
</marker>
|
|
14
|
+
<marker id="arrowBothways" markerUnits="userSpaceOnUse" viewBox="0 0 30 10" refX="15" refY="5" markerWidth="45.6" markerHeight="15.200000000000001" orient="auto">
|
|
15
|
+
<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="#CC79A7"/>
|
|
16
|
+
</marker>
|
|
17
|
+
<pattern id="hatchBlack" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
18
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="black" stroke-width="4"></line>
|
|
19
|
+
</pattern>
|
|
20
|
+
<pattern id="hatchForNode" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
21
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="#0072B2" stroke-width="4"></line>
|
|
22
|
+
</pattern>
|
|
23
|
+
<pattern id="hatchForLeaf" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
24
|
+
<line x1="0" y="0" x2="0" y2="10" stroke="#009E73" stroke-width="4"></line>
|
|
25
|
+
</pattern>
|
|
26
|
+
</defs>
|
|
27
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='362.90000000000003' y='67.5'><tspan x='362.90000000000003' y='67.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">S</tspan>
|
|
28
|
+
</text>
|
|
29
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: red; storoke-width: 0; font-size: 32px;' x='156.20000000000002' y='238.5'><tspan x='156.20000000000002' y='238.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">NP</tspan>
|
|
30
|
+
</text>
|
|
31
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: blue; storoke-width: 0; font-size: 32px;' x='165.70000000000002' y='409.5'><tspan x='165.70000000000002' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">N</tspan>
|
|
32
|
+
</text>
|
|
33
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #009E73; storoke-width: 0; font-size: 32px;' x='15.199999999999989' y='580.5'><tspan x='15.199999999999989' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">the<tspan style='fill:none;'>■</tspan>quick<tspan style='fill:none;'>■</tspan>brown<tspan style='fill:none;'>■</tspan>fox</tspan>
|
|
34
|
+
</text>
|
|
35
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: green; storoke-width: 0; font-size: 32px;' x='547.1000000000001' y='238.5'><tspan x='547.1000000000001' y='238.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">VP</tspan>
|
|
36
|
+
</text>
|
|
37
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='437.50000000000006' y='409.5'><tspan x='437.50000000000006' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">V</tspan>
|
|
38
|
+
</text>
|
|
39
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #009E73; storoke-width: 0; font-size: 32px;' x='401.00000000000006' y='580.5'><tspan x='401.00000000000006' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">jumps</tspan>
|
|
40
|
+
</text>
|
|
41
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='665.7' y='409.5'><tspan x='665.7' y='409.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">PP</tspan>
|
|
42
|
+
</text>
|
|
43
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #0072B2; storoke-width: 0; font-size: 32px;' x='578.3000000000001' y='580.5'><tspan x='578.3000000000001' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">P</tspan>
|
|
44
|
+
</text>
|
|
45
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #009E73; storoke-width: 0; font-size: 32px;' x='554.8000000000001' y='751.5'><tspan x='554.8000000000001' y='751.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">over</tspan>
|
|
46
|
+
</text>
|
|
47
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: purple; storoke-width: 0; font-size: 32px;' x='760.1000000000001' y='580.5'><tspan x='760.1000000000001' y='580.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">NP</tspan>
|
|
48
|
+
</text>
|
|
49
|
+
<text white-space='pre' alignment-baseline='text-top' style='fill: #009E73; storoke-width: 0; font-size: 32px;' x='681.6000000000001' y='751.5'><tspan x='681.6000000000001' y='751.5' style="" text-decoration="" font-family="'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif">the<tspan style='fill:none;'>■</tspan>lazy<tspan style='fill:none;'>■</tspan>dog</tspan>
|
|
50
|
+
</text>
|
|
51
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='177.70000000000002' y1='182.25' x2='371.90000000000003' y2='95.625' />
|
|
52
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='566.1000000000001' y1='182.25' x2='371.90000000000003' y2='95.625' />
|
|
53
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='177.70000000000002' y1='353.25' x2='177.70000000000002' y2='266.625' />
|
|
54
|
+
<polygon style='fill: none; stroke: black; stroke-width:2; stroke-linejoin:round;stroke-linecap:round;' points='15.199999999999989 524.25 340.2 524.25 177.70000000000002 437.625' />
|
|
55
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='447.50000000000006' y1='353.25' x2='566.1000000000001' y2='266.625' />
|
|
56
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='684.7' y1='353.25' x2='566.1000000000001' y2='266.625' />
|
|
57
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='447.50000000000006' y1='524.25' x2='447.50000000000006' y2='437.625' />
|
|
58
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='587.8000000000001' y1='524.25' x2='684.7' y2='437.625' />
|
|
59
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='781.6000000000001' y1='524.25' x2='684.7' y2='437.625' />
|
|
60
|
+
<line style='fill: none; stroke:black; stroke-width:2; stroke-linejoin:round; stroke-linecap:round;' x1='587.8000000000001' y1='695.25' x2='587.8000000000001' y2='608.625' />
|
|
61
|
+
<polygon style='fill: none; stroke: black; stroke-width:2; stroke-linejoin:round;stroke-linecap:round;' points='681.6000000000001 695.25 881.6000000000001 695.25 781.6000000000001 608.625' />
|
|
62
|
+
<polyline style='stroke:red; stroke-width:2; fill:none; stroke-linejoin:round; stroke-linecap:round;'
|
|
63
|
+
points='156.20000000000002,187.875 148.60000000000002,187.875 148.60000000000002,261.0 156.20000000000002,261.0' />
|
|
64
|
+
|
|
65
|
+
<polyline style='stroke:red; stroke-width:2; fill:none; stroke-linejoin:round; stroke-linecap:round;'
|
|
66
|
+
points='199.20000000000002,187.875 206.8,187.875 206.8,261.0 199.20000000000002,261.0' />
|
|
67
|
+
|
|
68
|
+
<polyline style='stroke:green; stroke-width:2; fill:none; stroke-linejoin:round; stroke-linecap:round;'
|
|
69
|
+
points='547.1000000000001,187.875 539.5000000000001,187.875 539.5000000000001,261.0 547.1000000000001,261.0' />
|
|
70
|
+
|
|
71
|
+
<polyline style='stroke:green; stroke-width:2; fill:none; stroke-linejoin:round; stroke-linecap:round;'
|
|
72
|
+
points='585.1000000000001,187.875 592.7000000000002,187.875 592.7000000000002,261.0 585.1000000000001,261.0' />
|
|
73
|
+
</svg>
|
data/docs/documentation.md
CHANGED
|
@@ -121,6 +121,25 @@ If `##` is placed at the beginning of the leaf text, a rectangle is drawn instea
|
|
|
121
121
|
|
|
122
122
|
If `###` is placed at the beginning of the leaf text, a rectangle with thicker lines is drawn.
|
|
123
123
|
|
|
124
|
+
### Per-Node Styling (Color)
|
|
125
|
+
|
|
126
|
+
You can specify a custom color for individual nodes using the `@color:` prefix. Both named colors and hex color codes are supported.
|
|
127
|
+
|
|
128
|
+
|Sample Input|Description|
|
|
129
|
+
|------------|-----------|
|
|
130
|
+
|`@red:NP`|Named color (red)|
|
|
131
|
+
|`@blue:VP`|Named color (blue)|
|
|
132
|
+
|`@#FF5500:NP`|Hex color code|
|
|
133
|
+
|`@#0A0:VP`|Short hex color code|
|
|
134
|
+
|
|
135
|
+
**Markup Order**: When combining with other prefixes, use this order: `^` (triangle) → `#` (enclosure) → `@color:` (color)
|
|
136
|
+
|
|
137
|
+
|Sample Input|Description|
|
|
138
|
+
|------------|-----------|
|
|
139
|
+
|`^@blue:NP`|Triangle connector + blue color|
|
|
140
|
+
|`#@red:NP`|Square brackets + red color|
|
|
141
|
+
|`^#@green:NP`|Triangle + brackets + green color|
|
|
142
|
+
|
|
124
143
|
### Escape Special Characters
|
|
125
144
|
|
|
126
145
|
The backslash character `\` must be used to print certain characters used in the markup. If you do not have the `\` key on your keyboard, you can also use the yen/yuan character `¥` to escape.
|
|
@@ -153,6 +172,76 @@ Each additional connectors is distinguished by an ID number. The ID is specified
|
|
|
153
172
|
|
|
154
173
|
A node can have any number of IDs. The same ID must appear in the text of the *two* nodes between which the additional connector is rendered. The same ID number cannot appear in more than two places.
|
|
155
174
|
|
|
175
|
+
### Command Line Interface Features
|
|
176
|
+
|
|
177
|
+
The following features are available only in the command-line interface.
|
|
178
|
+
|
|
179
|
+
#### Penn Treebank Format
|
|
180
|
+
|
|
181
|
+
RSyntaxTree automatically detects and converts Penn Treebank format to bracket notation:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
# Penn Treebank format
|
|
185
|
+
(S (NP the dog) (VP runs))
|
|
186
|
+
|
|
187
|
+
# Equivalent bracket notation
|
|
188
|
+
[S [NP the dog] [VP runs]]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Escaping special characters in Penn Treebank format:**
|
|
192
|
+
|
|
193
|
+
| Input | Displayed as |
|
|
194
|
+
|-------|--------------|
|
|
195
|
+
| `\(` `\)` | Parentheses `()` as literal text |
|
|
196
|
+
| `\[` `\]` | Square brackets `[]` as literal text |
|
|
197
|
+
|
|
198
|
+
Example:
|
|
199
|
+
```
|
|
200
|
+
(S (NP hello\(world\)) (VP test))
|
|
201
|
+
→ [S [NP hello(world)] [VP test]]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### Standard Input Support
|
|
205
|
+
|
|
206
|
+
You can pipe tree data via standard input:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
echo "[S [NP hello] [VP world]]" | rsyntaxtree -f svg -o ./
|
|
210
|
+
cat tree.txt | rsyntaxtree -f png -o ./
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Configuration File
|
|
214
|
+
|
|
215
|
+
Create a `.rsyntaxtreerc` file in your home directory or current directory to set default options:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
# ~/.rsyntaxtreerc
|
|
219
|
+
format: svg
|
|
220
|
+
color: modern
|
|
221
|
+
fontsize: 18
|
|
222
|
+
leafstyle: auto
|
|
223
|
+
symmetrize: off
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
CLI arguments override configuration file settings. Unknown options in the config file will generate warnings, and invalid values will cause errors with helpful messages.
|
|
227
|
+
|
|
228
|
+
#### TikZ Output
|
|
229
|
+
|
|
230
|
+
RSyntaxTree can generate TikZ/forest code for LaTeX documents using the `-f tikz` option. The output can be used directly in LaTeX with the `forest` package.
|
|
231
|
+
|
|
232
|
+
**Limitations:** The TikZ output focuses on tree structure and does not support the following visual features:
|
|
233
|
+
|
|
234
|
+
| Feature | TikZ Support |
|
|
235
|
+
|---------|--------------|
|
|
236
|
+
| Per-node coloring (`@color:`) | Not supported |
|
|
237
|
+
| Enclosures (`#`, `##`) | Not supported |
|
|
238
|
+
| Triangle connectors (`^`) | Not supported |
|
|
239
|
+
| Text decoration (bold, italic) | Not supported |
|
|
240
|
+
| Subscript/superscript (`_x_`, `__x__`) | Not supported |
|
|
241
|
+
| Path drawing (`+1`, `+>1`) | Not supported |
|
|
242
|
+
|
|
243
|
+
Users familiar with LaTeX can manually add these features to the generated TikZ code using standard LaTeX commands (e.g., `\textcolor{red}{NP}`, `\textbf{...}`).
|
|
244
|
+
|
|
156
245
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
|
|
157
246
|
<script src="https://cdn.jsdelivr.net/npm/lightbox2@2.11.3/src/js/lightbox.js"></script>
|
|
158
247
|
|
data/docs/documentation_ja.md
CHANGED
|
@@ -123,12 +123,31 @@ SVG形式を用いる場合,期待通りの表示を得るためには,ご
|
|
|
123
123
|
|
|
124
124
|
### リーフを囲む括弧と矩形の描画
|
|
125
125
|
|
|
126
|
-
ラベルまたはリーフとなるテキストの最初に(`^` が存在する場合はその直後に) `#` を付けると,そのテキスト全体を角括弧([ ])で囲みます(例:`[#NP text]`, `[NP #text]`, `[NP ^#text]`).
|
|
126
|
+
ラベルまたはリーフとなるテキストの最初に(`^` が存在する場合はその直後に) `#` を付けると,そのテキスト全体を角括弧([ ])で囲みます(例:`[#NP text]`, `[NP #text]`, `[NP ^#text]`).
|
|
127
127
|
|
|
128
128
|
テキストの最初に `##` を付けると,テキスト全体を矩形(ボックス)で囲みます.
|
|
129
129
|
|
|
130
130
|
テキストの最初に `###` を付けると,テキスト全体を太い線の矩形(ボックス)で囲みます.
|
|
131
131
|
|
|
132
|
+
### ノードごとの色指定
|
|
133
|
+
|
|
134
|
+
`@color:` プレフィックスを使用して,個々のノードにカスタムカラーを指定できます.色名とHEXカラーコードの両方がサポートされています.
|
|
135
|
+
|
|
136
|
+
|入力例|説明|
|
|
137
|
+
|------------|-----------|
|
|
138
|
+
|`@red:NP`|色名(赤)|
|
|
139
|
+
|`@blue:VP`|色名(青)|
|
|
140
|
+
|`@#FF5500:NP`|HEXカラーコード|
|
|
141
|
+
|`@#0A0:VP`|短縮形HEXカラーコード|
|
|
142
|
+
|
|
143
|
+
**マークアップの順序**:他のプレフィックスと組み合わせる場合は,次の順序を使用してください:`^`(三角形)→ `#`(囲み)→ `@color:`(色)
|
|
144
|
+
|
|
145
|
+
|入力例|説明|
|
|
146
|
+
|------------|-----------|
|
|
147
|
+
|`^@blue:NP`|三角形コネクター+青色|
|
|
148
|
+
|`#@red:NP`|角括弧+赤色|
|
|
149
|
+
|`^#@green:NP`|三角形+角括弧+緑色|
|
|
150
|
+
|
|
132
151
|
### 一部の文字を表示するためのエスケープ
|
|
133
152
|
|
|
134
153
|
文字装飾などのマークアップに使用される一部の文字をテキストとして表示するためには `\` によってエスケープする必要があります.使用している環境で `\` が使えない場合は `¥` で代用することができます.
|
|
@@ -164,6 +183,76 @@ IDにはどのような数字を用いても構いませんが,必ず **2箇
|
|
|
164
183
|
|
|
165
184
|
IDにはどのような数字を用いても構いませんが,必ず **2箇所** で同じIDを指定することが必要です.同じIDを3箇所以上で指定することはできません.
|
|
166
185
|
|
|
186
|
+
### コマンドラインインターフェースの機能
|
|
187
|
+
|
|
188
|
+
以下の機能はコマンドラインインターフェースでのみ利用可能です.
|
|
189
|
+
|
|
190
|
+
#### Penn Treebank形式
|
|
191
|
+
|
|
192
|
+
RSyntaxTreeはPenn Treebank形式を自動的に検出し,括弧表記に変換します:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
# Penn Treebank形式
|
|
196
|
+
(S (NP the dog) (VP runs))
|
|
197
|
+
|
|
198
|
+
# 同等の括弧表記
|
|
199
|
+
[S [NP the dog] [VP runs]]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Penn Treebank形式での特殊文字のエスケープ:**
|
|
203
|
+
|
|
204
|
+
| 入力 | 表示 |
|
|
205
|
+
|------|------|
|
|
206
|
+
| `\(` `\)` | 丸括弧 `()` をそのまま表示 |
|
|
207
|
+
| `\[` `\]` | 角括弧 `[]` をそのまま表示 |
|
|
208
|
+
|
|
209
|
+
例:
|
|
210
|
+
```
|
|
211
|
+
(S (NP hello\(world\)) (VP test))
|
|
212
|
+
→ [S [NP hello(world)] [VP test]]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### 標準入力のサポート
|
|
216
|
+
|
|
217
|
+
パイプを使って標準入力からツリーデータを渡すことができます:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
echo "[S [NP hello] [VP world]]" | rsyntaxtree -f svg -o ./
|
|
221
|
+
cat tree.txt | rsyntaxtree -f png -o ./
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### 設定ファイル
|
|
225
|
+
|
|
226
|
+
ホームディレクトリまたはカレントディレクトリに `.rsyntaxtreerc` ファイルを作成して,デフォルトオプションを設定できます:
|
|
227
|
+
|
|
228
|
+
```yaml
|
|
229
|
+
# ~/.rsyntaxtreerc
|
|
230
|
+
format: svg
|
|
231
|
+
color: modern
|
|
232
|
+
fontsize: 18
|
|
233
|
+
leafstyle: auto
|
|
234
|
+
symmetrize: off
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
コマンドライン引数は設定ファイルの設定を上書きします.設定ファイル内の不明なオプションは警告を生成し,無効な値はエラーメッセージを表示します.
|
|
238
|
+
|
|
239
|
+
#### TikZ出力
|
|
240
|
+
|
|
241
|
+
RSyntaxTreeは`-f tikz`オプションを使用してLaTeXドキュメント用のTikZ/forestコードを生成できます.出力は`forest`パッケージを使用してLaTeXで直接使用できます.
|
|
242
|
+
|
|
243
|
+
**制限事項:** TikZ出力はツリー構造に焦点を当てており,以下の視覚的機能はサポートされていません:
|
|
244
|
+
|
|
245
|
+
| 機能 | TikZサポート |
|
|
246
|
+
|------|--------------|
|
|
247
|
+
| ノード別カラー指定(`@color:`) | 非対応 |
|
|
248
|
+
| 囲み(`#`,`##`) | 非対応 |
|
|
249
|
+
| 三角形コネクタ(`^`) | 非対応 |
|
|
250
|
+
| テキスト装飾(太字,斜体) | 非対応 |
|
|
251
|
+
| 下付き・上付き文字(`_x_`,`__x__`) | 非対応 |
|
|
252
|
+
| パス描画(`+1`,`+>1`) | 非対応 |
|
|
253
|
+
|
|
254
|
+
LaTeXに精通しているユーザーは,標準的なLaTeXコマンド(例:`\textcolor{red}{NP}`,`\textbf{...}`)を使用して,生成されたTikZコードにこれらの機能を手動で追加できます.
|
|
255
|
+
|
|
167
256
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
|
|
168
257
|
<script src="https://cdn.jsdelivr.net/npm/lightbox2@2.11.3/src/js/lightbox.js"></script>
|
|
169
258
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#==========================
|
|
6
6
|
#
|
|
7
7
|
# Image utility functions to inspect text font metrics
|
|
8
|
-
# Copyright (c) 2007-
|
|
8
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
9
9
|
|
|
10
10
|
require_relative 'utils'
|
|
11
11
|
|
|
@@ -44,7 +44,7 @@ module RSyntaxTree
|
|
|
44
44
|
@col_bg = "none"
|
|
45
45
|
@col_fg = "black"
|
|
46
46
|
|
|
47
|
-
@col_line = if params[:hide_default_connectors]
|
|
47
|
+
@col_line = if params[:hide_default_connectors] == true
|
|
48
48
|
"none"
|
|
49
49
|
else
|
|
50
50
|
"black"
|
|
@@ -188,19 +188,19 @@ module RSyntaxTree
|
|
|
188
188
|
child = children[0]
|
|
189
189
|
case @leafstyle
|
|
190
190
|
when "auto"
|
|
191
|
-
if
|
|
191
|
+
if parent.triangle || child.contains_phrase
|
|
192
192
|
triangle_to_parent(parent, child)
|
|
193
193
|
else
|
|
194
194
|
line_to_parent(parent, child)
|
|
195
195
|
end
|
|
196
196
|
when "bar"
|
|
197
|
-
if
|
|
197
|
+
if parent.triangle
|
|
198
198
|
triangle_to_parent(parent, child)
|
|
199
199
|
else
|
|
200
200
|
line_to_parent(parent, child)
|
|
201
201
|
end
|
|
202
202
|
when "nothing", "none"
|
|
203
|
-
if
|
|
203
|
+
if parent.triangle
|
|
204
204
|
triangle_to_parent(parent, child)
|
|
205
205
|
elsif ETYPE_LEAF != child.type
|
|
206
206
|
line_to_parent(parent, child)
|
data/lib/rsyntaxtree/element.rb
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
#==========================
|
|
6
6
|
#
|
|
7
7
|
# Aa class that represents a basic tree element, either node or leaf.
|
|
8
|
-
# Copyright (c) 2007-
|
|
8
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
9
9
|
|
|
10
10
|
require_relative "markup_parser"
|
|
11
11
|
require_relative "utils"
|
|
12
12
|
|
|
13
13
|
module RSyntaxTree
|
|
14
14
|
class Element
|
|
15
|
-
attr_accessor :id, :parent, :type, :level, :width, :height, :content, :content_width, :content_height, :horizontal_indent, :vertical_indent, :triangle, :enclosure, :children, :font, :fontsize, :contains_phrase, :path
|
|
15
|
+
attr_accessor :id, :parent, :type, :level, :width, :height, :content, :content_width, :content_height, :horizontal_indent, :vertical_indent, :triangle, :enclosure, :children, :font, :fontsize, :contains_phrase, :path, :color
|
|
16
16
|
|
|
17
17
|
def initialize(id, parent, content, level, fontset, fontsize, global)
|
|
18
18
|
@global = global
|
|
@@ -49,6 +49,7 @@ module RSyntaxTree
|
|
|
49
49
|
@paths = results[:paths]
|
|
50
50
|
@enclosure = results[:enclosure]
|
|
51
51
|
@triangle = results[:triangle]
|
|
52
|
+
@color = results[:color]
|
|
52
53
|
|
|
53
54
|
@contains_phrase = false
|
|
54
55
|
setup
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#==========================
|
|
6
6
|
#
|
|
7
7
|
# Contains a list of unordered tree elements with a defined parent
|
|
8
|
-
# Copyright (c) 2007-
|
|
8
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
9
9
|
|
|
10
10
|
require_relative "element"
|
|
11
11
|
|
|
@@ -33,7 +33,7 @@ module RSyntaxTree
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def get_first
|
|
36
|
-
return nil if @elements.
|
|
36
|
+
return nil if @elements.empty?
|
|
37
37
|
|
|
38
38
|
@iterator = 0
|
|
39
39
|
@elements[@iterator]
|
|
@@ -41,9 +41,7 @@ module RSyntaxTree
|
|
|
41
41
|
|
|
42
42
|
def get_next
|
|
43
43
|
@iterator += 1
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
nil
|
|
44
|
+
@elements[@iterator]
|
|
47
45
|
end
|
|
48
46
|
|
|
49
47
|
def get_id(id)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#==========================
|
|
4
|
+
# format_converter.rb
|
|
5
|
+
#==========================
|
|
6
|
+
#
|
|
7
|
+
# Converts various tree notation formats to RSyntaxTree's bracket notation
|
|
8
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
9
|
+
|
|
10
|
+
module RSyntaxTree
|
|
11
|
+
module FormatConverter
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# Detect the format of the input string
|
|
15
|
+
# @param text [String] the input tree notation
|
|
16
|
+
# @return [Symbol] :penn or :bracket
|
|
17
|
+
def detect_format(text)
|
|
18
|
+
stripped = text.strip
|
|
19
|
+
if stripped.start_with?('(') && !stripped.start_with?('([')
|
|
20
|
+
:penn
|
|
21
|
+
else
|
|
22
|
+
:bracket
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Convert any supported format to bracket notation
|
|
27
|
+
# @param text [String] the input tree notation
|
|
28
|
+
# @return [String] bracket notation
|
|
29
|
+
def to_bracket(text)
|
|
30
|
+
case detect_format(text)
|
|
31
|
+
when :penn
|
|
32
|
+
penn_to_bracket(text)
|
|
33
|
+
else
|
|
34
|
+
text
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Convert Penn TreeBank format to bracket notation
|
|
39
|
+
# Penn: (S (NP hello) (VP world))
|
|
40
|
+
# Bracket: [S [NP hello] [VP world]]
|
|
41
|
+
# Use \( and \) to include literal parentheses in text
|
|
42
|
+
# @param text [String] Penn TreeBank notation
|
|
43
|
+
# @return [String] bracket notation
|
|
44
|
+
def penn_to_bracket(text)
|
|
45
|
+
# Normalize whitespace (collapse multiple spaces/newlines to single space)
|
|
46
|
+
normalized = text.gsub(/\s+/, ' ').strip
|
|
47
|
+
|
|
48
|
+
# Protect escaped parentheses with placeholders
|
|
49
|
+
result = normalized.gsub('\(', "\x00LPAREN\x00").gsub('\)', "\x00RPAREN\x00")
|
|
50
|
+
|
|
51
|
+
# Replace structural parentheses with brackets
|
|
52
|
+
result = result.gsub('(', '[').gsub(')', ']')
|
|
53
|
+
|
|
54
|
+
# Restore escaped parentheses as literal parentheses
|
|
55
|
+
result = result.gsub("\x00LPAREN\x00", '(').gsub("\x00RPAREN\x00", ')')
|
|
56
|
+
|
|
57
|
+
# Clean up extra spaces after opening brackets
|
|
58
|
+
result = result.gsub(/\[\s+/, '[')
|
|
59
|
+
# Clean up extra spaces before closing brackets
|
|
60
|
+
result = result.gsub(/\s+\]/, ']')
|
|
61
|
+
|
|
62
|
+
result
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -13,6 +13,11 @@ class MarkupParser < Parslet::Parser
|
|
|
13
13
|
rule(:brackets) { str('#') }
|
|
14
14
|
rule(:triangle) { str('^') }
|
|
15
15
|
|
|
16
|
+
# Color specification: @colorname: or @#hexcode:
|
|
17
|
+
rule(:color_name) { match('[a-zA-Z]').repeat(1) }
|
|
18
|
+
rule(:color_hex) { str('#') >> match('[0-9a-fA-F]').repeat(3, 6) }
|
|
19
|
+
rule(:color_spec) { str('@') >> (color_hex | color_name).as(:color_value) >> str(':') }
|
|
20
|
+
|
|
16
21
|
rule(:path) { (str('+') >> str('-').maybe >> (str('>') | str('<')).maybe >> match('\d').repeat(1)).as(:path) }
|
|
17
22
|
# rule(:escaped) { str('\\') >> match('[#<>{}\\^+*_=~\|\n\-]').as(:chr) }
|
|
18
23
|
rule(:escaped) { str('\\') >> match('[#<>{}\\\\^+*_=~\\|\\n\\-\\[\\]]').as(:chr) }
|
|
@@ -51,7 +56,7 @@ class MarkupParser < Parslet::Parser
|
|
|
51
56
|
rule(:markup) { (text | decoration | shape | bstroke) }
|
|
52
57
|
|
|
53
58
|
rule(:line) { (cr.as(:extracr) | border | bborder | markup.repeat(1).as(:line) >> (cr | eof | str('+').present?)) }
|
|
54
|
-
rule(:lines) { triangle.maybe.as(:triangle) >> (brectangle | rectangle | brackets).maybe.as(:enclosure) >> line.repeat(1) >> path.repeat(0).as(:paths) >> (cr | eof) }
|
|
59
|
+
rule(:lines) { triangle.maybe.as(:triangle) >> (brectangle | rectangle | brackets).maybe.as(:enclosure) >> color_spec.maybe.as(:color) >> line.repeat(1) >> path.repeat(0).as(:paths) >> (cr | eof) }
|
|
55
60
|
root :lines
|
|
56
61
|
end
|
|
57
62
|
|
|
@@ -171,7 +176,7 @@ module Markup
|
|
|
171
176
|
|
|
172
177
|
applied = @evaluator.apply(parsed)
|
|
173
178
|
|
|
174
|
-
results = { enclosure: :none, triangle: false, paths: [], contents: [] }
|
|
179
|
+
results = { enclosure: :none, triangle: false, paths: [], contents: [], color: nil }
|
|
175
180
|
applied.each do |h|
|
|
176
181
|
if h[:enclosure]
|
|
177
182
|
results[:enclosure] = case h[:enclosure].to_s
|
|
@@ -187,6 +192,12 @@ module Markup
|
|
|
187
192
|
end
|
|
188
193
|
results[:triangle] = h[:triangle].to_s == '^' if h[:triangle]
|
|
189
194
|
results[:paths] = h[:paths] if h[:paths]
|
|
195
|
+
# Handle color specification
|
|
196
|
+
if h[:color] && h[:color][:color_value]
|
|
197
|
+
color_value = h[:color][:color_value].to_s
|
|
198
|
+
# Prepend # if it's a hex color without it (parser captures just the hex part after #)
|
|
199
|
+
results[:color] = color_value
|
|
200
|
+
end
|
|
190
201
|
results[:contents] << h if h[:type] == :text || h[:type] == :border || h[:type] == :bborder
|
|
191
202
|
end
|
|
192
203
|
{ status: :success, results: results }
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
#
|
|
7
7
|
# Parses a phrase into leafs and nodes and store the result in an element list
|
|
8
8
|
# (see element_list.rb)
|
|
9
|
-
# Copyright (c) 2007-
|
|
9
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
10
10
|
|
|
11
11
|
require_relative 'elementlist'
|
|
12
12
|
require_relative 'element'
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#==========================
|
|
6
6
|
#
|
|
7
7
|
# Parses an element list into an SVG tree.
|
|
8
|
-
# Copyright (c) 2007-
|
|
8
|
+
# Copyright (c) 2007-2026 Yoichiro Hasebe <yohasebe@gmail.com>
|
|
9
9
|
|
|
10
10
|
# No tempfile usage in this file
|
|
11
11
|
require_relative 'base_graph'
|
|
@@ -149,7 +149,10 @@ module RSyntaxTree
|
|
|
149
149
|
right = left + element.content_width
|
|
150
150
|
txt_pos = left + (right - left) / 2
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
# Use element's custom color if specified, otherwise use default based on type
|
|
153
|
+
col = if element.color
|
|
154
|
+
element.color
|
|
155
|
+
elsif element.type == ETYPE_LEAF
|
|
153
156
|
@col_leaf
|
|
154
157
|
else
|
|
155
158
|
@col_node
|
|
@@ -444,7 +447,11 @@ module RSyntaxTree
|
|
|
444
447
|
|
|
445
448
|
path_flags.uniq.each do |k|
|
|
446
449
|
targets = path_pool_target[k]
|
|
450
|
+
next if targets.nil? || targets.empty?
|
|
451
|
+
|
|
447
452
|
fst = targets.shift
|
|
453
|
+
next if fst.nil?
|
|
454
|
+
|
|
448
455
|
targets.each do |t|
|
|
449
456
|
paths << { x1: fst[0], y1: fst[1], x2: t[0], y2: t[1], arrow: :double }
|
|
450
457
|
end
|