184 } |
184 } |
185 |
185 |
186 |
186 |
187 /* result messages */ |
187 /* result messages */ |
188 |
188 |
189 private val clean_elements = |
|
190 Markup.Elements(Markup.REPORT, Markup.NO_REPORT) |
|
191 |
|
192 def clean_message(body: XML.Body): XML.Body = |
|
193 body filter { |
|
194 case XML.Wrapped_Elem(Markup(name, _), _, _) => !clean_elements(name) |
|
195 case XML.Elem(Markup(name, _), _) => !clean_elements(name) |
|
196 case _ => true |
|
197 } map { |
|
198 case XML.Wrapped_Elem(markup, body, ts) => XML.Wrapped_Elem(markup, body, clean_message(ts)) |
|
199 case XML.Elem(markup, ts) => XML.Elem(markup, clean_message(ts)) |
|
200 case t => t |
|
201 } |
|
202 |
|
203 def message_reports(props: Properties.T, body: XML.Body): List[XML.Elem] = |
|
204 body flatMap { |
|
205 case XML.Wrapped_Elem(Markup(Markup.REPORT, ps), body, ts) => |
|
206 List(XML.Wrapped_Elem(Markup(Markup.REPORT, props ::: ps), body, ts)) |
|
207 case XML.Elem(Markup(Markup.REPORT, ps), ts) => |
|
208 List(XML.Elem(Markup(Markup.REPORT, props ::: ps), ts)) |
|
209 case XML.Wrapped_Elem(_, _, ts) => message_reports(props, ts) |
|
210 case XML.Elem(_, ts) => message_reports(props, ts) |
|
211 case XML.Text(_) => Nil |
|
212 } |
|
213 |
|
214 |
|
215 /* specific messages */ |
|
216 |
|
217 def is_result(msg: XML.Tree): Boolean = |
189 def is_result(msg: XML.Tree): Boolean = |
218 msg match { |
190 msg match { |
219 case XML.Elem(Markup(Markup.RESULT, _), _) => true |
191 case XML.Elem(Markup(Markup.RESULT, _), _) => true |
220 case _ => false |
192 case _ => false |
221 } |
193 } |
299 def unapply(tree: XML.Tree): Option[String] = |
271 def unapply(tree: XML.Tree): Option[String] = |
300 tree match { |
272 tree match { |
301 case XML.Elem(Markup(Markup.RESULT, _), List(XML.Text(result))) => Some(result) |
273 case XML.Elem(Markup(Markup.RESULT, _), List(XML.Text(result))) => Some(result) |
302 case _ => None |
274 case _ => None |
303 } |
275 } |
304 } |
|
305 |
|
306 |
|
307 /* reported positions */ |
|
308 |
|
309 private val position_elements = |
|
310 Markup.Elements(Markup.BINDING, Markup.ENTITY, Markup.REPORT, Markup.POSITION) |
|
311 |
|
312 def message_positions( |
|
313 self_id: Document_ID.Generic => Boolean, |
|
314 command_position: Position.T, |
|
315 chunk_name: Symbol.Text_Chunk.Name, |
|
316 chunk: Symbol.Text_Chunk, |
|
317 message: XML.Elem): Set[Text.Range] = |
|
318 { |
|
319 def elem_positions(props: Properties.T, set: Set[Text.Range]): Set[Text.Range] = |
|
320 props match { |
|
321 case Position.Identified(id, name) if self_id(id) && name == chunk_name => |
|
322 val opt_range = |
|
323 Position.Range.unapply(props) orElse { |
|
324 if (name == Symbol.Text_Chunk.Default) |
|
325 Position.Range.unapply(command_position) |
|
326 else None |
|
327 } |
|
328 opt_range match { |
|
329 case Some(symbol_range) => |
|
330 chunk.incorporate(symbol_range) match { |
|
331 case Some(range) => set + range |
|
332 case _ => set |
|
333 } |
|
334 case None => set |
|
335 } |
|
336 case _ => set |
|
337 } |
|
338 |
|
339 def positions(set: Set[Text.Range], tree: XML.Tree): Set[Text.Range] = |
|
340 tree match { |
|
341 case XML.Wrapped_Elem(Markup(name, props), _, body) => |
|
342 body.foldLeft(if (position_elements(name)) elem_positions(props, set) else set)(positions) |
|
343 case XML.Elem(Markup(name, props), body) => |
|
344 body.foldLeft(if (position_elements(name)) elem_positions(props, set) else set)(positions) |
|
345 case XML.Text(_) => set |
|
346 } |
|
347 |
|
348 val set = positions(Set.empty, message) |
|
349 if (set.isEmpty) elem_positions(message.markup.properties, set) |
|
350 else set |
|
351 } |
276 } |
352 } |
277 } |
353 |
278 |
354 |
279 |
355 trait Protocol |
280 trait Protocol |