src/Pure/Tools/bibtex.scala
author wenzelm
Sat, 04 Oct 2014 17:57:03 +0200
changeset 58534 573ce5ad13bc
parent 58533 dfbfc92118eb
child 58535 4815429974fe
permissions -rw-r--r--
clarified nesting of delimiters; tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Tools/bibtex.scala
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     3
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     4
Some support for bibtex files.
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     5
*/
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     6
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     7
package isabelle
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     8
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
     9
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
    10
import scala.collection.mutable
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    11
import scala.util.parsing.input.{Reader, CharSequenceReader}
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    12
import scala.util.parsing.combinator.RegexParsers
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    13
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    14
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    15
object Bibtex
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    16
{
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    17
  /** content **/
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    18
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    19
  private val months = List(
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    20
    "jan",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    21
    "feb",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    22
    "mar",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    23
    "apr",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    24
    "may",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    25
    "jun",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    26
    "jul",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    27
    "aug",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    28
    "sep",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    29
    "oct",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    30
    "nov",
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    31
    "dec")
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    32
  def is_month(s: String): Boolean = months.contains(s.toLowerCase)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    33
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    34
  private val commands = List("preamble", "string")
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    35
  def is_command(s: String): Boolean = commands.contains(s.toLowerCase)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    36
58524
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    37
  sealed case class Entry(
58526
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
    38
    kind: String,
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    39
    required: List[String],
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    40
    optional_crossref: List[String],
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    41
    optional_other: List[String])
58524
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    42
  {
58533
dfbfc92118eb fields are case-insensitive;
wenzelm
parents: 58532
diff changeset
    43
    def is_required(s: String): Boolean = required.contains(s.toLowerCase)
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    44
    def is_optional(s: String): Boolean =
58533
dfbfc92118eb fields are case-insensitive;
wenzelm
parents: 58532
diff changeset
    45
      optional_crossref.contains(s.toLowerCase) || optional_other.contains(s.toLowerCase)
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    46
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
    47
    def fields: List[String] = required ::: optional_crossref ::: optional_other
58524
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    48
    def template: String =
58526
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
    49
      "@" + kind + "{,\n" + fields.map(x => "  " + x + " = {},\n").mkString + "}\n"
58524
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    50
  }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
    51
58524
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    52
  val entries: List[Entry] =
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    53
    List(
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    54
      Entry("Article",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    55
        List("author", "title"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    56
        List("journal", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    57
        List("volume", "number", "pages", "month", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    58
      Entry("InProceedings",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    59
        List("author", "title"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    60
        List("booktitle", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    61
        List("editor", "volume", "number", "series", "pages", "month", "address",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    62
          "organization", "publisher", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    63
      Entry("InCollection",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    64
        List("author", "title", "booktitle"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    65
        List("publisher", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    66
        List("editor", "volume", "number", "series", "type", "chapter", "pages",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    67
          "edition", "month", "address", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    68
      Entry("InBook",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    69
        List("author", "editor", "title", "chapter"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    70
        List("publisher", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    71
        List("volume", "number", "series", "type", "address", "edition", "month", "pages", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    72
      Entry("Proceedings",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    73
        List("title", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    74
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    75
        List("booktitle", "editor", "volume", "number", "series", "address", "month",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    76
          "organization", "publisher", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    77
      Entry("Book",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    78
        List("author", "editor", "title"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    79
        List("publisher", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    80
        List("volume", "number", "series", "address", "edition", "month", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    81
      Entry("Booklet",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    82
        List("title"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    83
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    84
        List("author", "howpublished", "address", "month", "year", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    85
      Entry("PhdThesis",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    86
        List("author", "title", "school", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    87
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    88
        List("type", "address", "month", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    89
      Entry("MastersThesis",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    90
        List("author", "title", "school", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    91
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    92
        List("type", "address", "month", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    93
      Entry("TechReport",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    94
        List("author", "title", "institution", "year"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    95
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    96
        List("type", "number", "address", "month", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    97
      Entry("Manual",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    98
        List("title"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
    99
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   100
        List("author", "organization", "address", "edition", "month", "year", "note")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   101
      Entry("Unpublished",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   102
        List("author", "title", "note"),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   103
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   104
        List("month", "year")),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   105
      Entry("Misc",
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   106
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   107
        List(),
f805b366a497 context menu for bibtex entries;
wenzelm
parents: 58523
diff changeset
   108
        List("author", "title", "howpublished", "month", "year", "note")))
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   109
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   110
  def get_entry(kind: String): Option[Entry] =
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   111
    entries.find(entry => entry.kind.toLowerCase == kind.toLowerCase)
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   112
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   113
  def is_entry(kind: String): Boolean = get_entry(kind).isDefined
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   114
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   115
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   116
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   117
  /** tokens and chunks **/
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   118
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   119
  object Token
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   120
  {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   121
    object Kind extends Enumeration
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   122
    {
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   123
      val COMMAND = Value("command")
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   124
      val ENTRY = Value("entry")
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   125
      val KEYWORD = Value("keyword")
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   126
      val NAT = Value("natural number")
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   127
      val STRING = Value("string")
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   128
      val NAME = Value("name")
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   129
      val IDENT = Value("identifier")
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   130
      val IGNORED = Value("ignored")
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   131
      val ERROR = Value("bad input")
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   132
    }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   133
  }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   134
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   135
  sealed case class Token(kind: Token.Kind.Value, val source: String)
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   136
  {
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   137
    def is_kind: Boolean =
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   138
      kind == Token.Kind.COMMAND ||
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   139
      kind == Token.Kind.ENTRY ||
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   140
      kind == Token.Kind.IDENT
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   141
    def is_name: Boolean =
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   142
      kind == Token.Kind.NAME ||
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   143
      kind == Token.Kind.IDENT
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   144
    def is_ignored: Boolean = kind == Token.Kind.IGNORED
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   145
    def is_malformed: Boolean = kind == Token.Kind.ERROR
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   146
  }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   147
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   148
  case class Chunk(kind: String, tokens: List[Token])
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   149
  {
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   150
    val source = tokens.map(_.source).mkString
58526
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
   151
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   152
    private val content: Option[List[Token]] =
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   153
      tokens match {
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   154
        case Token(Token.Kind.KEYWORD, "@") :: body if !body.isEmpty =>
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   155
          (body.init.filterNot(_.is_ignored), body.last) match {
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   156
            case (tok :: Token(Token.Kind.KEYWORD, "{") :: toks, Token(Token.Kind.KEYWORD, "}"))
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   157
            if tok.is_kind => Some(toks)
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   158
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   159
            case (tok :: Token(Token.Kind.KEYWORD, "(") :: toks, Token(Token.Kind.KEYWORD, ")"))
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   160
            if tok.is_kind => Some(toks)
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   161
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   162
            case _ => None
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   163
          }
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   164
        case _ => None
58526
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
   165
      }
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
   166
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
   167
    def name: String =
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   168
      content match {
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   169
        case Some(tok :: _) if tok.is_name => tok.source
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   170
        case _ => ""
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   171
      }
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   172
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   173
    def is_ignored: Boolean = kind == "" && tokens.forall(_.is_ignored)
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   174
    def is_malformed: Boolean = kind == "" || tokens.exists(_.is_malformed)
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   175
    def is_command: Boolean =
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   176
      Bibtex.is_command(kind) && name != "" && content.isDefined && !is_malformed
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   177
    def is_entry: Boolean =
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   178
      Bibtex.is_entry(kind) && name != "" && content.isDefined && !is_malformed
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   179
  }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   180
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   181
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   182
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   183
  /** parsing **/
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   184
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   185
  // context of partial line-oriented scans
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   186
  abstract class Line_Context
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   187
  case object Ignored_Context extends Line_Context
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   188
  case class Item_Context(kind: String, delim: Delimited, right: String) extends Line_Context
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   189
  case class Delimited(quoted: Boolean, depth: Int)
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   190
  val Closed = Delimited(false, 0)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   191
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   192
  private def token(kind: Token.Kind.Value)(source: String): Token = Token(kind, source)
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   193
  private def keyword(source: String): Token = Token(Token.Kind.KEYWORD, source)
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   194
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   195
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   196
  // See also http://ctan.org/tex-archive/biblio/bibtex/base/bibtex.web
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   197
  // module @<Scan for and process a \.{.bib} command or database entry@>.
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   198
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   199
  object Parsers extends RegexParsers
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   200
  {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   201
    /* white space and comments */
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   202
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   203
    override val whiteSpace = "".r
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   204
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   205
    private val space = """[ \t\n\r]+""".r ^^ token(Token.Kind.IGNORED)
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   206
    private val strict_space = """[ \t]+""".r ^^ token(Token.Kind.IGNORED)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   207
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   208
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   209
    /* ignored material */
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   210
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   211
    private val ignored: Parser[Chunk] =
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   212
      rep1("""(?mi)([^@]+|@[ \t]*comment)""".r) ^^ {
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   213
        case ss => Chunk("", List(Token(Token.Kind.IGNORED, ss.mkString))) }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   214
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   215
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   216
    /* delimited string: outermost "..." or {...} and body with balanced {...} */
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   217
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   218
    // see also bibtex.web: scan_a_field_token_and_eat_white, scan_balanced_braces
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   219
    private def delimited_depth(delim: Delimited): Parser[(String, Delimited)] =
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   220
      new Parser[(String, Delimited)]
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   221
      {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   222
        require(if (delim.quoted) delim.depth > 0 else delim.depth >= 0)
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   223
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   224
        def apply(in: Input) =
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   225
        {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   226
          val start = in.offset
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   227
          val end = in.source.length
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   228
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   229
          var i = start
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   230
          var q = delim.quoted
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   231
          var d = delim.depth
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   232
          var finished = false
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   233
          while (!finished && i < end) {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   234
            val c = in.source.charAt(i)
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   235
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   236
            if (c == '"' && d == 0) { i += 1; d = 1; q = true }
58532
af2fc25662b6 clarified nesting of delimiters;
wenzelm
parents: 58531
diff changeset
   237
            else if (c == '"' && d == 1 && q) {
af2fc25662b6 clarified nesting of delimiters;
wenzelm
parents: 58531
diff changeset
   238
              i += 1; d = 0; q = false; finished = true
af2fc25662b6 clarified nesting of delimiters;
wenzelm
parents: 58531
diff changeset
   239
            }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   240
            else if (c == '{') { i += 1; d += 1 }
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   241
            else if (c == '}') {
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   242
              if (d == 1 && !q || d > 1) { i += 1; d -= 1; if (d == 0) finished = true }
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   243
              else {i = start; finished = true }
58532
af2fc25662b6 clarified nesting of delimiters;
wenzelm
parents: 58531
diff changeset
   244
            }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   245
            else if (d > 0) i += 1
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   246
            else finished = true
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   247
          }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   248
          if (i == start) Failure("bad input", in)
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   249
          else {
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   250
            val s = in.source.subSequence(start, i).toString
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   251
            Success((s, Delimited(q, d)), in.drop(i - start))
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   252
          }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   253
        }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   254
      }.named("delimited_depth")
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   255
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   256
    private def delimited: Parser[Token] =
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   257
      delimited_depth(Closed) ^?
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   258
        { case (s, delim) if delim == Closed => Token(Token.Kind.STRING, s) }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   259
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   260
    private def recover_delimited: Parser[Token] =
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   261
      """(?m)["{][^@]*""".r ^^ token(Token.Kind.ERROR)
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   262
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   263
    def delimited_line(item_ctxt: Item_Context): Parser[(Chunk, Line_Context)] =
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   264
      item_ctxt match {
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   265
        case Item_Context(kind, delim, _) =>
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   266
          delimited_depth(delim) ^^ { case (s, delim1) =>
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   267
            (Chunk(kind, List(Token(Token.Kind.STRING, s))), item_ctxt.copy(delim = delim1)) } |
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   268
          recover_delimited ^^ { case a => (Chunk(kind, List(a)), Ignored_Context) }
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   269
        }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   270
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   271
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   272
    /* other tokens */
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   273
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   274
    private val at = "@" ^^ keyword
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   275
    private val left_brace = "{" ^^ keyword
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   276
    private val right_brace = "}" ^^ keyword
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   277
    private val left_paren = "(" ^^ keyword
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   278
    private val right_paren = ")" ^^ keyword
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   279
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   280
    private val nat = "[0-9]+".r ^^ token(Token.Kind.NAT)
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   281
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   282
    private val identifier =
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   283
      """[\x21-\x7f&&[^"#%'(),={}0-9]][\x21-\x7f&&[^"#%'(),={}]]*""".r
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   284
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   285
    private val ident = identifier ^^ token(Token.Kind.IDENT)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   286
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   287
    val other_token = "[=#,]".r ^^ keyword | (nat | (ident | space))
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   288
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   289
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   290
    /* items: command or entry */
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   291
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   292
    private val item_kind =
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   293
      identifier ^^ { case a =>
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   294
        val kind =
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   295
          if (is_command(a)) Token.Kind.COMMAND
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   296
          else if (is_entry(a)) Token.Kind.ENTRY
58529
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   297
          else Token.Kind.IDENT
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   298
        Token(kind, a)
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   299
      }
cd4439d8799c support for bibtex token markup;
wenzelm
parents: 58528
diff changeset
   300
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   301
    private val item_start =
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   302
      at ~ rep(strict_space) ~ item_kind ~ rep(strict_space) ^^
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   303
        { case a ~ b ~ c ~ d => (c.source, List(a) ::: b ::: List(c) ::: d) }
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   304
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   305
    private val item_name =
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   306
      rep(strict_space) ~ identifier ^^
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   307
        { case a ~ b => a ::: List(Token(Token.Kind.NAME, b)) }
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   308
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   309
    private val item_body =
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   310
      delimited | (recover_delimited | other_token)
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   311
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   312
    private val item: Parser[Chunk] =
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   313
      (item_start ~ left_brace ~ item_name ~ rep(item_body) ~ opt(right_brace) |
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   314
       item_start ~ left_paren ~ item_name ~ rep(item_body) ~ opt(right_paren)) ^^
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   315
        { case (kind, a) ~ b ~ c ~ d ~ e => Chunk(kind, a ::: List(b) ::: c ::: d ::: e.toList) }
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   316
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   317
    private val recover_item: Parser[Chunk] =
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   318
      at ~ "(?m)[^@]*".r ^^ { case a ~ b => Chunk("", List(a, Token(Token.Kind.ERROR, b))) }
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   319
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   320
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   321
    /* chunks */
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   322
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   323
    val chunk: Parser[Chunk] = ignored | (item | recover_item)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   324
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   325
    def chunk_line(ctxt: Line_Context): Parser[(Chunk, Line_Context)] =
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   326
    {
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   327
      ctxt match {
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   328
        case Ignored_Context =>
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   329
          ignored ^^ { case a => (a, ctxt) } |
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   330
          item_start ~ (left_brace | left_paren) ~ opt(item_name) ^^
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   331
            { case (kind, a) ~ b ~ c =>
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   332
                val right = if (b.source == "{") "}" else ")"
58531
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   333
                val chunk = Chunk(kind, a ::: List(b) ::: (c getOrElse Nil))
454962877285 more explicit chunk name;
wenzelm
parents: 58530
diff changeset
   334
                (chunk, Item_Context(kind, Closed, right)) } |
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   335
          recover_item ^^ { case a => (a, Ignored_Context) }
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   336
        case item_ctxt @ Item_Context(kind, delim, right) =>
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   337
          if (delim.depth > 0)
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   338
            delimited_line(item_ctxt)
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   339
          else {
58534
573ce5ad13bc clarified nesting of delimiters;
wenzelm
parents: 58533
diff changeset
   340
            delimited_line(item_ctxt) |
58530
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   341
            other_token ^^ { case a => (Chunk(kind, List(a)), ctxt) } |
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   342
            right ^^ { case a => (Chunk(kind, List(keyword(a))), Ignored_Context) }
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   343
          }
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   344
        case _ => failure("")
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   345
      }
7ee248f19ca9 clarified Chunk -- avoid ooddities;
wenzelm
parents: 58529
diff changeset
   346
    }
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   347
  }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   348
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   349
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   350
  /* parse */
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   351
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   352
  def parse(input: CharSequence): List[Chunk] =
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   353
  {
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   354
    val in: Reader[Char] = new CharSequenceReader(input)
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   355
    Parsers.parseAll(Parsers.rep(Parsers.chunk), in) match {
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   356
      case Parsers.Success(result, _) => result
58526
f05ccce3eca2 SideKick parser for bibtex entries;
wenzelm
parents: 58524
diff changeset
   357
      case _ => error("Unexpected failure to parse input:\n" + input.toString)
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   358
    }
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   359
  }
58528
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   360
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   361
  def parse_line(input: CharSequence, context: Line_Context): (List[Chunk], Line_Context) =
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   362
  {
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   363
    var in: Reader[Char] = new CharSequenceReader(input)
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   364
    val chunks = new mutable.ListBuffer[Chunk]
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   365
    var ctxt = context
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   366
    while (!in.atEnd) {
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   367
      Parsers.parse(Parsers.chunk_line(ctxt), in) match {
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   368
        case Parsers.Success((x, c), rest) => { chunks += x; ctxt = c; in = rest }
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   369
        case Parsers.NoSuccess(_, rest) =>
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   370
          error("Unepected failure to parse input:\n" + rest.source.toString)
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   371
      }
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   372
    }
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   373
    (chunks.toList, ctxt)
7d6b8f8893e8 more explicit item kind;
wenzelm
parents: 58527
diff changeset
   374
  }
58523
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   375
}
937c479e62fe some support for bibtex files;
wenzelm
parents:
diff changeset
   376