diff --git a/lib/rouge/demos/bibtex b/lib/rouge/demos/bibtex new file mode 100644 index 0000000000..e029265881 --- /dev/null +++ b/lib/rouge/demos/bibtex @@ -0,0 +1,12 @@ +@article{Witten:1988hf, + author = "Witten, Edward", + title = "{Quantum Field Theory and the Jones Polynomial}", + journal = "Commun. Math. Phys.", + volume = "121", + year = "1989", + pages = "351-399", + doi = "10.1007/BF01217730", + note = "[,233(1988)]", + reportNumber = "IASSNS-HEP-88-33", + SLACcitation = "%%CITATION = CMPHA,121,351;%%" +} diff --git a/lib/rouge/lexers/bibtex.rb b/lib/rouge/lexers/bibtex.rb new file mode 100644 index 0000000000..cc6ece72da --- /dev/null +++ b/lib/rouge/lexers/bibtex.rb @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# Regular expressions based on https://github.com/SaswatPadhi/prismjs-bibtex +# and https://github.com/alecthomas/chroma/blob/master/lexers/b/bibtex.go + +module Rouge + module Lexers + class BibTeX < RegexLexer + title 'BibTeX' + desc "BibTeX" + tag 'bibtex' + aliases 'bib' + filenames '*.bib' + + valid_punctuation = Regexp.quote("@!$&.\\:;<>?[]^`|~*/+-") + valid_name = /[a-z_#{valid_punctuation}][\w#{valid_punctuation}]*/io + + state :root do + mixin :whitespace + + rule %r/@(#{valid_name})/o do |m| + match = m[1].downcase + + if match == "comment" + token Comment + elsif match == "preamble" + token Name::Class + push :closing_brace + push :value + push :opening_brace + elsif match == "string" + token Name::Class + push :closing_brace + push :field + push :opening_brace + else + token Name::Class + push :closing_brace + push :command_body + push :opening_brace + end + end + + rule %r/.+/, Comment + end + + state :opening_brace do + mixin :whitespace + rule %r/[{(]/, Punctuation, :pop! + end + + state :closing_brace do + mixin :whitespace + rule %r/[})]/, Punctuation, :pop! + end + + state :command_body do + mixin :whitespace + rule %r/[^\s\,\}]+/ do + token Name::Label + pop! + push :fields + end + end + + state :fields do + mixin :whitespace + rule %r/,/, Punctuation, :field + rule(//) { pop! } + end + + state :field do + mixin :whitespace + rule valid_name do + token Name::Attribute + push :value + push :equal_sign + end + rule(//) { pop! } + end + + state :equal_sign do + mixin :whitespace + rule %r/=/, Punctuation, :pop! + end + + state :value do + mixin :whitespace + rule valid_name, Name::Variable + rule %r/"/, Literal::String, :quoted_string + rule %r/\{/, Literal::String, :braced_string + rule %r/\d+/, Literal::Number + rule %r/#/, Punctuation + rule(//) { pop! } + end + + state :quoted_string do + rule %r/\{/, Literal::String, :braced_string + rule %r/"/, Literal::String, :pop! + rule %r/[^\{\"]+/, Literal::String + end + + state :braced_string do + rule %r/\{/, Literal::String, :braced_string + rule %r/\}/, Literal::String, :pop! + rule %r/[^\{\}]+/, Literal::String + end + + state :whitespace do + rule %r/\s+/, Text + end + end + end +end diff --git a/spec/lexers/bibtex_spec.rb b/spec/lexers/bibtex_spec.rb new file mode 100644 index 0000000000..00cd491df0 --- /dev/null +++ b/spec/lexers/bibtex_spec.rb @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +describe Rouge::Lexers::BibTeX do + let(:subject) { Rouge::Lexers::BibTeX.new } + + describe 'guessing' do + include Support::Guessing + + it 'guesses by filename' do + assert_guess :filename => 'foo.bib' + end + end +end + diff --git a/spec/visual/samples/bibtex b/spec/visual/samples/bibtex new file mode 100644 index 0000000000..2f8bd61d18 --- /dev/null +++ b/spec/visual/samples/bibtex @@ -0,0 +1,68 @@ +%%% Bibtex comment + +@inproceedings{DBLP:conf/pldi/PadhiSM16, + author = {Saswat Padhi and + Rahul Sharma and + Todd D. Millstein}, + title = {Data-driven precondition inference with learned features}, + booktitle = {Proceedings of the 37th {ACM} {SIGPLAN} Conference on Programming + Language Design and Implementation, {PLDI} 2016, Santa Barbara, CA, + USA, June 13-17, 2016}, + pages = {42--56}, + year = {2016}, + crossref = {DBLP:conf/pldi/2016}, + url = {https://doi.org/10.1145/2908080.2908099}, + doi = {10.1145/2908080.2908099}, + timestamp = {Tue, 06 Nov 2018 16:59:30 +0100}, + biburl = {https://dblp.org/rec/bib/conf/pldi/PadhiSM16}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} + +@article{article, + author = {Peter Adams}, + title = {The title of the work}, + journal = {The name of the journal}, + year = 1993, + number = 2, + pages = {201-213}, + month = 7, + note = {An optional note}, + volume = 4 +} + +@MISC{WEBSITE:1, + HOWPUBLISHED = "\url{http://example.com}", + AUTHOR = "Intel", + TITLE = "Example Website", + MONTH = "Dec", + YEAR = "1988", + NOTE = "Accessed on 2012-11-11" +} + +@STRING(PRL="Phys. Rev. Lett.") +@STRING(RMP="Rev. Mod. Phys.") + +@ARTICLE{klitzing:nobel, + AUTHOR="Klaus von Klitzing", + TITLE="The Quantised Hall Effect", + JOURNAL=RMP, + VOLUME=58, + PAGES=519, + YEAR=1986 +} + +@preamble{ "\newcommand{\mytext}{Last accessed:}" } + +@ARTICLE{knuth:1974, + author = {Knuth, Donald E.}, + title = {{C}omputer {P}rogramming as an {A}rt}, + journal = {Communications of the ACM}, + year = {1974}, + volume = {17}, + pages = {667--673}, + number = {12}, + month = {December }, + address = {New York, NY, USA}, + publisher = {ACM Press}, + note = {\mytext{} 09/20/12} +}