equal
deleted
inserted
replaced
54 var chunk_pos = Map.empty[String, Position.T] |
54 var chunk_pos = Map.empty[String, Position.T] |
55 val tokens = new mutable.ListBuffer[(Token, Position.T)] |
55 val tokens = new mutable.ListBuffer[(Token, Position.T)] |
56 var line = 1 |
56 var line = 1 |
57 var offset = 1 |
57 var offset = 1 |
58 |
58 |
59 def token_pos(tok: Token): Position.T = |
59 def make_pos(length: Int): Position.T = |
60 Position.Offset(offset) ::: Position.End_Offset(offset + tok.source.length) ::: |
60 Position.Offset(offset) ::: Position.End_Offset(offset + length) ::: Position.Line(line) |
61 Position.Line(line) |
|
62 |
61 |
63 def advance_pos(tok: Token) |
62 def advance_pos(tok: Token) |
64 { |
63 { |
65 for (s <- Symbol.iterator(tok.source)) { |
64 for (s <- Symbol.iterator(tok.source)) { |
66 if (Symbol.is_newline(s)) line += 1 |
65 if (Symbol.is_newline(s)) line += 1 |
72 if (0 < l && l <= tokens.length) tokens(l - 1)._2 else Position.none |
71 if (0 < l && l <= tokens.length) tokens(l - 1)._2 else Position.none |
73 |
72 |
74 for (chunk <- chunks) { |
73 for (chunk <- chunks) { |
75 val name = chunk.name |
74 val name = chunk.name |
76 if (name != "" && !chunk_pos.isDefinedAt(name)) { |
75 if (name != "" && !chunk_pos.isDefinedAt(name)) { |
77 chunk_pos += (name -> token_pos(chunk.tokens.head)) |
76 chunk_pos += (name -> make_pos(chunk.heading_length)) |
78 } |
77 } |
79 for (tok <- chunk.tokens) { |
78 for (tok <- chunk.tokens) { |
80 tokens += (tok.copy(source = tok.source.replace("\n", " ")) -> token_pos(tok)) |
79 tokens += (tok.copy(source = tok.source.replace("\n", " ")) -> make_pos(tok.source.length)) |
81 advance_pos(tok) |
80 advance_pos(tok) |
82 } |
81 } |
83 } |
82 } |
84 |
83 |
85 Isabelle_System.with_tmp_dir("bibtex")(tmp_dir => |
84 Isabelle_System.with_tmp_dir("bibtex")(tmp_dir => |
318 kind == Token.Kind.NAME || |
317 kind == Token.Kind.NAME || |
319 kind == Token.Kind.IDENT |
318 kind == Token.Kind.IDENT |
320 def is_ignored: Boolean = |
319 def is_ignored: Boolean = |
321 kind == Token.Kind.SPACE || |
320 kind == Token.Kind.SPACE || |
322 kind == Token.Kind.COMMENT |
321 kind == Token.Kind.COMMENT |
323 def is_malformed: Boolean = kind == |
322 def is_malformed: Boolean = |
324 Token.Kind.ERROR |
323 kind == Token.Kind.ERROR |
|
324 def is_open: Boolean = |
|
325 kind == Token.Kind.KEYWORD && (source == "{" || source == "(") |
325 } |
326 } |
326 |
327 |
327 case class Chunk(kind: String, tokens: List[Token]) |
328 case class Chunk(kind: String, tokens: List[Token]) |
328 { |
329 { |
329 val source = tokens.map(_.source).mkString |
330 val source = tokens.map(_.source).mkString |
346 def name: String = |
347 def name: String = |
347 content match { |
348 content match { |
348 case Some(tok :: _) if tok.is_name => tok.source |
349 case Some(tok :: _) if tok.is_name => tok.source |
349 case _ => "" |
350 case _ => "" |
350 } |
351 } |
|
352 |
|
353 def heading_length: Int = |
|
354 if (name == "") 1 |
|
355 else (0 /: tokens.takeWhile(tok => !tok.is_open)){ case (n, tok) => n + tok.source.length } |
351 |
356 |
352 def is_ignored: Boolean = kind == "" && tokens.forall(_.is_ignored) |
357 def is_ignored: Boolean = kind == "" && tokens.forall(_.is_ignored) |
353 def is_malformed: Boolean = kind == "" || tokens.exists(_.is_malformed) |
358 def is_malformed: Boolean = kind == "" || tokens.exists(_.is_malformed) |
354 def is_command: Boolean = Bibtex.is_command(kind) && name != "" && content.isDefined |
359 def is_command: Boolean = Bibtex.is_command(kind) && name != "" && content.isDefined |
355 def is_entry: Boolean = Bibtex.is_entry(kind) && name != "" && content.isDefined |
360 def is_entry: Boolean = Bibtex.is_entry(kind) && name != "" && content.isDefined |