Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.renderer.js |
— | — | @@ -22,6 +22,16 @@ |
23 | 23 | }, inspectorMap); |
24 | 24 | }); |
25 | 25 | }; |
| 26 | + var extensionAttribute = function(node, name) { |
| 27 | + var lname = name.toLowerCase(); |
| 28 | + var match = null; |
| 29 | + $.each(node.params, function(i, param) { |
| 30 | + if (param.name.toLowerCase() == lname) { |
| 31 | + match = param; |
| 32 | + } |
| 33 | + }); |
| 34 | + return match ? match.text : null; |
| 35 | + } |
26 | 36 | var node; |
27 | 37 | if (typeof tree == "string") { |
28 | 38 | // hack |
— | — | @@ -107,9 +117,27 @@ |
108 | 118 | // @fixme names etc? |
109 | 119 | if (self.context.refs === undefined) { |
110 | 120 | self.context.refs = []; |
| 121 | + self.context.refsByName = {}; |
111 | 122 | } |
112 | | - self.context.refs.push(tree); |
113 | | - var refNum = self.context.refs.length; |
| 123 | + var refNum; |
| 124 | + var name = extensionAttribute(tree, 'name'); |
| 125 | + if (name !== null && name in self.context.refsByName) { |
| 126 | + // Already seen! |
| 127 | + refNum = self.context.refsByName[name]; |
| 128 | + var origRef = self.context.refs[refNum - 1]; |
| 129 | + if ('content' in tree && tree.content && !('content' in origRef && origRef.content)) { |
| 130 | + // Earlier one was empty; replace it with this one. |
| 131 | + self.context.refs[refNum - 1] = tree; |
| 132 | + } |
| 133 | + } else { |
| 134 | + // New one! |
| 135 | + self.context.refs.push(tree); |
| 136 | + refNum = self.context.refs.length; |
| 137 | + if (name !== null) { |
| 138 | + self.context.refsByName[name] = refNum; |
| 139 | + } |
| 140 | + } |
| 141 | + |
114 | 142 | var ref = $('<span class="ref parseNode">[</span>'); |
115 | 143 | $('<a></a>') |
116 | 144 | .text(refNum + '') |
— | — | @@ -128,6 +156,10 @@ |
129 | 157 | if ('content' in subtree) { |
130 | 158 | subParseArray(subtree.content, ref); |
131 | 159 | } |
| 160 | + ref.data('parseNode', subtree); // assign the node for the tree inspector |
| 161 | + if (inspectorMap) { |
| 162 | + inspectorMap.put(subtree, ref[0]); // store for reverse lookup |
| 163 | + } |
132 | 164 | references.append(ref); |
133 | 165 | }); |
134 | 166 | node = references[0]; |
Index: trunk/extensions/ParserPlayground/modules/ext.parserPlayground.serializer.js |
— | — | @@ -98,7 +98,7 @@ |
99 | 99 | if ('name' in param) { |
100 | 100 | src += param.name + '='; |
101 | 101 | } |
102 | | - src += subParseArray(param.contents); |
| 102 | + src += subParseArray(param.content); |
103 | 103 | } |
104 | 104 | } |
105 | 105 | src += '}}'; |
Index: trunk/extensions/ParserPlayground/modules/pegParser.pegjs.txt |
— | — | @@ -165,11 +165,11 @@ |
166 | 166 | = name:template_param_name "=" c:template_param_text { |
167 | 167 | return { |
168 | 168 | name: name, |
169 | | - contents: c |
| 169 | + content: c |
170 | 170 | }; |
171 | 171 | } / c:template_param_text { |
172 | 172 | return { |
173 | | - contents: c |
| 173 | + content: c |
174 | 174 | }; |
175 | 175 | } |
176 | 176 | |