syntax_tree 1.2.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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