mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
[web] match biber in three bibtex parsing edge cases GitOrigin-RevId: da7e2c0b9f137e7debfe26f09c531a61a135e40e
152 lines
4.0 KiB
Plaintext
152 lines
4.0 KiB
Plaintext
@tokens {
|
|
whiteSpace { $[\t\n\r ]+ }
|
|
|
|
// Anything outside of an entry at the top level is a BibTeX free-form comment.
|
|
// A word may contain a "%" but may not start with one, so a "%" at a token
|
|
// boundary still opens a comment: btparse parses the entry in
|
|
// "Junk% @article{a}" but treats "Junk % @article{a}" as a comment.
|
|
junkWord { ![@ \t\n\r%] ![@ \t\n\r]* }
|
|
Junk { junkWord (whiteSpace junkWord)* }
|
|
|
|
// BibLaTeX supports comments starting with a % and extending to the end of
|
|
// the line
|
|
Comment { "%" ![\n\r]* }
|
|
|
|
// btparse derives a name by "removing the magic 10 from printable ASCII, then
|
|
// further excluding @, \ and ~", the magic 10 being " # % ' ( ) , = { } and
|
|
// space. Stating that by exclusion rather than by listing the allowed
|
|
// punctuation also admits non-ASCII: btparse's own lexer is ASCII-only here,
|
|
// but biber accepts UTF-8 throughout, including in citation keys.
|
|
// See https://metacpan.org/dist/Text-BibTeX/view/btparse/doc/bt_language.pod
|
|
identifierChar { ![\u{0}-\u{20}\u{7f}"#%'(),=@\\{}~] }
|
|
|
|
// Identifiers cannot start with a digit, so that a value like 1995 is a
|
|
// NumberLiteral rather than a macro name. Citation keys can.
|
|
identifierStart { ![\u{0}-\u{20}\u{7f}"#%'(),=@\\{}~0-9] }
|
|
|
|
identifier { identifierStart identifierChar* }
|
|
|
|
EntryType { identifier }
|
|
|
|
CitationKey { identifierChar+ }
|
|
|
|
NumberLiteral { @digit+ }
|
|
|
|
"#" "="
|
|
}
|
|
|
|
@external specialize {EntryType} specializeEntryType from "./tokens.mjs" {
|
|
stringKeyword,
|
|
preambleKeyword,
|
|
commentKeyword
|
|
}
|
|
|
|
@skip { whiteSpace | Comment }
|
|
|
|
@top Bibliography {
|
|
(Junk | Entry | CommentEntry | PreambleEntry | StringEntry)*
|
|
}
|
|
|
|
StringEntry { StringCommand StringBody }
|
|
PreambleEntry { PreambleCommand PreambleBody }
|
|
CommentEntry { CommentCommand CommentBody }
|
|
Entry { EntryCommand EntryBody }
|
|
|
|
EntryCommand { "@" EntryType }
|
|
EntryBody { commandBody<entryContents> }
|
|
StringCommand { "@" stringKeyword }
|
|
StringBody { commandBody<fields> }
|
|
PreambleCommand { "@" preambleKeyword }
|
|
PreambleBody { commandBody<Value> }
|
|
CommentCommand { "@" commentKeyword }
|
|
|
|
commandBody<contents> {
|
|
(
|
|
BodyOpen[closedBy="BodyClose"] { "{" }
|
|
contents
|
|
BodyClose[openedBy="BodyOpen"] { "}" }
|
|
) | (
|
|
BodyOpen[closedBy="BodyClose"] { "(" }
|
|
contents
|
|
BodyClose[openedBy="BodyOpen"] { ")" }
|
|
)
|
|
}
|
|
|
|
entryContents { CitationKey ("," fields)? }
|
|
|
|
fields { (Field ("," Field)* ","?)? }
|
|
|
|
Field { FieldName "=" Value }
|
|
FieldName { identifier }
|
|
Value { simpleValue ("#" simpleValue)* }
|
|
simpleValue { StringLiteral | NumberLiteral | StringName }
|
|
StringName { identifier }
|
|
|
|
@local tokens {
|
|
strOpenBrace { "{" }
|
|
strCloseBrace { "}" }
|
|
strOpenParen { "(" }
|
|
strCloseParen { ")" }
|
|
strQuote { "\"" }
|
|
@else strOther
|
|
}
|
|
|
|
@skip {} {
|
|
StringLiteral {
|
|
(
|
|
StringOpen[closedBy="StringClose"] { "\"" }
|
|
StringContents { quotedStringContents }
|
|
StringClose[openedBy="StringOpen"] { strQuote }
|
|
) | (
|
|
StringOpen[closedBy="StringClose"] { "{" }
|
|
StringContents { bracedStringContents }
|
|
StringClose[openedBy="StringOpen"] { strCloseBrace }
|
|
)
|
|
}
|
|
|
|
CommentBody {
|
|
(
|
|
BodyOpen[closedBy="BodyClose"] { "{" }
|
|
CommentContents { bracedStringContents }
|
|
BodyClose[openedBy="BodyOpen"] { strCloseBrace }
|
|
) | (
|
|
BodyOpen[closedBy="BodyClose"] { "(" }
|
|
CommentContents { parenthesizedStringContents }
|
|
BodyClose[openedBy="BodyOpen"] { strCloseParen }
|
|
)
|
|
}
|
|
|
|
quotedStringContents {
|
|
(
|
|
strOpenBrace bracedStringContents strCloseBrace |
|
|
strOpenParen |
|
|
strCloseParen |
|
|
strCloseBrace |
|
|
strOther
|
|
)*
|
|
}
|
|
|
|
parenthesizedStringContents {
|
|
(
|
|
strOpenBrace bracedStringContents strCloseBrace |
|
|
strQuote |
|
|
strOpenParen |
|
|
strCloseBrace |
|
|
strOther
|
|
)*
|
|
|
|
}
|
|
|
|
bracedStringContents {
|
|
(
|
|
strOpenBrace bracedStringContents strCloseBrace |
|
|
strQuote |
|
|
strOpenParen |
|
|
strCloseParen |
|
|
strOther
|
|
)*
|
|
}
|
|
}
|
|
|
|
@external propSource highlighting from "./highlight.mjs"
|