Merge pull request #13572 from overleaf/mj-bibtex-grammar

[cm6] Add support for bibtex

GitOrigin-RevId: 28bc8e47c53df1612c1e30cf690e893b0bbf500c
This commit is contained in:
Mathias Jakobsen
2023-07-17 10:47:59 +00:00
committed by Copybot
parent e5d6777211
commit 67e7621633
15 changed files with 413 additions and 101 deletions
@@ -0,0 +1,10 @@
import { LRLanguage } from '@codemirror/language'
import { parser } from '../../lezer-bibtex/bibtex.mjs'
import { bibtexEntryCompletions } from './completions/snippets'
export const BibTeXLanguage = LRLanguage.define({
parser,
languageData: {
autocomplete: bibtexEntryCompletions,
},
})
@@ -0,0 +1,95 @@
import { CompletionContext, snippet } from '@codemirror/autocomplete'
type Environment = {
name: string
requiredAttributes: string[]
}
const environments: Environment[] = [
{
name: 'article',
requiredAttributes: ['author', 'title', 'journal', 'year'],
},
{
name: 'book',
requiredAttributes: ['author', 'title', 'publisher', 'year'],
},
{
name: 'booklet',
requiredAttributes: ['key', 'title'],
},
{
name: 'conference',
requiredAttributes: ['key', 'title', 'year'],
},
{
name: 'inbook',
requiredAttributes: ['author', 'title', 'publisher', 'year', 'chapter'],
},
{
name: 'incollection',
requiredAttributes: ['author', 'title', 'booktitle', 'publisher', 'year'],
},
{
name: 'inproceedings',
requiredAttributes: ['author', 'title', 'booktitle', 'year'],
},
{
name: 'manual',
requiredAttributes: ['key', 'title'],
},
{
name: 'masterthesis',
requiredAttributes: ['author', 'title', 'school', 'year'],
},
{
name: 'misc',
requiredAttributes: ['key', 'note'],
},
{
name: 'phdthesis',
requiredAttributes: ['author', 'title', 'school', 'year'],
},
{
name: 'proceedings',
requiredAttributes: ['key', 'title', 'year'],
},
{
name: 'techreport',
requiredAttributes: ['author', 'title', 'institution', 'year'],
},
{
name: 'unpublished',
requiredAttributes: ['author', 'title', 'note'],
},
]
const prepareSnippet = (environment: Environment) => {
return `@${
environment.name
}{#{citation-key},${environment.requiredAttributes.map(
attribute => `
${attribute} = #{}`
)}
}`
}
export function bibtexEntryCompletions(context: CompletionContext) {
const word = context.matchBefore(/@\w*/)
if (word?.from === word?.to && !context.explicit) return null
return {
from: word?.from ?? context.pos,
options: [
...environments.map(env => ({
label: `@${env.name}`,
type: 'snippet',
apply: snippet(prepareSnippet(env)),
})),
{
label: '@string',
type: 'snippet',
apply: snippet('@string{#{string-key} = #{}}'),
},
],
}
}
@@ -0,0 +1,8 @@
import { LanguageSupport, indentUnit } from '@codemirror/language'
import { BibTeXLanguage } from './bibtex-language'
export const bibtex = () => {
return new LanguageSupport(BibTeXLanguage, [
indentUnit.of(' '), // 4 spaces
])
}