syntax_tree 1.2.0 → 2.1.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.
data/doc/logo.svg ADDED
@@ -0,0 +1,284 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 10 700 520" width="700" height="510">
4
+ <path fill="black">
5
+ <animate
6
+ attributeName="d"
7
+ values="
8
+ M 350, 700 l 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 z;
9
+ M 346, 700 l 8, 0 c 10, -20, 20, -50, 15, -80 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c -5, 10, -10, 50, -40, 80 z ;
10
+ M 340, 700 l 20, 0 c 30, -100, 30, -150, 10, -200 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 10, 50, -10, 150, -50, 200 z ;
11
+ M 338, 700 l 24, 0 c 50, -150, 10, -160, 0, -300 c 0, -30, 0, -60, 5, -65 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q -3, 0, -6, 10 c 0, -30, 0, -40, -2, -50 q 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 q 0, 0, 0, 0 c 0, 10, -5, 10, -5, 20 c -5, -5, -5, 0, -10, -5 c 0, 0, 0, 0, 0, 0 c 10, 50, 60, 300, -35, 390 z ;
12
+ M 335, 700 l 30, 0 c 50, -150, 10, -160, 0, -300 c 0, -50, 0, -80, 20, -80 c 0, 0, 0, 0, 0, 0 c 0, 0, 0, 0, 0, 0 q 0, 0, 0, 0 q -10, 0, -20, 10 c 0, -30, -20, -70, 10, -85 q -5, -5, -15, 5 c -10, -40, 10, -60, 30, -60 c 0, 0, 0, 0, 0, 0 c -10, 0, -20, 0, -30, 10 q 0, -10, 2, -20 q -12, 45, -6, 55 q -5, -15, -10, -20 c 0, 20, 20, 20, 5, 90 c -10, -5, -10, 0, -15, -5 c 0, 0, 0, 0, 0, 0 c 20, 50, 70, 300, -30, 400 z ;
13
+ M 335, 700 l 30, 0 c 50, -150, 10, -160, 0, -300 c 0, -50, 0, -90, 50, -75 c 0, 0, 0, 0, 0, 0 c -15, -10, -20, -15, -30, -10 q 10, -8, 20, -10 q -30, 0, -40, 20 c 0, -30, -20, -70, 30, -85 q -20, -5, -30, 5 c -10, -40, 20, -60, 40, -60 c 0, 0, 0, 0, 0, 0 c -20, 0, -30, 0, -40, 10 q 0, -20, 5, -40 q -10, 0, -20, 60 q -10, -15, -20, -20 c 0, 40, 30, 40, 20, 100 c -20, -5, -20, 0, -30, -5 c 10, 10, 30, 20, 40, 180 c 10, 130, -30, 200, -60, 230 z ;
14
+ "
15
+ begin="0s"
16
+ dur="1s"
17
+ />
18
+ <animate
19
+ attributeName="d"
20
+ values="
21
+ M 335, 700 l 30, 0 c 50, -150, 10, -160, 0, -300 c 0, -50, 0, -90, 50, -75 c 0, 0, 0, 0, 0, 0 c -15, -10, -20, -15, -30, -10 q 10, -8, 20, -10 q -30, 0, -40, 20 c 0, -30, -20, -70, 30, -85 q -20, -5, -30, 5 c -10, -40, 20, -60, 40, -60 c 0, 0, 0, 0, 0, 0 c -20, 0, -30, 0, -40, 10 q 0, -20, 5, -40 q -10, 0, -20, 60 q -10, -15, -20, -20 c 0, 40, 30, 40, 20, 100 c -20, -5, -20, 0, -30, -5 c 10, 10, 30, 20, 40, 180 c 10, 130, -30, 200, -60, 230 z ;
22
+ M 330, 700 l 40, 0 c 50, -150, 10, -160, 0, -300 c 0, -50, 0, -90, 70, -60 c 20, 10, 100, 30, 150, -20 c -120, 50, -150, -15, -180, -10 q 50, -30, 120, -15 q -80, -50, -160, 20 c -10, -60, 0, -80, 160, -70 q -80, -30, -160, -10 c -10, -30, 20, -40, 40, -40 c 50, 0, 80, -10, 100, -40 c -80, 50, -100, 0, -140, 30 q 0, -50, 60, -100 q -50, 0, -90, 110 q -90, -80, -100, -120 c -10, 100, 90, 90, 100, 200 c -120, -30, -160, 30, -200, -30 c 10, 90, 180, 0, 200, 110 c 30, 200, 20, 250, -50, 345 z
23
+ "
24
+ begin="1s"
25
+ dur=".5s"
26
+ fill="freeze"
27
+ />
28
+ <animate attributeName="opacity" to=".1" dur="1s" begin="3.0s" fill="freeze" />
29
+ </path>
30
+ <defs>
31
+ <path id="ruby" d="M 4 0 l 18, 0 l 4, 9, l -13, 11, l -13, -11 z" />
32
+ </defs>
33
+ <g fill="red" opacity="0">
34
+ <animate attributeName="opacity" to="1" dur="1s" begin="2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
35
+ <g>
36
+ <g>
37
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
38
+ <use href="#ruby" x="220" y="40"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
39
+ <use href="#ruby" x="260" y="40"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
40
+ <use href="#ruby" x="300" y="40"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
41
+ <use href="#ruby" x="340" y="40"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
42
+ <use href="#ruby" x="380" y="40"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
43
+ <use href="#ruby" x="420" y="40"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
44
+ <use href="#ruby" x="460" y="40"><animate attributeName="x" to="260" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
45
+ <use href="#ruby" x="500" y="40"><animate attributeName="x" to="300" dur="1s" begin="3.35s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
46
+ </g>
47
+ </g>
48
+ <g>
49
+ <g>
50
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
51
+ <use href="#ruby" x="200" y="80"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
52
+ <use href="#ruby" x="480" y="80"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
53
+ <use href="#ruby" x="520" y="80"><animate attributeName="x" to="260" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
54
+ </g>
55
+ <g>
56
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
57
+ <use href="#ruby" x="280" y="80"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
58
+ <use href="#ruby" x="320" y="80"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
59
+ <use href="#ruby" x="360" y="80"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
60
+ <use href="#ruby" x="440" y="80"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
61
+ </g>
62
+ </g>
63
+ <g>
64
+ <g>
65
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
66
+ <use href="#ruby" x="300" y="120"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
67
+ <use href="#ruby" x="340" y="120"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
68
+ <use href="#ruby" x="420" y="120"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
69
+ <use href="#ruby" x="460" y="120"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
70
+ <use href="#ruby" x="500" y="120"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
71
+ <use href="#ruby" x="540" y="120"><animate attributeName="x" to="260" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
72
+ </g>
73
+ <g>
74
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
75
+ <use href="#ruby" x="180" y="120"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
76
+ </g>
77
+ </g>
78
+ <g>
79
+ <g>
80
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
81
+ <use href="#ruby" x="160" y="160"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
82
+ <use href="#ruby" x="520" y="160"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
83
+ <use href="#ruby" x="560" y="160"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
84
+ </g>
85
+ <g>
86
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
87
+ <use href="#ruby" x="200" y="160"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
88
+ <use href="#ruby" x="240" y="160"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
89
+ <use href="#ruby" x="320" y="160"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
90
+ </g>
91
+ </g>
92
+ <g>
93
+ <g>
94
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
95
+ <use href="#ruby" x="140" y="200"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
96
+ <use href="#ruby" x="180" y="200"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
97
+ <use href="#ruby" x="220" y="200"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
98
+ <use href="#ruby" x="260" y="200"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
99
+ <use href="#ruby" x="460" y="200"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
100
+ <use href="#ruby" x="500" y="200"><animate attributeName="x" to="260" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
101
+ <use href="#ruby" x="540" y="200"><animate attributeName="x" to="300" dur="1s" begin="3.35s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
102
+ <use href="#ruby" x="580" y="200"><animate attributeName="x" to="340" dur="1s" begin="3.4s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
103
+ </g>
104
+ <g>
105
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
106
+ <use href="#ruby" x="420" y="200"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
107
+ </g>
108
+ </g>
109
+ <g>
110
+ <g>
111
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
112
+ <use href="#ruby" x="560" y="240"><animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
113
+ <use href="#ruby" x="600" y="240"><animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
114
+ </g>
115
+ <g>
116
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
117
+ <use href="#ruby" x="160" y="240"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
118
+ <use href="#ruby" x="200" y="240"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
119
+ <use href="#ruby" x="240" y="240"><animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
120
+ <use href="#ruby" x="280" y="240"><animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
121
+ </g>
122
+ </g>
123
+ <g>
124
+ <g>
125
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
126
+ <use href="#ruby" x="540" y="280"><animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
127
+ <use href="#ruby" x="580" y="280"><animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" /></use>
128
+ </g>
129
+ </g>
130
+ <g>
131
+ <g>
132
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
133
+ <use href="#ruby" x="520" y="315">
134
+ <animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
135
+ <animate attributeName="y" to="320" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
136
+ </use>
137
+ </g>
138
+ <g>
139
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
140
+ <use href="#ruby" x="170" y="315">
141
+ <animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
142
+ <animate attributeName="y" to="320" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
143
+ </use>
144
+ <use href="#ruby" x="205" y="315">
145
+ <animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
146
+ <animate attributeName="y" to="320" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
147
+ </use>
148
+ <use href="#ruby" x="240" y="315">
149
+ <animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
150
+ <animate attributeName="y" to="320" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
151
+ </use>
152
+ <use href="#ruby" x="275" y="315">
153
+ <animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
154
+ <animate attributeName="y" to="320" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
155
+ </use>
156
+ <use href="#ruby" x="485" y="315">
157
+ <animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
158
+ <animate attributeName="y" to="320" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
159
+ </use>
160
+ </g>
161
+ </g>
162
+ <g>
163
+ <g>
164
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
165
+ <use href="#ruby" x="205" y="350">
166
+ <animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
167
+ <animate attributeName="y" to="360" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
168
+ </use>
169
+ <use href="#ruby" x="240" y="350">
170
+ <animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
171
+ <animate attributeName="y" to="360" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
172
+ </use>
173
+ <use href="#ruby" x="310" y="350">
174
+ <animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
175
+ <animate attributeName="y" to="360" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
176
+ </use>
177
+ <use href="#ruby" x="380" y="350">
178
+ <animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
179
+ <animate attributeName="y" to="360" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
180
+ </use>
181
+ <use href="#ruby" x="415" y="350">
182
+ <animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
183
+ <animate attributeName="y" to="360" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
184
+ </use>
185
+ </g>
186
+ <g>
187
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
188
+ <use href="#ruby" x="275" y="350">
189
+ <animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
190
+ <animate attributeName="y" to="360" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
191
+ </use>
192
+ </g>
193
+ </g>
194
+ <g>
195
+ <g>
196
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
197
+ <use href="#ruby" x="240" y="385">
198
+ <animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
199
+ <animate attributeName="y" to="400" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
200
+ </use>
201
+ <use href="#ruby" x="275" y="385">
202
+ <animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
203
+ <animate attributeName="y" to="400" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
204
+ </use>
205
+ <use href="#ruby" x="380" y="385">
206
+ <animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
207
+ <animate attributeName="y" to="400" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
208
+ </use>
209
+ <use href="#ruby" x="415" y="385">
210
+ <animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
211
+ <animate attributeName="y" to="400" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
212
+ </use>
213
+ <use href="#ruby" x="450" y="385">
214
+ <animate attributeName="x" to="220" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
215
+ <animate attributeName="y" to="400" dur="1s" begin="3.25s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
216
+ </use>
217
+ <use href="#ruby" x="485" y="385">
218
+ <animate attributeName="x" to="260" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
219
+ <animate attributeName="y" to="400" dur="1s" begin="3.3s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
220
+ </use>
221
+ </g>
222
+ <g>
223
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
224
+ <use href="#ruby" x="310" y="385">
225
+ <animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
226
+ <animate attributeName="y" to="400" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
227
+ </use>
228
+ </g>
229
+ </g>
230
+ <g>
231
+ <g>
232
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
233
+ <use href="#ruby" x="275" y="420">
234
+ <animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
235
+ <animate attributeName="y" to="440" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
236
+ </use>
237
+ <use href="#ruby" x="310" y="420">
238
+ <animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
239
+ <animate attributeName="y" to="440" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
240
+ </use>
241
+ <use href="#ruby" x="415" y="420">
242
+ <animate attributeName="x" to="140" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
243
+ <animate attributeName="y" to="440" dur="1s" begin="3.15s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
244
+ </use>
245
+ <use href="#ruby" x="450" y="420">
246
+ <animate attributeName="x" to="180" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
247
+ <animate attributeName="y" to="440" dur="1s" begin="3.2s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
248
+ </use>
249
+ </g>
250
+ <g>
251
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
252
+ <use href="#ruby" x="380" y="420">
253
+ <animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
254
+ <animate attributeName="y" to="440" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
255
+ </use>
256
+ </g>
257
+ </g>
258
+ <g>
259
+ <g>
260
+ <animate attributeName="opacity" to=".1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
261
+ <use href="#ruby" x="310" y="455">
262
+ <animate attributeName="x" to="20" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
263
+ <animate attributeName="y" to="480" dur="1s" begin="3.0s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
264
+ </use>
265
+ <use href="#ruby" x="380" y="455">
266
+ <animate attributeName="x" to="60" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
267
+ <animate attributeName="y" to="480" dur="1s" begin="3.05s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
268
+ </use>
269
+ </g>
270
+ <g>
271
+ <animate attributeName="fill" to="teal" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
272
+ <use href="#ruby" x="415" y="455">
273
+ <animate attributeName="x" to="100" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
274
+ <animate attributeName="y" to="480" dur="1s" begin="3.1s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
275
+ </use>
276
+ </g>
277
+ </g>
278
+ </g>
279
+ <g opacity="0" fill="teal" font-size="140" font-family="monospace" letter-spacing="5">
280
+ <animate attributeName="opacity" to="1" dur="1s" begin="5s" calcMode="spline" keyTimes="0; 1" keySplines="0.25 0.25 0.25 0.75" fill="freeze" />
281
+ <text x="220" y="223">yntax</text>
282
+ <text x="220" y="464">ree</text>
283
+ </g>
284
+ </svg>
data/exe/stree CHANGED
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  $:.unshift(File.expand_path("../lib", __dir__))
5
+
5
6
  require "syntax_tree"
