├── spec
├── fixtures
│ ├── database.unk
│ ├── database.bibtex
│ ├── database-issue84.bib
│ ├── database.bib
│ └── database.rfc.xml
├── throwaway_spec.rb
├── index_spec.rb
├── integration_spec.rb
├── csl
│ └── styles
│ │ ├── tex_citealp_numeric_spec.rb
│ │ ├── tex_citep_numeric_spec.rb
│ │ ├── tex_citeps_numeric_spec.rb
│ │ ├── tex_citealps_numeric_spec.rb
│ │ ├── tex_citeyear_numeric_spec.rb
│ │ ├── tex_citeyear_authoryear_spec.rb
│ │ ├── tex_citeyearpar_numeric_spec.rb
│ │ ├── tex_citeyearpar_authoryear_spec.rb
│ │ ├── rfc_v2_spec.rb
│ │ ├── rfc_v3_spec.rb
│ │ ├── tex_citealt_numeric_spec.rb
│ │ ├── tex_citeauthor_numeric_spec.rb
│ │ ├── tex_citeauthor_authoryear_spec.rb
│ │ ├── tex_citealt_authoryear_spec.rb
│ │ ├── tex_citet_authoryear_spec.rb
│ │ ├── tex_citep_authoryear_spec.rb
│ │ ├── tex_citealp_authoryear_spec.rb
│ │ ├── tex_citet_numeric_spec.rb
│ │ ├── tex_citealts_numeric_spec.rb
│ │ ├── tex_citeauthors_numeric_spec.rb
│ │ ├── tex_citeauthors_authoryear_spec.rb
│ │ ├── tex_citealts_authoryear_spec.rb
│ │ ├── tex_citets_authoryear_spec.rb
│ │ ├── tex_citeps_authoryear_spec.rb
│ │ ├── tex_citealps_authoryear_spec.rb
│ │ └── tex_citets_numeric_spec.rb
├── citation_helper.rb
├── citeproc
│ └── ruby
│ │ └── formats
│ │ └── adoc_spec.rb
├── nocite_spec.rb
├── end_to_end_spec.rb
├── database_spec.rb
├── macros_spec.rb
└── citation_item_spec.rb
├── .rspec
├── Gemfile
├── .hound.yml
├── .codeclimate.yml
├── lib
├── asciidoctor-bibliography
│ ├── version.rb
│ ├── asciidoctor
│ │ ├── document_ext.rb
│ │ └── bibliographer_preprocessor.rb
│ ├── asciidoctor.rb
│ ├── errors.rb
│ ├── formatter.rb
│ ├── bibliographer.rb
│ ├── citation_item.rb
│ ├── database.rb
│ ├── databases
│ │ ├── rfc.rb
│ │ └── bibtex.rb
│ └── index.rb
├── asciidoctor-bibliography.rb
├── csl
│ └── styles
│ │ ├── rfc-v2.csl
│ │ ├── rfc-v3.csl
│ │ ├── tex-citealp-numeric.csl
│ │ ├── tex-citealps-numeric.csl
│ │ ├── tex-citeauthor-numeric.csl
│ │ ├── tex-citeauthors-numeric.csl
│ │ ├── tex-citeauthor-authoryear.csl
│ │ ├── tex-citeauthors-authoryear.csl
│ │ ├── tex-citep-numeric.csl
│ │ ├── tex-citeps-numeric.csl
│ │ ├── tex-citeyear-numeric.csl
│ │ ├── tex-citeyear-authoryear.csl
│ │ ├── tex-citeyearpar-numeric.csl
│ │ ├── tex-citeyearpar-authoryear.csl
│ │ ├── tex-citealp-authoryear.csl
│ │ ├── tex-citealps-authoryear.csl
│ │ ├── tex-citep-authoryear.csl
│ │ ├── tex-citeps-authoryear.csl
│ │ ├── tex-citealt-numeric.csl
│ │ ├── tex-citealts-numeric.csl
│ │ ├── tex-citet-numeric.csl
│ │ ├── tex-citets-numeric.csl
│ │ ├── tex-citealt-authoryear.csl
│ │ ├── tex-citealts-authoryear.csl
│ │ ├── tex-citet-authoryear.csl
│ │ └── tex-citets-authoryear.csl
└── citeproc
│ └── ruby
│ └── formats
│ └── adoc.rb
├── Rakefile
├── bin
├── setup
└── rspec
├── .rubocop.yml
├── samples
├── latex_macros_in_bibtex
│ ├── sample.adoc
│ └── reference.bib
├── tex
│ ├── sample-sort.adoc
│ ├── biblio.bib
│ ├── sample-authoryear.adoc
│ └── sample-numbers.adoc
└── standard
│ ├── sample-targets.adoc
│ ├── sample-ieee.adoc
│ ├── sample-default.adoc
│ ├── sample-din.adoc
│ └── biblio.bib
├── LICENSE.txt
├── .github
└── workflows
│ └── test-and-release.yml
├── .gitignore
├── asciidoctor-bibliography.gemspec
└── SYNTAX.adoc
/spec/fixtures/database.unk:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/.hound.yml:
--------------------------------------------------------------------------------
1 | ruby:
2 | enabled: true
3 | config_file: .rubocop.yml
4 |
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | rubocop:
3 | enabled: true
4 | config:
5 | file: .rubocop.yml
6 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/version.rb:
--------------------------------------------------------------------------------
1 | module AsciidoctorBibliography
2 | VERSION = "0.11.0".freeze
3 | end
4 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/gem_tasks"
2 | require "rspec/core/rake_task"
3 |
4 | RSpec::Core::RakeTask.new(:spec)
5 |
6 | task :default => :spec
7 |
--------------------------------------------------------------------------------
/spec/fixtures/database.bibtex:
--------------------------------------------------------------------------------
1 | @article{Bar10,
2 | author = {F. Bar},
3 | title = {Article title},
4 | publisher = {Publisher},
5 | year = {2010}
6 | }
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 | IFS=$'\n\t'
4 | set -vx
5 |
6 | bundle install
7 |
8 | # Do any other automated setup that you need to do here
9 |
--------------------------------------------------------------------------------
/spec/throwaway_spec.rb:
--------------------------------------------------------------------------------
1 | describe :throwaway do
2 | # This just covers a couple of trivial lines to better track coverage.
3 | # To be deleted when coverage is satisfactory.
4 | document = Asciidoctor::Document.new
5 | document.bibliographer
6 | end
7 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | inherit_from: .oss-guides.rubocop.yml
2 |
3 | AllCops:
4 | TargetRubyVersion: 2.3
5 |
6 | # TODO: shorten all lines to 80, as per oss-guides.
7 | Metrics/LineLength:
8 | Max: 120
9 | Exclude:
10 | - 'spec/**/*_spec.rb'
11 |
12 | Rails:
13 | Enabled: false
14 |
--------------------------------------------------------------------------------
/samples/latex_macros_in_bibtex/sample.adoc:
--------------------------------------------------------------------------------
1 | = Latex Macros In Bibtex Items
2 | :bibliography-database: reference.bib
3 | :bibliography-style: ieee
4 |
5 | == Contents
6 |
7 | This is a paper "Validation and Verificaton of Computer Forensic Software
8 | tools -- Searching Function" (see cite:guo2009[]).
9 |
10 | == Bibliography
11 |
12 | bibliography::[]
13 |
14 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography.rb:
--------------------------------------------------------------------------------
1 | begin
2 | require "byebug"
3 | rescue LoadError
4 | end
5 |
6 | require_relative "asciidoctor-bibliography/asciidoctor"
7 |
8 | module AsciidoctorBibliography
9 | def self.root
10 | File.dirname __dir__
11 | end
12 |
13 | def self.csl_styles_root
14 | File.join AsciidoctorBibliography.root,
15 | "lib/csl/styles"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/asciidoctor/document_ext.rb:
--------------------------------------------------------------------------------
1 | # Extends Document to support additional method
2 | module AsciidoctorBibliography
3 | module Asciidoctor
4 | module DocumentExt
5 | # All our document-level permanence passes through this accessor.
6 | def bibliographer
7 | @bibliographer ||= AsciidoctorBibliography::Bibliographer.new
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/samples/tex/sample-sort.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-tex-style: numeric
4 | :bibliography-style: ieee
5 | :bibliography-sort: { macro: author, sort: descending }
6 |
7 |
8 | ## Citations
9 |
10 |
11 | cite:[Lane12a]
12 |
13 | cite:[Lane12b]
14 |
15 | cite:[Anderson04]
16 |
17 |
18 | ## Bibliography
19 |
20 |
21 | bibliography::[]
22 |
23 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/asciidoctor.rb:
--------------------------------------------------------------------------------
1 | require "asciidoctor/extensions"
2 |
3 | require_relative "asciidoctor/bibliographer_preprocessor"
4 | require_relative "asciidoctor/document_ext"
5 | require_relative "bibliographer"
6 |
7 | Asciidoctor::Document.include AsciidoctorBibliography::Asciidoctor::DocumentExt
8 |
9 | Asciidoctor::Extensions.register do
10 | preprocessor AsciidoctorBibliography::Asciidoctor::BibliographerPreprocessor
11 | end
12 |
--------------------------------------------------------------------------------
/samples/standard/sample-targets.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-hyperlinks: true
4 |
5 | ## Standard
6 |
7 | cite:[Lane12a]
8 |
9 | cite:foo[Anderson04]
10 |
11 | cite:bar[Lane12a]+foo[Lane12b]
12 |
13 | ## Bibliographies
14 |
15 | ### Default
16 |
17 | bibliography::default[]
18 |
19 | ### Foo
20 |
21 | bibliography::foo[]
22 |
23 | ### Bar
24 |
25 | bibliography::bar[]
26 |
--------------------------------------------------------------------------------
/samples/standard/sample-ieee.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-style: ieee
4 |
5 | ## Standard
6 |
7 | cite:[Anderson04]
8 |
9 | cite:[Anderson04, page=10]
10 |
11 | cite:[Anderson04, chapter=10]
12 |
13 | cite:[Anderson04, page=10, chapter=12]
14 |
15 | cite:[Lane12a]+[Lane12b]
16 |
17 | cite:[Lane12a, page=42]+[Lane12b, opus=12]
18 |
19 | ## Bibliography
20 |
21 | bibliography::[]
22 |
23 |
--------------------------------------------------------------------------------
/samples/standard/sample-default.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-hyperlinks: true
4 |
5 | ## Standard
6 |
7 | cite:[Lane12a]+[Lane12b]
8 |
9 | cite:[Anderson04]
10 |
11 | cite:[Anderson04, page=10]
12 |
13 | cite:[Anderson04, chapter=10]
14 |
15 | cite:[Anderson04, page=10, chapter=12]
16 |
17 | cite:[Lane12a, page=42]+[Lane12b, opus=12]
18 |
19 | ## Bibliography
20 |
21 | bibliography::[]
22 |
23 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/errors.rb:
--------------------------------------------------------------------------------
1 | module AsciidoctorBibliography
2 | module Errors
3 | class Error < StandardError; end
4 |
5 | module Options
6 | class Missing < Error; end
7 | class Invalid < Error; end
8 | end
9 |
10 | module Database
11 | class UnsupportedFormat < Error; end
12 | class FileNotFound < Error; end
13 | class IdNotFound < Error; end
14 | class ConflictingIds < Error; end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/samples/standard/sample-din.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-style: din-1505-2-alphanumeric
4 |
5 | ## Standard
6 |
7 | cite:[Anderson04]
8 |
9 | cite:[Anderson04, page=10]
10 |
11 | cite:[Anderson04, chapter=10]
12 |
13 | cite:[Anderson04, page=10, chapter=12]
14 |
15 | cite:[Lane12a]+[Lane12b]
16 |
17 | cite:[Lane12a, page=42]+[Lane12b, opus=12]
18 |
19 | ## Bibliography
20 |
21 | bibliography::[]
22 |
23 |
--------------------------------------------------------------------------------
/samples/latex_macros_in_bibtex/reference.bib:
--------------------------------------------------------------------------------
1 | @article{guo2009,
2 | title = {Validation and Verification of Computer Forensic Software
3 | tools\textemdash{}{{Searching Function}}
4 | {\url{http://www.csoonline.com/article/2122329/investigations-forensics/the-rise-of-anti-forensics.html}}},
5 | volume = {6},
6 | issn = {17422876},
7 | doi = {10.1016/j.diin.2009.06.015},
8 | language = {en},
9 | timestamp = {2016-06-13T16:44:17Z},
10 | urldate = {2016-06-13},
11 | journal = {Digital Investigation},
12 | author = {Guo, Yinghua and Slay, Jill and Beckett, Jason},
13 | month = sep,
14 | year = {2009},
15 | pages = {S12--S22}
16 | }
17 |
--------------------------------------------------------------------------------
/spec/index_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "citation_helper"
4 |
5 | describe AsciidoctorBibliography::Index do
6 | describe ".render" do
7 | subject { described_class.new([], "default", "") }
8 |
9 | it "does not fail when no citations occur in the document" do
10 | options = { "bibliography-style" => "ieee", "bibliography-database" => "database.bibtex", "bibliography-passthrough" => "true", "bibliography-prepend-empty" => "false" }
11 | bibliographer = init_bibliographer options: options
12 | expect { subject.render bibliographer}.to_not raise_exception
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/samples/tex/biblio.bib:
--------------------------------------------------------------------------------
1 | @book{Lane12a,
2 | author = {P. Lane},
3 | title = {Book title},
4 | publisher = {Publisher},
5 | year = {2000}
6 | }
7 |
8 | @book{Lane12b,
9 | author = {K. Mane and D. Smith},
10 | title = {Book title},
11 | publisher = {Publisher},
12 | year = {2000}
13 | }
14 |
15 | @book{Anderson98,
16 | editor = {J. R. Anderson and C. Lebiere},
17 | title = {The Atomic Components of {2\sum} Thought},
18 | publisher = {Lawrence Erlbaum},
19 | address = {Mahwah, NJ},
20 | year = {1998}
21 | }
22 |
23 | @article{Anderson04,
24 | author = {J. R. Anderson and D. Bothell and M. D. Byrne and S. Douglass and C. Lebiere and Y. L. Qin},
25 | title = {An integrated theory of the mind},
26 | journal = {Psychological Review},
27 | volume = {111},
28 | number = {4},
29 | pages = {1036--1060},
30 | year = {2004}
31 | }
32 |
--------------------------------------------------------------------------------
/samples/standard/biblio.bib:
--------------------------------------------------------------------------------
1 | @book{Lane12a,
2 | author = {P. Lane},
3 | title = {Book title},
4 | publisher = {Publisher},
5 | year = {2000}
6 | }
7 |
8 | @book{Lane12b,
9 | author = {K. Mane and D. Smith},
10 | title = {Book title},
11 | publisher = {Publisher},
12 | year = {2000}
13 | }
14 |
15 | @book{Anderson98,
16 | editor = {J. R. Anderson and C. Lebiere},
17 | title = {The Atomic Components of {2\sum} Thought},
18 | publisher = {Lawrence Erlbaum},
19 | address = {Mahwah, NJ},
20 | year = {1998}
21 | }
22 |
23 | @article{Anderson04,
24 | author = {J. R. Anderson and D. Bothell and M. D. Byrne and S. Douglass and C. Lebiere and Y. L. Qin},
25 | title = {An integrated theory of the mind},
26 | journal = {Psychological Review},
27 | volume = {111},
28 | number = {4},
29 | pages = {1036--1060},
30 | year = {2004}
31 | }
32 |
--------------------------------------------------------------------------------
/bin/rspec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'rspec' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require "pathname"
12 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
13 | "../../Gemfile", Pathname.new(__FILE__).realpath
14 | )
15 |
16 | bundle_binstub = File.expand_path("bundle", __dir__)
17 |
18 | if File.file?(bundle_binstub)
19 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
20 | load(bundle_binstub)
21 | else
22 | abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
23 | Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
24 | end
25 | end
26 |
27 | require "rubygems"
28 | require "bundler/setup"
29 |
30 | load Gem.bin_path("rspec-core", "rspec")
31 |
--------------------------------------------------------------------------------
/lib/csl/styles/rfc-v2.csl:
--------------------------------------------------------------------------------
1 |
2 |
27 |
--------------------------------------------------------------------------------
/lib/csl/styles/rfc-v3.csl:
--------------------------------------------------------------------------------
1 |
2 |
27 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/formatter.rb:
--------------------------------------------------------------------------------
1 | require "citeproc"
2 | require "csl/styles"
3 | require "yaml"
4 |
5 | require_relative "../citeproc/ruby/formats/adoc"
6 |
7 | module AsciidoctorBibliography
8 | class Formatter < ::CiteProc::Processor
9 | def initialize(style, locale: "en-US")
10 | super style: style, format: :adoc, locale: locale
11 | end
12 |
13 | def replace_bibliography_sort(array)
14 | new_keys = array.map(&::CSL::Style::Sort::Key.method(:new))
15 | new_sort = ::CSL::Style::Sort.new.add_children(*new_keys)
16 |
17 | bibliography = engine.style.find_child("bibliography")
18 | bibliography.find_child("sort")&.unlink
19 |
20 | bibliography.add_child new_sort
21 | end
22 |
23 | def force_sort!(mode:)
24 | # Valid modes are :citation and :bibliography
25 | engine.sort! data, engine.style.send(mode).sort_keys if engine.style.send(mode).sort?
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/bibliographer.rb:
--------------------------------------------------------------------------------
1 | module AsciidoctorBibliography
2 | class Bibliographer
3 | attr_accessor :citations
4 | attr_accessor :indices
5 | attr_accessor :database
6 | attr_reader :occurring_keys
7 | attr_accessor :options
8 |
9 | def initialize
10 | @options = {}
11 | @citations = []
12 | @indices = []
13 | @database = nil
14 | @occurring_keys = {}
15 | end
16 |
17 | def add_citation(citation)
18 | citations << citation
19 |
20 | # NOTE: Since we're rendering the whole (possibly composite) citation as missing - even if
21 | # NOTE: a single key is nil - we add none of them to the occurring keys to be rendered in indices.
22 | return if citation.any_missing_id?(self)
23 |
24 | citation.citation_items.group_by(&:target).each do |target, citation_items|
25 | @occurring_keys[target] ||= []
26 | @occurring_keys[target].concat(citation_items.map(&:key)).uniq!
27 | end
28 | end
29 |
30 | def appearance_index_of(target, id)
31 | @occurring_keys[target].index(id) + 1
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Ribose Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/citation_item.rb:
--------------------------------------------------------------------------------
1 | require "asciidoctor/attribute_list"
2 |
3 | module AsciidoctorBibliography
4 | class CitationItem
5 | LOCATORS = CiteProc::CitationItem.labels.map(&:to_s).push("locator").freeze
6 |
7 | attr_accessor :key, :target, :positional_attributes, :named_attributes
8 |
9 | def initialize
10 | yield self if block_given?
11 | end
12 |
13 | def prefix
14 | named_attributes["prefix"]
15 | end
16 |
17 | def suffix
18 | named_attributes["suffix"]
19 | end
20 |
21 | def text
22 | named_attributes["text"]
23 | end
24 |
25 | def locators
26 | named_attributes.select { |key, _| LOCATORS.include? key }
27 | end
28 |
29 | def locator
30 | locators.first
31 | end
32 |
33 | def parse_attribute_list(string)
34 | parsed_attributes = ::Asciidoctor::AttributeList.new(string).parse
35 | self.named_attributes = parsed_attributes.reject { |key, _| key.is_a? Integer }
36 | self.positional_attributes = parsed_attributes.select { |key, _| key.is_a? Integer }.values
37 | self.key = positional_attributes.shift
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/spec/integration_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "asciidoctor-bibliography"
4 |
5 | describe "rendering citations styles containing square brackets" do
6 | let(:parsed_document) do
7 | Asciidoctor::Document.new(<<~ADOC_INPUT).tap(&:parse)
8 | = Sample document
9 | :bibliography-database: spec/fixtures/database.bib
10 | :bibliography-hyperlinks: true
11 | :bibliography-style: ieee
12 | ...
13 |
14 | This paragraph contains a citation: cite:[Lane12a].
15 | It also contains [.my-class]#some# inline styling.
16 | ADOC_INPUT
17 | end
18 |
19 | it "does not confuse rendered brackets with macro brackets in the paragraph" do
20 | # I.e. we're trying to avoid results like
21 | # ```
22 | #
This paragraph contains a citation: some inline styling.
24 | # ```
25 | expect(parsed_document.render).to eq(<<~HTML_OUTPUT.strip)
26 |
27 |
This paragraph contains a citation: [1].
28 | It also contains some inline styling.
29 |
30 | HTML_OUTPUT
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/.github/workflows/test-and-release.yml:
--------------------------------------------------------------------------------
1 | name: test-and-release
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | tags: [ 'v*' ]
7 | pull_request:
8 |
9 | concurrency:
10 | group: '${{ github.workflow }}-${{ github.job }}-${{ github.head_ref || github.ref_name }}'
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | test:
15 | name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
16 | runs-on: ${{ matrix.os }}
17 | continue-on-error: false
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | ruby: [ '2.5', '2.6', '2.7', '3.0', '3.1' ]
22 | os: [ ubuntu-latest, windows-latest, macos-latest ]
23 |
24 | steps:
25 | - uses: actions/checkout@v3
26 |
27 | - uses: ruby/setup-ruby@v1
28 | with:
29 | ruby-version: ${{ matrix.ruby }}
30 | bundler-cache: true
31 |
32 | - run: bundle exec rspec
33 |
34 | release:
35 | name: Release gem
36 | needs: test
37 | runs-on: ubuntu-latest
38 | if: contains(github.ref, 'refs/tags/v')
39 | steps:
40 | - uses: actions/checkout@v3
41 | - uses: ruby/setup-ruby@v1
42 | with:
43 | ruby-version: 2.7
44 | bundler-cache: true
45 | - uses: cadwallion/publish-rubygems-action@master
46 | env:
47 | RUBYGEMS_API_KEY: ${{secrets.RIBOSE_RUBYGEMS_API_KEY}}
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | /.config
4 | /coverage/
5 | /InstalledFiles
6 | /pkg/
7 | /spec/reports/
8 | /spec/examples.txt
9 | /test/tmp/
10 | /test/version_tmp/
11 | /tmp/
12 |
13 | # Used by dotenv library to load environment variables.
14 | # .env
15 |
16 | ## Specific to RubyMotion:
17 | .dat*
18 | .repl_history
19 | build/
20 | *.bridgesupport
21 | build-iPhoneOS/
22 | build-iPhoneSimulator/
23 |
24 | ## Specific to RubyMotion (use of CocoaPods):
25 | #
26 | # We recommend against adding the Pods directory to your .gitignore. However
27 | # you should judge for yourself, the pros and cons are mentioned at:
28 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29 | #
30 | # vendor/Pods/
31 |
32 | ## Documentation cache and generated files:
33 | /.yardoc/
34 | /_yardoc/
35 | /doc/
36 | /rdoc/
37 |
38 | ## Environment normalization:
39 | /.bundle/
40 | /vendor/bundle
41 | /lib/bundler/man/
42 |
43 | # for a library or gem, you might want to ignore these files since the code is
44 | # intended to run in multiple environments; otherwise, check them in:
45 | Gemfile.lock
46 | .ruby-version
47 | .ruby-gemset
48 |
49 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50 | .rvmrc
51 |
52 | **/.byebug_history
53 |
54 | # omit compiled documents
55 | samples/**/*.html
56 | README.html
57 |
58 | # omit cache of remote shared rubocop config
59 | .rubocop-https---raw-githubusercontent-com-riboseinc-oss-guides-master-style--rubocop-yml
--------------------------------------------------------------------------------
/lib/citeproc/ruby/formats/adoc.rb:
--------------------------------------------------------------------------------
1 | require "citeproc/ruby/format"
2 |
3 | module CiteProc
4 | module Ruby
5 | module Formats
6 | class Adoc < Format
7 | def apply_font_style
8 | output.replace "_#{output}_" if options[:'font-style'] == "italic"
9 | end
10 |
11 | # TODO
12 | # def apply_font_variant
13 | # output.replace "*#{output}*" if options[:'font-variant'] == 'small-caps'
14 | # end
15 |
16 | def apply_font_weight
17 | output.replace "*#{output}*" if options[:'font-weight'] == "bold"
18 | end
19 |
20 | # TODO
21 | # def apply_text_decoration
22 | # output.replace "*#{output}*" if options[:'text-decoration'] == 'underline'
23 | # end
24 |
25 | def apply_vertical_align
26 | output.replace "^#{output}^" if options[:"vertical-align"] == "sup"
27 | output.replace "~#{output}~" if options[:"vertical-align"] == "sub"
28 | end
29 |
30 | def apply_suffix
31 | options[:suffix] += " " if aligned_first_field?
32 | super
33 | end
34 |
35 | private
36 |
37 | def aligned_first_field?
38 | return node.root.bibliography.layout.children.first == node if aligned_first_accessible?
39 | false
40 | end
41 |
42 | def aligned_first_accessible?
43 | !(node.root.is_a? CSL::Locale) &&
44 | node.root.respond_to?(:bibliography) &&
45 | node.root.bibliography["second-field-align"]
46 | end
47 | end
48 | end
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealp_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealp macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealp:[Erdos65]", options: options)).
10 | to eq "1"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealp:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "1, 2"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealp:[Erdos65, prefix=see]", options: options)).
20 | to eq "see 1"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealp:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "1, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealp:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see 1, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealp:[Erdos65, page=41-43]", options: options)).
35 | to eq "1, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealp:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "1, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citep_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citep macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citep:[Erdos65]", options: options)).
10 | to eq "[1]"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citep:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "[1, 2]"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citep:[Erdos65, prefix=see]", options: options)).
20 | to eq "[see 1]"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citep:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "[1, new edition]"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citep:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "[see 1, new edition]"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citep:[Erdos65, page=41-43]", options: options)).
35 | to eq "[1, pp. 41-43]"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citep:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "[1, somewhere]"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeps_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citep* macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citep*:[Erdos65]", options: options)).
10 | to eq "[1]"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citep*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "[1, 2]"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citep*:[Erdos65, prefix=see]", options: options)).
20 | to eq "[see 1]"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citep*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "[1, new edition]"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citep*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "[see 1, new edition]"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citep*:[Erdos65, page=41-43]", options: options)).
35 | to eq "[1, pp. 41-43]"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citep*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "[1, somewhere]"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealps_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealp* macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealp*:[Erdos65]", options: options)).
10 | to eq "1"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealp*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "1, 2"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealp*:[Erdos65, prefix=see]", options: options)).
20 | to eq "see 1"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealp*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "1, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealp*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see 1, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealp*:[Erdos65, page=41-43]", options: options)).
35 | to eq "1, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealp*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "1, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/samples/tex/sample-authoryear.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-tex-style: authoryear
4 | :bibliography-style: apa
5 |
6 | ## Citations
7 |
8 | citet:[Anderson04] (citet, single)
9 |
10 | citet:[Lane12a]+[Lane12b] (citet, multiple)
11 |
12 | citet*:[Anderson04] (citet*, single)
13 |
14 | citet*:[Lane12a]+[Lane12b] (citet*, multiple)
15 |
16 | citealt:[Anderson04] (citealt, single)
17 |
18 | citealt:[Lane12a]+[Lane12b] (citealt, multiple)
19 |
20 | citealt*:[Anderson04] (citealt*, single)
21 |
22 | citealt*:[Lane12a]+[Lane12b] (citealt*, multiple)
23 |
24 | citep:[Anderson04] (citep, single)
25 |
26 | citep:[Lane12a]+[Lane12b] (citep, multiple)
27 |
28 | citep*:[Anderson04] (citep*, single)
29 |
30 | citep*:[Lane12a]+[Lane12b] (citep*, multiple)
31 |
32 | citealp:[Anderson04] (citealp, single)
33 |
34 | citealp:[Lane12a]+[Lane12b] (citealp, multiple)
35 |
36 | citealp*:[Anderson04] (citealp*, single)
37 |
38 | citealp*:[Lane12a]+[Lane12b] (citealp*, multiple)
39 |
40 | citeauthor:[Anderson04] (citeauthor, single)
41 |
42 | citeauthor:[Lane12a]+[Lane12b] (citeauthor, multiple)
43 |
44 | citeauthor*:[Anderson04] (citeauthor*, single)
45 |
46 | citeauthor*:[Lane12a]+[Lane12b] (citeauthor*, multiple)
47 |
48 | citeyear:[Anderson04] (citeyear, single)
49 |
50 | citeyear:[Lane12a]+[Lane12b] (citeyear, multiple)
51 |
52 | citeyearpar:[Anderson04] (citeyearpar, single)
53 |
54 | citeyearpar:[Lane12a]+[Lane12b] (citeyearpar, multiple)
55 |
56 | fullcite:[Anderson04] (fullcite)
57 |
58 |
59 | ## Bibliography
60 |
61 |
62 | bibliography::[]
63 |
64 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeyear_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeyear macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeyear:[Erdos65]", options: options)).
10 | to eq "1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeyear:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "1965, 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeyear:[Erdos65, prefix=see]", options: options)).
20 | to eq "see 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeyear:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeyear:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeyear:[Erdos65, page=41-43]", options: options)).
35 | to eq "1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeyear:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/samples/tex/sample-numbers.adoc:
--------------------------------------------------------------------------------
1 | = Sample usage of asciidoctor-bibliography
2 | :bibliography-database: biblio.bib
3 | :bibliography-tex-style: numeric
4 | :bibliography-style: ieee
5 |
6 |
7 | ## Citations
8 |
9 |
10 | citet:[Anderson04] (citet, single)
11 |
12 | citet:[Lane12a]+[Lane12b] (citet, multiple)
13 |
14 | citet*:[Anderson04] (citet*, single)
15 |
16 | citet*:[Lane12a]+[Lane12b] (citet*, multiple)
17 |
18 | citealt:[Anderson04] (citealt, single)
19 |
20 | citealt:[Lane12a]+[Lane12b] (citealt, multiple)
21 |
22 | citealt*:[Anderson04] (citealt*, single)
23 |
24 | citealt*:[Lane12a]+[Lane12b] (citealt*, multiple)
25 |
26 | citep:[Anderson04] (citep, single)
27 |
28 | citep:[Lane12a]+[Lane12b] (citep, multiple)
29 |
30 | citep*:[Anderson04] (citep*, single)
31 |
32 | citep*:[Lane12a]+[Lane12b] (citep*, multiple)
33 |
34 | citealp:[Anderson04] (citealp, single)
35 |
36 | citealp:[Lane12a]+[Lane12b] (citealp, multiple)
37 |
38 | citealp*:[Anderson04] (citealp*, single)
39 |
40 | citealp*:[Lane12a]+[Lane12b] (citealp*, multiple)
41 |
42 | citeauthor:[Anderson04] (citeauthor, single)
43 |
44 | citeauthor:[Lane12a]+[Lane12b] (citeauthor, multiple)
45 |
46 | citeauthor*:[Anderson04] (citeauthor*, single)
47 |
48 | citeauthor*:[Lane12a]+[Lane12b] (citeauthor*, multiple)
49 |
50 | citeyear:[Anderson04] (citeyear, single)
51 |
52 | citeyear:[Lane12a]+[Lane12b] (citeyear, multiple)
53 |
54 | citeyearpar:[Anderson04] (citeyearpar, single)
55 |
56 | citeyearpar:[Lane12a]+[Lane12b] (citeyearpar, multiple)
57 |
58 | fullcite:[Anderson04] (fullcite)
59 |
60 |
61 | ## Bibliography
62 |
63 |
64 | bibliography::[]
65 |
66 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeyear_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeyear macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeyear:[Erdos65]", options: options)).
10 | to eq "1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeyear:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "1965; 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeyear:[Erdos65, prefix=see]", options: options)).
20 | to eq "see 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeyear:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeyear:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeyear:[Erdos65, page=41-43]", options: options)).
35 | to eq "1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeyear:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeyearpar_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeyearpar macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeyearpar:[Erdos65]", options: options)).
10 | to eq "[1965]"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeyearpar:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "[1965, 1935]"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeyearpar:[Erdos65, prefix=see]", options: options)).
20 | to eq "[see 1965]"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeyearpar:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "[1965, new edition]"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeyearpar:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "[see 1965, new edition]"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeyearpar:[Erdos65, page=41-43]", options: options)).
35 | to eq "[1965, pp. 41-43]"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeyearpar:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "[1965, somewhere]"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeyearpar_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeyearpar macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeyearpar:[Erdos65]", options: options)).
10 | to eq "(1965)"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeyearpar:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "(1965; 1935)"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeyearpar:[Erdos65, prefix=see]", options: options)).
20 | to eq "(see 1965)"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeyearpar:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "(1965, new edition)"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeyearpar:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "(see 1965, new edition)"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeyearpar:[Erdos65, page=41-43]", options: options)).
35 | to eq "(1965, pp. 41-43)"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeyearpar:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "(1965, somewhere)"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/rfc_v2_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "cite macro with rfc-v2 style" do
6 | let(:options) { { "bibliography-style" => "rfc-v2", "bibliography-database" => "database.rfc.xml", "bibliography-passthrough" => "true", "bibliography-prepend-empty" => "false" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("cite:[RFC2119]", options: options)).
10 | to eq '++++++'
11 | end
12 |
13 | it "formats a single citation with locator" do
14 | expect(formatted_citation("cite:[RFC2119, section=1.2.3]", options: options)).
15 | to eq '++++++'
16 | end
17 |
18 | it "formats a single bibliography entry" do
19 | expect(formatted_bibliography("cite:[RFC2119]", options: options)).
20 | to eq '+++Key words for use in RFCs to Indicate Requirement LevelsIn many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.+++'
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/spec/csl/styles/rfc_v3_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "cite macro with rfc-v3 style" do
6 | let(:options) { { "bibliography-style" => "rfc-v3", "bibliography-database" => "database.rfc.xml", "bibliography-passthrough" => "true", "bibliography-prepend-empty" => "false" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("cite:[RFC2119]", options: options)).
10 | to eq '++++++'
11 | end
12 |
13 | it "formats a single citation with locator" do
14 | expect(formatted_citation("cite:[RFC2119, section=1.2.3]", options: options)).
15 | to eq '++++++'
16 | end
17 |
18 | it "formats a single bibliography entry" do
19 | expect(formatted_bibliography("cite:[RFC2119]", options: options)).
20 | to eq '+++Key words for use in RFCs to Indicate Requirement LevelsIn many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.+++'
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/database.rb:
--------------------------------------------------------------------------------
1 | require_relative "databases/bibtex"
2 | require_relative "databases/rfc"
3 | require_relative "errors"
4 |
5 | module AsciidoctorBibliography
6 | # This is an array of citeproc entries.
7 | class Database < Array
8 | def initialize(*filepaths)
9 | filepaths.each do |filepath|
10 | append filepath
11 | end
12 | end
13 |
14 | def append(filepath)
15 | concat Database.load(filepath)
16 | ensure_no_conflicts!
17 | self
18 | end
19 |
20 | def find_entry_by_id(id)
21 | result = detect { |entry| entry["id"] == id }
22 | if result.nil?
23 | message = "No entry with id '#{id}' was found in the bibliographic database."
24 | raise Errors::Database::IdNotFound, message
25 | end
26 | result
27 | end
28 |
29 | def self.load(filepath)
30 | raise Errors::Database::FileNotFound, filepath unless File.exist?(filepath)
31 |
32 | fileext = File.extname filepath
33 | case fileext
34 | when *Databases::BibTeX::EXTENSIONS
35 | Databases::BibTeX.load filepath
36 | when *Databases::RFC::EXTENSIONS
37 | Databases::RFC.load filepath
38 | else
39 | raise Errors::Database::UnsupportedFormat, fileext
40 | end
41 | end
42 |
43 | private
44 |
45 | def ensure_no_conflicts!
46 | ids = map { |entry| entry["id"] }
47 | conflicting_ids = ids.select { |id| ids.count(id) > 1 }.uniq.sort
48 | raise Errors::Database::ConflictingIds, <<~MESSAGE if conflicting_ids.any?
49 | Conflicting ids were found during database import: #{conflicting_ids}.
50 | MESSAGE
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealt_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealt macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealt:[Erdos65]", options: options)).
10 | to eq "Erdős et al. 1"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealt:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al. 1, Einstein et al. 2"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealt:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős et al. see 1"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealt:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al. 1, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealt:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős et al. see 1, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealt:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al. 1, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealt:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al. 1, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeauthor_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeauthor macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeauthor:[Erdos65]", options: options)).
10 | to eq "Erdős et al."
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeauthor:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al., Einstein et al."
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeauthor:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős et al."
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeauthor:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al., new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeauthor:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős et al., new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeauthor:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al., pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeauthor:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al., somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeauthor_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeauthor macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeauthor:[Erdos65]", options: options)).
10 | to eq "Erdős et al."
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeauthor:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al.; Einstein et al."
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeauthor:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős et al."
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeauthor:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al., new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeauthor:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős et al., new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeauthor:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al., pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeauthor:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al., somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealt_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealt macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealt:[Erdos65]", options: options)).
10 | to eq "Erdős et al. 1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealt:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al. 1965; Einstein et al. 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealt:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős et al. see 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealt:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al. 1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealt:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős et al. see 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealt:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al. 1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealt:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al. 1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citet_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citet macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citet:[Erdos65]", options: options)).
10 | to eq "Erdős et al. (1965)"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citet:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al. (1965); Einstein et al. (1935)"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citet:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős et al. (see 1965)"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citet:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al. (1965, new edition)"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citet:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős et al. (see 1965, new edition)"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citet:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al. (1965, pp. 41-43)"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citet:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al. (1965, somewhere)"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citep_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citep macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citep:[Erdos65]", options: options)).
10 | to eq "(Erdős et al., 1965)"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citep:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "(Erdős et al., 1965; Einstein et al., 1935)"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citep:[Erdos65, prefix=see]", options: options)).
20 | to eq "(see Erdős et al., 1965)"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citep:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "(Erdős et al., 1965, new edition)"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citep:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "(see Erdős et al., 1965, new edition)"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citep:[Erdos65, page=41-43]", options: options)).
35 | to eq "(Erdős et al., 1965, pp. 41-43)"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citep:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "(Erdős et al., 1965, somewhere)"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealp_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealp macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealp:[Erdos65]", options: options)).
10 | to eq "Erdős et al., 1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealp:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al., 1965; Einstein et al., 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealp:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős et al., 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealp:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al., 1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealp:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős et al., 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealp:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al., 1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealp:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al., 1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/fixtures/database-issue84.bib:
--------------------------------------------------------------------------------
1 |
2 | @article{baran_distributed_1964,
3 | title = {On distributed communications networks},
4 | volume = {12},
5 | issn = {0096-1965},
6 | number = {1},
7 | journal = {IEEE transactions on Communications Systems},
8 | author = {Baran, Paul},
9 | year = {1964},
10 | pages = {1--9},
11 | file = {Bar64.pdf:https://www.rand.org/pubs/papers/P2626.html:text/html}
12 | }
13 |
14 | @article{lukasik_why_2011,
15 | title = {Why the {Arpanet} {Was} {Built}},
16 | volume = {33},
17 | issn = {1058-6180},
18 | url = {http://ieeexplore.ieee.org/document/5432117/},
19 | doi = {10.1109/MAHC.2010.11},
20 | language = {en},
21 | number = {3},
22 | urldate = {2019-02-20},
23 | journal = {IEEE Annals of the History of Computing},
24 | author = {Lukasik, Stephen},
25 | month = mar,
26 | year = {2011},
27 | pages = {4--21},
28 | file = {Lukasik - 2011 - Why the Arpanet Was Built.pdf:application/pdf}
29 | }
30 |
31 | @inproceedings{roberts_arpanet_1986,
32 | title = {The {Arpanet} and computer networks},
33 | isbn = {0-89791-176-8},
34 | publisher = {ACM},
35 | author = {Roberts, Larry},
36 | year = {1986},
37 | pages = {51--58},
38 | file = {p51-roberts.pdf:application/pdf}
39 | }
40 |
41 | @article{dommering_internet:_2015,
42 | title = {The {Internet}: a global free space with limited state control},
43 | shorttitle = {The {Internet}},
44 | url = {https://dare.uva.nl/search?identifier=8672fb24-0825-4bdb-98ac-989e370446ae},
45 | language = {en},
46 | urldate = {2019-02-20},
47 | author = {Dommering, E. and van Ginkel, B. and de Goede, M. and Koops, B. J. and Plooij-van Gorsel, E. and Verrijn Stuart, H. and Smallenbroek, J.},
48 | year = {2015},
49 | file = {THE INTERNET A GLOBAL FREE SPACE WITH LIMITED STAT.pdf:application/pdf}
50 | }
51 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citet_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citet macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citet:[Erdos65]", options: options)).
10 | to eq "Erdős et al. [1]"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citet:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős et al. [1], Einstein et al. [2]"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citet:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős et al. [see 1]"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citet:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős et al. [1, new edition]"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citet:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős et al. [see 1, new edition]"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citet:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős et al. [1, pp. 41-43]"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citet:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős et al. [1, somewhere]"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealts_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealt* macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealt*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer 1"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealt*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer 1, Einstein, Podolsky, and Rosen 2"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealt*:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős, Heyting, and Brouwer see 1"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealt*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer 1, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealt*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős, Heyting, and Brouwer see 1, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealt*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer 1, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealt*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer 1, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeauthors_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeauthor* macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeauthor*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeauthor*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer, Einstein, Podolsky, and Rosen"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeauthor*:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős, Heyting, and Brouwer"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeauthor*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeauthor*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős, Heyting, and Brouwer, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeauthor*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeauthor*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/databases/rfc.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "nokogiri"
4 |
5 | module AsciidoctorBibliography
6 | module Databases
7 | module RFC
8 | EXTENSIONS = %w[.rfc .xml].freeze
9 |
10 | MONTHS = %w{january february march april may june july
11 | august september october november december}.freeze
12 |
13 | def self.load(filename)
14 | ::Nokogiri::XML(File.open(filename)).
15 | xpath("//reference").
16 | map { |reference_tag| tag_to_citeproc reference_tag }
17 | end
18 |
19 | def self.tag_to_citeproc(reference_tag)
20 | {
21 | "id" => reference_tag.attr("anchor"),
22 | "author" => get_author_list(reference_tag),
23 | "title" => reference_tag.xpath("//title").first&.text&.strip,
24 | "issued" => {
25 | "date-parts" => get_date_parts(reference_tag)
26 | },
27 | # NOTE: we keep the original XML to re-render it when needed
28 | "note" => reference_tag.to_xml
29 | }
30 | end
31 |
32 | def self.get_date_parts(reference_tag)
33 | date_tag = reference_tag.xpath("//date").first
34 | year = date_tag&.attr("year")
35 | month = date_tag&.attr("month")
36 | day = date_tag&.attr("day")
37 | month = MONTHS.index(month.downcase) + 1 unless month.nil?
38 | [year, month, day].take_while { |date_part| !date_part.nil? }.map(&:to_s)
39 | end
40 |
41 | def self.get_author_list(reference_tag)
42 | author_tags = reference_tag.xpath("//author")
43 | author_tags.map do |author_tag|
44 | {
45 | "family" => author_tag&.attr("surname"),
46 | "given" => author_tag&.attr("initials")
47 | }
48 | end
49 | end
50 | end
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeauthors_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citeauthor* macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citeauthor*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citeauthor*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer; Einstein, Podolsky, and Rosen"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citeauthor*:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős, Heyting, and Brouwer"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citeauthor*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citeauthor*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős, Heyting, and Brouwer, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citeauthor*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citeauthor*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealts_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealt* macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealt*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer 1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealt*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer 1965; Einstein, Podolsky, and Rosen 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealt*:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős, Heyting, and Brouwer see 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealt*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer 1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealt*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős, Heyting, and Brouwer see 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealt*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer 1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealt*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer 1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citets_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citet* macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citet*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer (1965)"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citet*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer (1965); Einstein, Podolsky, and Rosen (1935)"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citet*:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős, Heyting, and Brouwer (see 1965)"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citet*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer (1965, new edition)"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citet*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős, Heyting, and Brouwer (see 1965, new edition)"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citet*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer (1965, pp. 41-43)"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citet*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer (1965, somewhere)"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citeps_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citep* macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citep*:[Erdos65]", options: options)).
10 | to eq "(Erdős, Heyting, and Brouwer, 1965)"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citep*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "(Erdős, Heyting, and Brouwer, 1965; Einstein, Podolsky, and Rosen, 1935)"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citep*:[Erdos65, prefix=see]", options: options)).
20 | to eq "(see Erdős, Heyting, and Brouwer, 1965)"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citep*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "(Erdős, Heyting, and Brouwer, 1965, new edition)"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citep*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "(see Erdős, Heyting, and Brouwer, 1965, new edition)"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citep*:[Erdos65, page=41-43]", options: options)).
35 | to eq "(Erdős, Heyting, and Brouwer, 1965, pp. 41-43)"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citep*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "(Erdős, Heyting, and Brouwer, 1965, somewhere)"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citealps_authoryear_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citealp* macro with authoryear style" do
6 | let(:options) { { "bibliography-tex-style" => "authoryear", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citealp*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer, 1965"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citealp*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer, 1965; Einstein, Podolsky, and Rosen, 1935"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citealp*:[Erdos65, prefix=see]", options: options)).
20 | to eq "see Erdős, Heyting, and Brouwer, 1965"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citealp*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer, 1965, new edition"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citealp*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "see Erdős, Heyting, and Brouwer, 1965, new edition"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citealp*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer, 1965, pp. 41-43"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citealp*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer, 1965, somewhere"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/citation_helper.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "asciidoctor-bibliography"
4 |
5 | def init_bibliographer(options: {})
6 | bibliographer = AsciidoctorBibliography::Bibliographer.new
7 |
8 | opts = options.dup
9 |
10 | db_path = File.join __dir__, "fixtures", opts.delete("bibliography-database")
11 | bibliographer.database = AsciidoctorBibliography::Database.new.append db_path
12 |
13 | bibliographer.options =
14 | AsciidoctorBibliography::Options.new.
15 | merge(
16 | "bibliography-hyperlinks" => "false",
17 | "bibliography-prepend-empty" => "false",
18 | ).merge(opts)
19 |
20 | bibliographer
21 | end
22 |
23 | def formatted_citation(macro, options: {})
24 | bibliographer = init_bibliographer options: options
25 |
26 | macro.gsub(AsciidoctorBibliography::Citation::REGEXP) do
27 | macro_name, macro_pars = Regexp.last_match.captures
28 | target_and_attributes_list_pairs = macro_pars.scan(AsciidoctorBibliography::Citation::MACRO_PARAMETERS_REGEXP)
29 | citation = AsciidoctorBibliography::Citation.new(macro_name, *target_and_attributes_list_pairs)
30 | bibliographer.add_citation(citation)
31 | citation.render bibliographer
32 | end
33 | end
34 |
35 | def formatted_bibliography(macro, options: {})
36 | bibliographer = init_bibliographer options: options
37 | macro.gsub(AsciidoctorBibliography::Citation::REGEXP) do
38 | macro_name, macro_pars = Regexp.last_match.captures
39 | target_and_attributes_list_pairs = macro_pars.scan(AsciidoctorBibliography::Citation::MACRO_PARAMETERS_REGEXP)
40 | citation = AsciidoctorBibliography::Citation.new(macro_name, *target_and_attributes_list_pairs)
41 | bibliographer.add_citation(citation)
42 | # citation.render bibliographer
43 | index = AsciidoctorBibliography::Index.new("bibliography", "", "")
44 | index.render(bibliographer).join
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/spec/csl/styles/tex_citets_numeric_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "../../citation_helper"
4 |
5 | describe "citet* macro with numeric style" do
6 | let(:options) { { "bibliography-tex-style" => "numeric", "bibliography-database" => "database.bib" } }
7 |
8 | it "formats a single citation" do
9 | expect(formatted_citation("citet*:[Erdos65]", options: options)).
10 | to eq "Erdős, Heyting, and Brouwer [1]"
11 | end
12 |
13 | it "formats a grouped citation" do
14 | expect(formatted_citation("citet*:[Erdos65]+[Einstein35]", options: options)).
15 | to eq "Erdős, Heyting, and Brouwer [1], Einstein, Podolsky, and Rosen [2]"
16 | end
17 |
18 | it "formats a single citation with a prefix" do
19 | expect(formatted_citation("citet*:[Erdos65, prefix=see]", options: options)).
20 | to eq "Erdős, Heyting, and Brouwer [see 1]"
21 | end
22 |
23 | it "formats a single citation with a suffix" do
24 | expect(formatted_citation("citet*:[Erdos65, suffix=new edition]", options: options)).
25 | to eq "Erdős, Heyting, and Brouwer [1, new edition]"
26 | end
27 |
28 | it "formats a single citation with both a prefix and a suffix" do
29 | expect(formatted_citation("citet*:[Erdos65, prefix=see, suffix=new edition]", options: options)).
30 | to eq "Erdős, Heyting, and Brouwer [see 1, new edition]"
31 | end
32 |
33 | it "formats a single citation with a standard locator" do
34 | expect(formatted_citation("citet*:[Erdos65, page=41-43]", options: options)).
35 | to eq "Erdős, Heyting, and Brouwer [1, pp. 41-43]"
36 | end
37 |
38 | it "formats a single citation with a custom locator" do
39 | expect(formatted_citation("citet*:[Erdos65, locator=somewhere]", options: options)).
40 | to eq "Erdős, Heyting, and Brouwer [1, somewhere]"
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/citeproc/ruby/formats/adoc_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "asciidoctor-bibliography"
4 | require_relative "../../../citation_helper"
5 |
6 | describe CiteProc::Ruby::Formats::Adoc do
7 | before { processor.import(BibTeX.open("spec/fixtures/database.bib").to_citeproc) }
8 |
9 | context "using apa citations" do
10 | let(:processor) { CiteProc::Processor.new(style: "apa", format: "adoc") }
11 | let(:year) { processor.engine.style.citation.children["layout"].children[0].children[1] }
12 | let(:rendered_citation) { processor.render(:citation, id: "Gettier63") }
13 |
14 | describe ".apply_font_style" do
15 | it "makes journal italic" do
16 | year["font-style"] = "italic"
17 | expect(rendered_citation).to eq("(Gettier, _1963_)")
18 | end
19 | end
20 |
21 | describe ".apply_font_weight" do
22 | it "makes journal bold" do
23 | year["font-weight"] = "bold"
24 | expect(rendered_citation).to eq("(Gettier, *1963*)")
25 | end
26 | end
27 |
28 | describe ".apply_vertical_align" do
29 | it "makes journal supscript " do
30 | year["vertical-align"] = "sup"
31 | expect(rendered_citation).to eq("(Gettier, ^1963^)")
32 | end
33 |
34 | it "makes journal subscript " do
35 | year["vertical-align"] = "sub"
36 | expect(rendered_citation).to eq("(Gettier, ~1963~)")
37 | end
38 | end
39 | end
40 |
41 | context "using ieee bibliography" do
42 | let(:processor) { CiteProc::Processor.new(style: "ieee", format: "adoc") }
43 | let(:rendered_bibliography) { processor.render(:bibliography, id: "Gettier63").first }
44 |
45 | describe ".apply_suffix" do
46 | before { processor.import(BibTeX.open("spec/fixtures/database.bib").to_citeproc) }
47 | it "adds space between first and second field" do
48 | processor.items["Gettier63"].merge("citation-number": "0")
49 | expect(rendered_bibliography).to match(/^\[0\] E. L. Gettier/)
50 | end
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/spec/nocite_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "asciidoctor-bibliography"
4 |
5 | describe "a typical usage of nocite" do
6 | let(:document) do
7 | input = <<~'ASCIIDOC'
8 | :bibliography-database: ./spec/fixtures/database.bib
9 | :bibliography-style: apa
10 |
11 | == Hidden citations
12 | Nothing here: nocite:[Lane12a].
13 | Nothing here: nocite:[Erdos65]+special[Einstein35].
14 |
15 | == Default bibliography
16 | bibliography::[]
17 |
18 | == Special bibliography
19 | bibliography::special[]
20 | ASCIIDOC
21 | document = ::Asciidoctor::Document.new(input)
22 | document.parse
23 | document
24 | end
25 |
26 | it "hides citations and show references" do
27 | expect(document.convert).to eq <<~HTML.rstrip
28 |
29 |
Hidden citations
30 |
31 |
32 |
Nothing here: .
33 | Nothing here: .
34 |
35 |
36 |
37 |
38 |
Default bibliography
39 |
40 |
41 |
Erdős, P., Heyting, A., & Brouwer, L. E. (1965). Some very hard sums. Difficult Maths Today, 30.
42 |
43 |
44 |
Lane, P. (2000). Book title. Publisher.
45 |
46 |
47 |
48 |
49 |
Special bibliography
50 |
51 |
52 |
Einstein, A., Podolsky, B., & Rosen, N. (1935). Can quantum-mechanical description of physical reality be considered complete? Physical Review, 47(10), 777.
53 |
54 |
55 |
56 | HTML
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/asciidoctor-bibliography.gemspec:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | lib = File.expand_path("../lib", __FILE__)
4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5 | require "asciidoctor-bibliography/version"
6 |
7 | Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8 | spec.name = "asciidoctor-bibliography"
9 | spec.version = AsciidoctorBibliography::VERSION
10 | spec.authors = ["Ribose Inc."]
11 | spec.email = ["open.source@ribose.com"]
12 |
13 | spec.summary = 'Citations and bibliography the "asciidoctor-way"'
14 | spec.description = <<~SPEC
15 | asciidoctor-bibliography lets you handle citations and bibliography the "asciidoctor-way"!
16 |
17 | Its syntax is designed to be native-asciidoctor:
18 | * single cite `cite:[key]`;
19 | * contextual cite `cite[key, page=3]`;
20 | * multiple cites `cite:[key1]+[key2]`;
21 | * full cite `fullcite:[key]`; and
22 | * TeX-compatible macros including `citep:[key]`, `citet:[key]` and friends.
23 |
24 | Citation output styles are fully bridged to the CSL library, supporting formats such as IEEE, APA, Chicago, DIN and ISO 690.
25 |
26 | The `bibliography::[]` command generates a full reference list that adheres to your configured citation style.
27 | SPEC
28 |
29 | spec.homepage = "https://github.com/riboseinc/asciidoctor-bibliography"
30 | spec.license = "MIT"
31 |
32 | spec.require_paths = ["lib"]
33 | spec.files = `git ls-files`.split("\n")
34 | spec.test_files = `git ls-files -- {spec}/*`.split("\n")
35 | spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
36 |
37 | spec.add_dependency "asciidoctor", ">= 1.5.6"
38 | spec.add_dependency "bibtex-ruby", "~> 6.0.0"
39 | spec.add_dependency "citeproc-ruby", "~> 1.1.7"
40 | spec.add_dependency "csl-styles", "~> 1.0.1"
41 | spec.add_dependency "latex-decode", "~> 0.2.2"
42 | spec.add_dependency "nokogiri", "~> 1.8"
43 |
44 | spec.add_development_dependency "byebug"
45 | spec.add_development_dependency "rake", "~> 12.3"
46 | spec.add_development_dependency "rspec", "~> 3.7"
47 | spec.add_development_dependency "rubocop"
48 | spec.add_development_dependency "simplecov"
49 | spec.add_development_dependency "yard"
50 | end
51 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/databases/bibtex.rb:
--------------------------------------------------------------------------------
1 | require "bibtex"
2 | require "bibtex/filters"
3 | require "latex/decode/base"
4 | require "latex/decode/maths"
5 | require "latex/decode/accents"
6 | require "latex/decode/diacritics"
7 | require "latex/decode/punctuation"
8 | require "latex/decode/symbols"
9 | require "latex/decode/greek"
10 |
11 | module AsciidoctorBibliography
12 | module Databases
13 | module BibTeX
14 | EXTENSIONS = %w[.bib .bibtex .biblatex].freeze
15 |
16 | def self.load(filename)
17 | # TODO: detect BibLaTeX code w/ other extensions
18 | warn <<~MESSAGE if File.extname(filename) == '.biblatex'
19 | WARNING: you are requiring a BibLaTeX database; only features compatible with BibTeX are guaranteed to work.
20 | MESSAGE
21 | ::BibTeX.open(filename, filter: [LatexFilter]).to_citeproc
22 | end
23 |
24 | # NOTE: the class below comes from asciidoctor-bibtex
25 |
26 | # This filter extends the original latex filter in bibtex-ruby to handle
27 | # unknown latex macros more gracefully. We could have used latex-decode
28 | # gem together with our custom replacement rules, but latex-decode eats up
29 | # all braces after it finishes all decoding. So we hack over the
30 | # LaTeX.decode function and insert our rules before `strip_braces`.
31 | class LatexFilter < ::BibTeX::Filter
32 | def apply(value) # rubocop:disable Metrics/MethodLength; keep this a list, though!
33 | text = value.to_s
34 | LaTeX::Decode::Base.normalize(text)
35 | LaTeX::Decode::Maths.decode!(text)
36 | LaTeX::Decode::Accents.decode!(text)
37 | LaTeX::Decode::Diacritics.decode!(text)
38 | LaTeX::Decode::Punctuation.decode!(text)
39 | LaTeX::Decode::Symbols.decode!(text)
40 | LaTeX::Decode::Greek.decode!(text)
41 | # TODO: could we be doing something smarter with some macros, e.g. \url?
42 | text.gsub!(/\\url\{(.+?)\}/, ' \\1 ')
43 | text.gsub!(/\\\w+(?=\s+\w)/, "")
44 | text.gsub!(/\\\w+(?:\[.+?\])?\s*\{(.+?)\}/, '\\1')
45 | LaTeX::Decode::Base.strip_braces(text)
46 | LaTeX.normalize_C(text)
47 | end
48 | end
49 | end
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/spec/fixtures/database.bib:
--------------------------------------------------------------------------------
1 | @book{Lane12a,
2 | author = {P. Lane},
3 | title = {Book title},
4 | publisher = {Publisher},
5 | year = {2000}
6 | }
7 |
8 | @book{Lane12b,
9 | author = {K. Mane and D. Smith},
10 | title = {Book title},
11 | publisher = {Publisher},
12 | year = {2000}
13 | }
14 |
15 | @book{Anderson98,
16 | editor = {J. R. Anderson and C. Lebiere},
17 | title = {The Atomic Components of {2\sum} Thought},
18 | publisher = {Lawrence Erlbaum},
19 | address = {Mahwah, NJ},
20 | year = {1998}
21 | }
22 |
23 | @article{Anderson04,
24 | author = {J. R. Anderson and D. Bothell and M. D. Byrne and S. Douglass and C. Lebiere and Y. L. Qin},
25 | title = {An integrated theory of the mind},
26 | journal = {Psychological Review},
27 | volume = {111},
28 | number = {4},
29 | pages = {1036--1060},
30 | year = {2004}
31 | }
32 |
33 | @article{Erdos65,
34 | title = {Some very hard sums},
35 | journal={Difficult Maths Today},
36 | author={Paul Erdős and Arend Heyting and Luitzen Egbertus Brouwer},
37 | year={1965},
38 | pages={30}
39 | }
40 |
41 | @article{Einstein35,
42 | title={Can quantum-mechanical description of physical reality be considered complete?},
43 | author={Einstein, Albert and Podolsky, Boris and Rosen, Nathan},
44 | journal={Physical review},
45 | volume={47},
46 | number={10},
47 | pages={777},
48 | year={1935},
49 | publisher={APS}
50 | }
51 |
52 | @article{Gettier63,
53 | title={Is justified true belief knowledge?},
54 | author={Gettier, Edmund L},
55 | journal={analysis},
56 | volume={23},
57 | number={6},
58 | pages={121--123},
59 | year={1963},
60 | publisher={JSTOR}
61 | }
62 |
63 | @techreport{iso:31000,
64 | author = {ISO},
65 | institution = {International Organization for Standardization},
66 | address = {Geneva, Switzerland},
67 | title = {Risk management---Principles and guidelines},
68 | number = {31000:2009},
69 | shorthand = {ISO 31000:2009},
70 | type = {ISO},
71 | year = {2009}
72 | }
73 |
74 | @techreport{iso:guide73,
75 | author = {ISO},
76 | institution = {International Organization for Standardization},
77 | address = {Geneva, Switzerland},
78 | title = {Risk management---Vocabulary},
79 | number = {73:2009(E/F)},
80 | shorthand = {ISO Guide 73:2009},
81 | type = {ISO Guide},
82 | year = {2013}
83 | }
84 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/index.rb:
--------------------------------------------------------------------------------
1 | require "asciidoctor/attribute_list"
2 | require_relative "formatter"
3 |
4 | module AsciidoctorBibliography
5 | class Index
6 | REGEXP = /^(bibliography)::(\S+)?\[(|.*?[^\\])\]$/
7 |
8 | attr_reader :macro, :target, :attributes
9 |
10 | def initialize(macro, target, attributes)
11 | @macro = macro
12 | @target = target.to_s.empty? ? "default" : target
13 | @attributes = ::Asciidoctor::AttributeList.new(attributes).parse
14 | end
15 |
16 | def render(bibliographer)
17 | formatter = setup_formatter bibliographer
18 |
19 | lines = []
20 | formatter.bibliography.each_with_index do |reference, index|
21 | id = anchor_id "bibliography", target, formatter.data[index].id
22 | lines << wrap_up_reference(reference: reference, id: id, bibliographer: bibliographer)
23 | end
24 |
25 | # Intersperse the lines with empty ones to render as paragraphs.
26 | lines.join("\n\n").lines.map(&:strip)
27 | end
28 |
29 | private
30 |
31 | def wrap_up_reference(reference:, id:, bibliographer:)
32 | text = reference.dup
33 | text.prepend "anchor:#{id}[]" if bibliographer.options.hyperlinks?
34 | text = ["+++", reference, "+++"].join if bibliographer.options.passthrough?(:reference)
35 | text.prepend "{empty}" if bibliographer.options.prepend_empty?(:reference)
36 | text
37 | end
38 |
39 | def setup_formatter(bibliographer)
40 | formatter = Formatter.new(bibliographer.options.style, locale: bibliographer.options.locale)
41 |
42 | formatter.replace_bibliography_sort bibliographer.options.sort unless bibliographer.options.sort.nil?
43 |
44 | filtered_db = prepare_filtered_db bibliographer
45 | formatter.import filtered_db
46 | formatter.force_sort!(mode: :bibliography)
47 |
48 | formatter
49 | end
50 |
51 | def prepare_filtered_db(bibliographer)
52 | if bibliographer.occurring_keys.include? target
53 | bibliographer.occurring_keys[target].
54 | map { |id| bibliographer.database.find_entry_by_id(id) }.
55 | map { |entry| prepare_entry_metadata bibliographer, entry }
56 | else {}
57 | end
58 | end
59 |
60 | def prepare_entry_metadata(bibliographer, entry)
61 | entry.
62 | merge('citation-number': bibliographer.appearance_index_of(target, entry["id"])).
63 | merge('citation-label': entry["id"]) # TODO: smart label generators
64 | end
65 |
66 | def anchor_id(*fragments)
67 | fragments.compact.join("-")
68 | end
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/spec/end_to_end_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require "asciidoctor-bibliography"
4 | require "asciidoctor-bibliography/asciidoctor/bibliographer_preprocessor"
5 |
6 | describe "an asciidoctor document with bibliography usage" do
7 | let(:document) do
8 | input = <<~'ASCIIDOC'
9 | = This is the document title
10 | :doctype: book
11 | :bibliography-database: ./spec/fixtures/database-issue84.bib
12 | :bibliography-style: university-of-york-mla
13 | == Section 1
14 | The Advanced Research Projects Agency Network (ARPANET),
15 | an early network connecting many major universities and
16 | research institutions in the USA,
17 | was first demonstrated publicly in October 1972
18 | cite:[roberts_arpanet_1986, page=3].
19 | It was initially funded by the United States
20 | Department of Defense during the cold war as a part of
21 | "the command and control assignment" of the ARPA program
22 | cite:[lukasik_why_2011, page=10].
23 | The ((ARPANET)) was designed to be "as distributed as possible,"
24 | because its routing algorithm was adapted from an article by Paul Baran,
25 | written at the time he was at the RAND Corporation researching
26 | on highly survivable communication networks "in the thermonuclear era"
27 | cite:[baran_distributed_1964, page=18].
28 | With the support of the US National Science Foundation, ARPANET gradually
29 | "evolved into a commercial, worldwide open network" -- the Internet
30 | cite:[dommering_internet:_2015, page=13].
31 | [bibliography]
32 | == Bibliography
33 | bibliography::[]
34 | ASCIIDOC
35 | document = ::Asciidoctor::Document.new(input)
36 | document.parse
37 | document
38 | end
39 |
40 | it "creates a valid internal bibliographer state" do
41 | expect(document.bibliographer.occurring_keys["default"]).
42 | to eq ["roberts_arpanet_1986",
43 | "lukasik_why_2011",
44 | "baran_distributed_1964",
45 | "dommering_internet:_2015"]
46 | end
47 |
48 | it "generates the correct mla bibliography" do
49 | expect(document.catalog[:refs]["_bibliography"].blocks[0].lines[0]).
50 | to include("Baran, Paul.")
51 | expect(document.catalog[:refs]["_bibliography"].blocks[1].lines[0]).
52 | to include("Dommering, E., et al.")
53 | expect(document.catalog[:refs]["_bibliography"].blocks[2].lines[0]).
54 | to include("Lukasik, Stephen.")
55 | expect(document.catalog[:refs]["_bibliography"].blocks[3].lines[0]).
56 | to include("Roberts, Larry.")
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/spec/database_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | describe AsciidoctorBibliography::Database do
4 | describe ".new" do
5 | it "is by default an empty array" do
6 | expect(described_class.new).to eq([])
7 | end
8 |
9 | it "can be initialized with a single database" do
10 | expect(described_class.new("spec/fixtures/database.bib")).to_not eq([])
11 | end
12 |
13 | it "can be initialized with a list of databases" do
14 | expect(described_class.new("spec/fixtures/database.bib", "spec/fixtures/database.bibtex")).to_not eq([])
15 | end
16 | end
17 |
18 | describe "#find_entry_by_id" do
19 | subject { described_class.new("spec/fixtures/database.bib") }
20 |
21 | it "finds an existing id" do
22 | expect { subject.find_entry_by_id("foo") }.
23 | to raise_exception AsciidoctorBibliography::Errors::Database::IdNotFound
24 | end
25 |
26 | it "raises error if asked to retrieve unexisting id" do
27 | expect(subject.find_entry_by_id("Lane12a")).
28 | to eq("author" => [{ "family" => "Lane", "given" => "P." }],
29 | "title" => "Book title",
30 | "publisher" => "Publisher",
31 | "id" => "Lane12a",
32 | "issued" => { "date-parts" => [[2000]] },
33 | "type" => "book")
34 | end
35 | end
36 |
37 | describe "#append" do
38 | let(:db) { described_class.new }
39 |
40 | it "can load and concatenate databases after initialization" do
41 | expect(db.length).to eq(0)
42 | expect { db.append("spec/fixtures/database.bib") }.to(change { db.length })
43 | expect { db.append("spec/fixtures/database.bibtex") }.to(change { db.length })
44 | end
45 |
46 | it "raises error if conflicting ids are found" do
47 | db.append("spec/fixtures/database.bib")
48 | expect { db.append("spec/fixtures/database.bib") }.
49 | to raise_exception AsciidoctorBibliography::Errors::Database::ConflictingIds
50 | end
51 | end
52 |
53 | describe ".load" do
54 | it "raises error if given non existing file" do
55 | expect { described_class.load "spec/fixtures/database.xxx" }.
56 | to raise_exception AsciidoctorBibliography::Errors::Database::FileNotFound
57 | end
58 |
59 | it "raises error if given unknown format" do
60 | expect { described_class.load "spec/fixtures/database.unk" }.
61 | to raise_exception AsciidoctorBibliography::Errors::Database::UnsupportedFormat
62 | end
63 |
64 | it "recognizes Bib(La)Tex databases" do
65 | expect { described_class.load "spec/fixtures/database.bib" }.to_not raise_exception
66 | expect { described_class.load "spec/fixtures/database.bibtex" }.to_not raise_exception
67 | end
68 | end
69 | end
70 |
--------------------------------------------------------------------------------
/spec/macros_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | require_relative "citation_helper"
4 |
5 | describe "cite macro with apa style" do
6 | it "formats a complex citation" do
7 | expect(formatted_citation("cite:[Erdos65, prefix='see ']+[Einstein35, page=41-43]",
8 | options: { "bibliography-style" => "apa",
9 | "bibliography-database" => "database.bib",
10 | "bibliography-hyperlinks" => "true" })).
11 | to eq "(<>; " +
12 | "<>)"
13 | end
14 | end
15 |
16 | describe "cite macro with arbitrary interpolated text" do
17 | it "formats a complex citation" do
18 | expect(formatted_citation("cite:[Erdos65, text=foo {cite} bar]",
19 | options: { "bibliography-style" => "apa",
20 | "bibliography-database" => "database.bib",
21 | "bibliography-hyperlinks" => "true" })).
22 | to eq "(<>)"
23 | end
24 | end
25 |
26 | describe "fullcite macro with apa style" do
27 | it "formats a complex citation" do
28 | expect(formatted_citation("fullcite:[Erdos65]",
29 | options: { "bibliography-style" => "apa",
30 | "bibliography-database" => "database.bib" })).
31 | to eq "Erdős, P., Heyting, A., & Brouwer, L. E. (1965). Some very hard sums. _Difficult Maths Today_, 30."
32 | end
33 | end
34 |
35 | describe "cite macro using an unknown key" do
36 | it "formats bold question marks" do
37 | expect(formatted_citation("cite:[Erdos65]+[foobar]",
38 | options: { "bibliography-style" => "apa",
39 | "bibliography-database" => "database.bib",
40 | "bibliography-hyperlinks" => "true" })).
41 | to eq "*??*"
42 | end
43 | end
44 |
45 | describe "cite macro using more than two keys" do
46 | it "formats all cited keys" do
47 | expect(formatted_citation("cite:[Lane12a]+[Lane12b]+[Erdos65]+[Einstein35]",
48 | options: { "bibliography-style" => "apa",
49 | "bibliography-database" => "database.bib",
50 | "bibliography-hyperlinks" => "true" })).
51 | to eq "(<>; <>; <>; <>)"
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/SYNTAX.adoc:
--------------------------------------------------------------------------------
1 | = asciidoctor-bibliography Syntax
2 |
3 | We base our syntax off the asciidoctor `footnoteref` command.
4 |
5 | [source,ruby]
6 | ----
7 | footnoteref:[ref,Opinions are my own.]
8 | footnoteref:[ref]
9 | ----
10 |
11 | asciidoctor supports these commands now:
12 |
13 | Attributes:
14 | [source,ruby]
15 | ----
16 | video::video_file.mp4[width=640, start=60, end=140, options=autoplay]
17 | ----
18 |
19 | Options:
20 | [source,ruby]
21 | ----
22 | audio::ocean_waves.mp3[options="autoplay,loop"]
23 | ----
24 |
25 | The "and" syntax:
26 |
27 | [source,ruby]
28 | ----
29 | \ifdef::env-github+backend-html5[HTML5 only.]
30 | ----
31 |
32 |
33 | == Proposed Syntax
34 |
35 | === Basic Usage
36 |
37 | [source,ruby]
38 | ----
39 | # Output => "[1]"
40 | cite:[foo]
41 |
42 | # Output => "[1, Page 5]"
43 | cite:[foo, page=5]
44 |
45 | # Output => "[1, Page 5; 2, Chapter 21]"
46 | cite:[foo, page=5]+[foobar, chapter=21]
47 |
48 | # Output => "[1, 2]"
49 | # or => "[1-2]"
50 | cite:[foo]+[foobar]
51 |
52 | # Output => "[1, 3]"
53 | cite:[foo]+[bar]
54 | ----
55 |
56 | === BibTeX-compatible Usage
57 |
58 | [source,ruby]
59 | ----
60 | # BibTeX \citet{goossens93}
61 | # Output: "Goossens et al. (1993)"
62 | citet:[goossens93]
63 | cite:[goossens93]
64 | cite:[goossens93, authors=abbrev, format="%authors% (%year%)"]
65 |
66 | # BibTeX \citet{goossens93}
67 | # Output "(Goossens et al., 1993)"
68 | citep:[goossens93]
69 | cite:[goossens93, type=parens]
70 | cite:[goossens93, authors=abbrev, format="(%authors%, %year%)"]
71 |
72 | # BibTeX \citet*{goossens93}
73 | # Output "Goossens, Mittlebach, and Samarin (1993)"
74 | citets:[goossens93]
75 | cite:[goossens93, authors=full, type=text]
76 | cite:[goossens93, authors=full, format="%authors% (%year%)"]
77 |
78 | # BibTeX \citep*{goossens93}
79 | # Output "(Goossens, Mittlebach, and Samarin, 1993)"
80 | citeps:[goossens93]
81 | cite:[goossens93, authors=full, type=parens]
82 | cite:[goossens93, authors=full, format="(%authors%, %year%)"]
83 |
84 | # BibTeX \citeauthor{goossens93}
85 | # Output "Goossens et al."
86 | citeauthor:[goossens93]
87 | cite:[goossens93, only=authors, authors=abbrev]
88 | cite:[goossens93, authors=abbrev, format="%authors%"]
89 |
90 | # BibTeX \citeauthor*{goossens93}
91 | # Output => "Goossens, Mittlebach, and Samarin"
92 | citeauthors:[goossens93]
93 | cite:[goossens93, only=authors, authors=full]
94 | cite:[goossens93, authors=full, format="%authors%"]
95 |
96 | # BibTeX \citeyear{goossens93}
97 | # Output => "1993"
98 | citeyear:[goossens93]
99 | cite:[goossens93, only=year]
100 | cite:[goossens93, format="%year%"]
101 |
102 | # BibTeX \citeyearpar{goossens93}
103 | # Output => "(1993)"
104 | citeyear:[goossens93]
105 | cite:[goossens93, format="(%year%)"]
106 |
107 | # BibTeX \citealt{goossens93}
108 | # Output => "Goossens et al. 1993"
109 | citealt:[goossens93]
110 | cite:[goossens93, authors=abbrev, format="%authors% %year%"]
111 |
112 | # BibTeX \citealp{goossens93}
113 | # Output => "Goossens et al., 1993"
114 | citealp:[goossens93]
115 | cite:[goossens93, authors=abbrev, format="%authors%, %year%"]
116 | ----
117 |
118 |
--------------------------------------------------------------------------------
/lib/asciidoctor-bibliography/asciidoctor/bibliographer_preprocessor.rb:
--------------------------------------------------------------------------------
1 | require "asciidoctor"
2 |
3 | require_relative "../database"
4 | require_relative "../citation"
5 | require_relative "../index"
6 | require_relative "../options"
7 |
8 | module AsciidoctorBibliography
9 | module Asciidoctor
10 | class BibliographerPreprocessor < ::Asciidoctor::Extensions::Preprocessor
11 | def process(document, reader)
12 | document.bibliographer.options =
13 | ::AsciidoctorBibliography::Options.build document, reader
14 |
15 | document.bibliographer.database =
16 | ::AsciidoctorBibliography::Database.new *expand_db_globs(document)
17 |
18 | lines = remove_comments(reader.read_lines)
19 | processed_lines = process_lines lines, document.bibliographer
20 | reader.unshift_lines processed_lines
21 | reader
22 | end
23 |
24 | private
25 |
26 | def process_lines(lines, bibliographer)
27 | # First we fetch citations and replace them with uuids,
28 | lines = fetch_citations lines, bibliographer
29 | # then we render them
30 | lines = render_citations lines, bibliographer
31 | # and finally we render indices.
32 | render_indices lines, bibliographer
33 | end
34 |
35 | def remove_comments(lines)
36 | # Remove block comments
37 | ls = lines.join("\n").split(/^\/\/\/\/\n/).
38 | select.with_index { |_, i| i.even? }.join
39 | # Remove line comments
40 | ls.split("\n").reject { |line| line.start_with?("//") }
41 | end
42 |
43 | def fetch_citations(lines, bibliographer)
44 | lines.join("\n").gsub(Citation::REGEXP) do
45 | macro_name, macro_pars = Regexp.last_match.captures
46 | target_and_attributes_list_pairs = macro_pars.scan(Citation::MACRO_PARAMETERS_REGEXP)
47 | citation = Citation.new(macro_name, *target_and_attributes_list_pairs)
48 | bibliographer.add_citation(citation)
49 | citation.uuid
50 | end.lines.map(&:chomp)
51 | end
52 |
53 | def render_citations(lines, bibliographer)
54 | processed_lines = lines.join("\n")
55 | bibliographer.citations.each do |citation|
56 | processed_lines.sub!(citation.uuid) do
57 | citation.render bibliographer
58 | end
59 | end
60 | processed_lines.lines.map(&:chomp)
61 | end
62 |
63 | def render_indices(lines, bibliographer)
64 | lines.map do |line|
65 | if line =~ Index::REGEXP
66 | index = Index.new(*Regexp.last_match.captures)
67 | index.render bibliographer
68 | else
69 | line
70 | end
71 | end.flatten
72 | end
73 |
74 | def expand_db_globs(document)
75 | glob_pattern(
76 | document.bibliographer.options.database,
77 | document.base_dir,
78 | )
79 | end
80 |
81 | def glob_pattern(pattern_string, base_dir)
82 | pattern_string.split.map do |pattern|
83 | Dir.chdir(base_dir) { Dir.glob(normalize_separator(pattern)) }
84 | end.flatten
85 | end
86 |
87 | def normalize_separator(path)
88 | return path if File::ALT_SEPARATOR.nil?
89 | path.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
90 | end
91 | end
92 | end
93 | end
94 |
--------------------------------------------------------------------------------
/spec/citation_item_spec.rb:
--------------------------------------------------------------------------------
1 | describe AsciidoctorBibliography::CitationItem do
2 | describe ".new" do
3 | it "can be mutely initialized" do
4 | expect { described_class.new }.to_not raise_exception
5 | end
6 |
7 | it "can be initialized with a block operating on itself" do
8 | itself = nil
9 | expect(described_class.new { |ci| itself = ci }).to be(itself)
10 | end
11 | end
12 |
13 | describe "#parse_attribute_list" do
14 | subject { described_class.new }
15 |
16 | before do
17 | subject.parse_attribute_list "foo, lol=bar, baz, qux, zod=13"
18 | end
19 |
20 | it "treats the first positional attribute as the id" do
21 | expect(subject.key).to eq "foo"
22 | end
23 |
24 | it "extracts the positional attributes in order, except the first one" do
25 | expect(subject.positional_attributes).to eq ["baz", "qux"]
26 | end
27 |
28 | it "extracts all named attributes" do
29 | expect(subject.named_attributes).to eq("lol" => "bar", "zod" => "13")
30 | end
31 | end
32 |
33 | describe "#locators" do
34 | subject { described_class.new }
35 |
36 | it "returns no locator if none are present" do
37 | subject.parse_attribute_list "foo, lol=bar, baz, qux, zod=42"
38 | expect(subject.locator).to be_nil
39 | end
40 |
41 | it "recognizes all CSL locators" do
42 | locators = %w[book chapter column figure folio issue line note opus
43 | page paragraph part section sub-verbo verse volume]
44 | locators_hash = locators.map { |l| [l, rand(10).to_s] }.to_h
45 | locators_string = locators_hash.to_a.map { |a| a.join "=" }.join(", ")
46 |
47 | subject.parse_attribute_list "foo, #{locators_string}"
48 | expect(subject.locators).to eq locators_hash
49 | end
50 |
51 | it "recognizes non standard locator" do
52 | subject.parse_attribute_list "foo, locator=' somewhere'"
53 | expect(subject.locators).to eq("locator" => " somewhere")
54 | end
55 | end
56 |
57 | describe "#locator" do
58 | subject { described_class.new }
59 |
60 | it "returns the first locator if existing" do
61 | subject.parse_attribute_list("foo, page=42, locator=bar, chapter=24")
62 | expect(subject.locator).to eq(%w[page 42])
63 | end
64 |
65 | it "returns nil if no loctor exist" do
66 | subject.parse_attribute_list("foo, bar, zod=quz")
67 | expect(subject.locator).to be_nil
68 | end
69 | end
70 |
71 | describe "#prefix" do
72 | subject { described_class.new }
73 |
74 | it "returns the prefix if it exist" do
75 | subject.parse_attribute_list("foo, prefix=bar")
76 | expect(subject.prefix).to eq("bar")
77 | end
78 |
79 | it "returns nil if no prefix exists" do
80 | subject.parse_attribute_list("foo, bar, zod=quz")
81 | expect(subject.prefix).to be_nil
82 | end
83 | end
84 |
85 | describe "#suffix" do
86 | subject { described_class.new }
87 |
88 | it "returns the suffix if it exist" do
89 | subject.parse_attribute_list("foo, suffix=bar")
90 | expect(subject.suffix).to eq("bar")
91 | end
92 |
93 | it "returns nil if no suffix exists" do
94 | subject.parse_attribute_list("foo, bar, zod=quz")
95 | expect(subject.suffix).to be_nil
96 | end
97 | end
98 |
99 | describe "#text" do
100 | subject { described_class.new }
101 |
102 | it "returns the text if it exist" do
103 | subject.parse_attribute_list("foo, text='prefix {ref} suffix'")
104 | expect(subject.text).to eq("prefix {ref} suffix")
105 | end
106 |
107 | it "returns nil if no text exists" do
108 | subject.parse_attribute_list("foo, bar, zod=quz")
109 | expect(subject.text).to be_nil
110 | end
111 | end
112 | end
113 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealp-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealps-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeauthor-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeauthors-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeauthor-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeauthors-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citep-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeps-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeyear-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeyear-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeyearpar-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeyearpar-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
117 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealp-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
118 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealps-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
118 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citep-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
118 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citeps-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
118 |
--------------------------------------------------------------------------------
/spec/fixtures/database.rfc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Key words for use in RFCs to Indicate Requirement Levels
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Writing I-Ds and RFCs using XML
24 |
25 |
26 |
27 |
28 |
29 |
30 | This memo presents a technique for using XML (Extensible Markup Language) as a source format for documents in the Internet-Drafts (I-Ds) and Request for Comments (RFC) series. This memo provides information for the Internet community.
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Guidelines for Writing RFC Text on Security Considerations
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | All RFCs are required to have a Security Considerations section. Historically, such sections have been relatively weak. This document provides guidelines to RFC authors on how to write a good Security Considerations section. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Guidelines for Writing an IANA Considerations Section in RFCs
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Many protocols make use of identifiers consisting of constants and other well-known values. Even after a protocol has been defined and deployment has begun, new values may need to be assigned (e.g., for a new option type in DHCP, or a new encryption or authentication transform for IPsec). To ensure that such quantities have consistent values and interpretations across all implementations, their assignment must be administered by a central authority. For IETF protocols, that role is provided by the Internet Assigned Numbers Authority (IANA).
74 |
75 |
76 | In order for IANA to manage a given namespace prudently, it needs guidelines describing the conditions under which new values can be assigned or when modifications to existing values can be made. If IANA is expected to play a role in the management of a namespace, IANA must be given clear and concise instructions describing that role. This document discusses issues that should be considered in formulating a policy for assigning values to a namespace and provides guidelines for authors on the specific text that must be included in documents that place demands on IANA.
77 |
78 |
79 | This document obsoletes RFC 2434. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealt-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealts-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citet-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citets-numeric.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealt-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citealts-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citet-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------
/lib/csl/styles/tex-citets-authoryear.csl:
--------------------------------------------------------------------------------
1 |
2 |
120 |
--------------------------------------------------------------------------------