From 5a3c5f14b38e5f88d24de338b80492bb2a591221 Mon Sep 17 00:00:00 2001 From: Mario Perez <mapreal19@gmail.com> Date: Mon, 19 Jul 2021 16:21:36 +0200 Subject: [PATCH] feat: allows braces on citekey --- lib/bibtex/lexer.rb | 11 +++++++---- test/bibtex/test_lexer.rb | 18 +++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/bibtex/lexer.rb b/lib/bibtex/lexer.rb index ff57337..f255aa9 100644 --- a/lib/bibtex/lexer.rb +++ b/lib/bibtex/lexer.rb @@ -58,8 +58,8 @@ class Lexer string: /string/io, comment: /comment\b/io, preamble: /preamble\b/io, - key: %r{\s*[[:alpha:][:digit:] /:_!$\?\.%+;&\*'"-]+,}io, - optional_key: %r{\s*[[:alpha:][:digit:] /:_!$\?\.%+;&\*'"-]*,}io + key: %r{\s*[[:alpha:][:digit:] /:_!$\?\.%+;&\*'"-\{\}]+,}io, + optional_key: %r{\s*[[:alpha:][:digit:] /:_!$\?\.%+;&\*'"-\{\}]*,}io } MODE = Hash.new(:meta).merge( @@ -120,7 +120,7 @@ def next_token @stack.shift end - # Returns true if the lexer is currenty parsing a BibTeX object. + # Returns true if the lexer is currently parsing a BibTeX object. def bibtex_mode? MODE[@mode] == :bibtex end @@ -308,7 +308,10 @@ def enter_object push([:LBRACE, '{']) @mode = :content if @brace_level > 1 || @brace_level == 1 && active?(:comment) - push [:KEY, @scanner.matched.chop.strip] if @scanner.scan(Lexer.patterns[allow_missing_keys? ? :optional_key : :key]) + if @scanner.scan(Lexer.patterns[allow_missing_keys? ? :optional_key : :key]) + key = @scanner.matched.chop.strip.tr('{}', '') + push [:KEY, key] + end end else diff --git a/test/bibtex/test_lexer.rb b/test/bibtex/test_lexer.rb index 7dc100b..5904c91 100644 --- a/test/bibtex/test_lexer.rb +++ b/test/bibtex/test_lexer.rb @@ -7,33 +7,37 @@ class LexerTest < Minitest::Spec end it 'strips line breaks by default' do - Lexer.new.analyse(%(@string{ x = "foo\nbar" })).stack[-3].must_be :==, + _(Lexer.new.analyse(%(@string{ x = "foo\nbar" })).stack[-3]).must_be :==, [:STRING_LITERAL, 'foo bar'] end it 'strips whitespace after line breaks by default' do - Lexer.new.analyse(%(@string{ x = "foo\n bar" })).stack[-3].must_be :==, + _(Lexer.new.analyse(%(@string{ x = "foo\n bar" })).stack[-3]).must_be :==, [:STRING_LITERAL, 'foo bar'] end it 'matches KEY tokens' do - Lexer.new.analyse('@misc{foo, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] + _(Lexer.new.analyse('@misc{foo, }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] end it 'matches KEY tokens with non-ascii characters' do - Lexer.new.analyse('@misc{löwe, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] + _(Lexer.new.analyse('@misc{löwe, }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] end it 'matches KEY tokens after whitespace' do - Lexer.new.analyse('@misc{ foo, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] + _(Lexer.new.analyse('@misc{ foo, }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] + end + + it 'matches KEY tokens with braces' do + _(Lexer.new.analyse('@misc{foo:{123}, }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] end it "doesn't start a comment for types starting with but not equal @comment" do - Lexer.new.analyse('@commentary{staudinger, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] + _(Lexer.new.analyse('@commentary{staudinger, }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false] end it "doesn't start a preamble for types starting with but not equal @preamble" do - Lexer.new.analyse('@preamblestring{ preamble }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :NAME, :RBRACE, false] + _(Lexer.new.analyse('@preamblestring{ preamble }').symbols).must_be :==, [:AT, :NAME, :LBRACE, :NAME, :RBRACE, false] end end end