6
7
  require "syntax_tree/cli"
7
8
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class SyntaxTree
3
+ module SyntaxTree
4
4
  module CLI
5
5
  # A utility wrapper around colored strings in the output.
6
6
  class Color
@@ -15,6 +15,10 @@ class SyntaxTree
15
15
  "\033[#{code}m#{value}\033[0m"
16
16
  end
17
17
 
18
+ def self.bold(value)
19
+ new(value, "1")
20
+ end
21
+
18
22
  def self.gray(value)
19
23
  new(value, "38;5;102")
20
24
  end
@@ -30,7 +34,7 @@ class SyntaxTree
30
34
 
31
35
  # The parent action class for the CLI that implements the basics.
32
36
  class Action
33
- def run(filepath, source)
37
+ def run(handler, filepath, source)
34
38
  end
35
39
 
36
40
  def success
@@ -42,8 +46,8 @@ class SyntaxTree
42
46
 
43
47
  # An action of the CLI that prints out the AST for the given source.
44
48
  class AST < Action
45
- def run(filepath, source)
46
- pp SyntaxTree.parse(source)
49
+ def run(handler, filepath, source)
50
+ pp handler.parse(source)
47
51
  end
48
52
  end
49
53
 
@@ -53,8 +57,8 @@ class SyntaxTree
53
57
  class UnformattedError < StandardError
54
58
  end
55
59
 
56
- def run(filepath, source)
57
- raise UnformattedError if source != SyntaxTree.format(source)
60
+ def run(handler, filepath, source)
61
+ raise UnformattedError if source != handler.format(source)
58
62
  rescue StandardError
59
63
  warn("[#{Color.yellow("warn")}] #{filepath}")
60
64
  raise
@@ -75,11 +79,11 @@ class SyntaxTree
75
79
  class NonIdempotentFormatError < StandardError
76
80
  end
77
81
 
78
- def run(filepath, source)
82
+ def run(handler, filepath, source)
79
83
  warning = "[#{Color.yellow("warn")}] #{filepath}"
80
- formatted = SyntaxTree.format(source)
84
+ formatted = handler.format(source)
81
85
 
82
- if formatted != SyntaxTree.format(formatted)
86
+ if formatted != handler.format(formatted)
83
87
  raise NonIdempotentFormatError
84
88
  end
85
89
  rescue StandardError
@@ -98,29 +102,29 @@ class SyntaxTree
98
102
 
99
103
  # An action of the CLI that prints out the doc tree IR for the given source.
100
104
  class Doc < Action
101
- def run(filepath, source)
105
+ def run(handler, filepath, source)
102
106
  formatter = Formatter.new([])
103
- SyntaxTree.parse(source).format(formatter)
107
+ handler.parse(source).format(formatter)
104
108
  pp formatter.groups.first
105
109
  end
106
110
  end
107
111
 
108
112
  # An action of the CLI that formats the input source and prints it out.
109
113
  class Format < Action
110
- def run(filepath, source)
111
- puts SyntaxTree.format(source)
114
+ def run(handler, filepath, source)
115
+ puts handler.format(source)
112
116
  end
113
117
  end
114
118
 
115
119
  # An action of the CLI that formats the input source and writes the
116
120
  # formatted output back to the file.
117
121
  class Write < Action
118
- def run(filepath, source)
122
+ def run(handler, filepath, source)
119
123
  print filepath
120
124
  start = Time.now
121
125
 
122
- formatted = SyntaxTree.format(source)
123
- File.write(filepath, formatted)
126
+ formatted = handler.format(source)
127
+ File.write(filepath, formatted) if filepath != :stdin
124
128
 
125
129
  color = source == formatted ? Color.gray(filepath) : filepath
126
130
  delta = ((Time.now - start) * 1000).round
@@ -135,24 +139,60 @@ class SyntaxTree
135
139
  # The help message displayed if the input arguments are not correctly
136
140
  # ordered or formatted.
137
141
  HELP = <<~HELP
138
- stree MODE FILE
142
+ #{Color.bold("stree ast [OPTIONS] [FILE]")}
143
+ Print out the AST corresponding to the given files
144
+
145
+ #{Color.bold("stree check [OPTIONS] [FILE]")}
146
+ Check that the given files are formatted as syntax tree would format them
147
+
148
+ #{Color.bold("stree debug [OPTIONS] [FILE]")}
149
+ Check that the given files can be formatted idempotently
150
+
151
+ #{Color.bold("stree doc [OPTIONS] [FILE]")}
152
+ Print out the doc tree that would be used to format the given files
153
+
154
+ #{Color.bold("stree format [OPTIONS] [FILE]")}
155
+ Print out the formatted version of the given files
156
+
157
+ #{Color.bold("stree help")}
158
+ Display this help message
159
+
160
+ #{Color.bold("stree lsp")}
161
+ Run syntax tree in language server mode
139
162
 
140
- MODE: ast | check | debug | doc | format | write
141
- FILE: one or more paths to files to parse
163
+ #{Color.bold("stree version")}
164
+ Output the current version of syntax tree
165
+
166
+ #{Color.bold("stree write [OPTIONS] [FILE]")}
167
+ Read, format, and write back the source of the given files
168
+
169
+ [OPTIONS]
170
+
171
+ --plugins=...
172
+ A comma-separated list of plugins to load.
142
173
  HELP
143
174
 
144
175
  class << self
145
176
  # Run the CLI over the given array of strings that make up the arguments
146
177
  # passed to the invocation.
147
178
  def run(argv)
148
- if argv.length < 2
149
- warn(HELP)
150
- return 1
179
+ name, *arguments = argv
180
+
181
+ case name
182
+ when "help"
183
+ puts HELP
184
+ return 0
185
+ when "lsp"
186
+ require "syntax_tree/language_server"
187
+ LanguageServer.new.run
188
+ return 0
189
+ when "version"
190
+ puts SyntaxTree::VERSION
191
+ return 0
151
192
  end
152
193
 
153
- arg, *patterns = argv
154
194
  action =
155
- case arg
195
+ case name
156
196
  when "a", "ast"
157
197
  AST.new
158
198
  when "c", "check"
@@ -170,33 +210,50 @@ class SyntaxTree
170
210
  return 1
171
211
  end
172
212
 
213
+ # If we're not reading from stdin and the user didn't supply and
214
+ # filepaths to be read, then we exit with the usage message.
215
+ if STDIN.tty? && arguments.empty?
216
+ warn(HELP)
217
+ return 1
218
+ end
219
+
220
+ # If there are any plugins specified on the command line, then load them
221
+ # by requiring them here. We do this by transforming something like
222
+ #
223
+ # stree format --plugins=haml template.haml
224
+ #
225
+ # into
226
+ #
227
+ # require "syntax_tree/haml"
228
+ #
229
+ if arguments.first&.start_with?("--plugins=")
230
+ plugins = arguments.shift[/^--plugins=(.*)$/, 1]
231
+ plugins.split(",").each { |plugin| require "syntax_tree/#{plugin}" }
232
+ end
233
+
234
+ # Track whether or not there are any errors from any of the files that
235
+ # we take action on so that we can properly clean up and exit.
173
236
  errored = false
174
- patterns.each do |pattern|
175
- Dir.glob(pattern).each do |filepath|
176
- next unless File.file?(filepath)
177
- source = SyntaxTree.read(filepath)
178
-
179
- begin
180
- action.run(filepath, source)
181
- rescue ParseError => error
182
- warn("Error: #{error.message}")
183
-
184
- if error.lineno
185
- highlight_error(error, source)
186
- else
187
- warn(error.message)
188
- warn(error.backtrace)
189
- end
190
-
191
- errored = true
192
- rescue Check::UnformattedError, Debug::NonIdempotentFormatError
193
- errored = true
194
- rescue => error
195
- warn(error.message)
196
- warn(error.backtrace)
197
- errored = true
198
- end
237
+
238
+ each_file(arguments) do |handler, filepath, source|
239
+ action.run(handler, filepath, source)
240
+ rescue Parser::ParseError => error
241
+ warn("Error: #{error.message}")
242
+
243
+ if error.lineno
244
+ highlight_error(error, source)
245
+ else
246
+ warn(error.message)
247
+ warn(error.backtrace)
199
248
  end
249
+
250
+ errored = true
251
+ rescue Check::UnformattedError, Debug::NonIdempotentFormatError
252
+ errored = true
253
+ rescue => error
254
+ warn(error.message)
255
+ warn(error.backtrace)
256
+ errored = true
200
257
  end
201
258
 
202
259
  if errored
@@ -210,6 +267,22 @@ class SyntaxTree
210
267
 
211
268
  private
212
269
 
270
+ def each_file(arguments)
271
+ if STDIN.tty?
272
+ arguments.each do |pattern|
273
+ Dir.glob(pattern).each do |filepath|
274
+ next unless File.file?(filepath)
275
+
276
+ handler = HANDLERS[File.extname(filepath)]
277
+ source = handler.read(filepath)
278
+ yield handler, filepath, source
279
+ end
280
+ end
281
+ else
282
+ yield HANDLERS[".rb"], :stdin, STDIN.read
283
+ end
284
+ end
285
+
213
286
  # Highlights a snippet from a source and parse error.
214
287
  def highlight_error(error, source)
215
288
  lines = source.lines