├── .github └── workflows │ ├── docs.yml │ ├── lint.yml │ └── tests.yml ├── .gitignore ├── .rubocop.yml ├── .simplecov ├── CHANGES.md ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENCE ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── cff.gemspec ├── lib ├── cff.rb └── cff │ ├── citable.rb │ ├── entity.rb │ ├── errors.rb │ ├── file.rb │ ├── formatters.rb │ ├── formatters │ ├── all.rb │ ├── apalike.rb │ ├── bibtex.rb │ └── formatter.rb │ ├── identifier.rb │ ├── index.rb │ ├── licensable.rb │ ├── model_part.rb │ ├── person.rb │ ├── reference.rb │ ├── schema.rb │ ├── schemas │ └── 1.2.0.json │ ├── util.rb │ ├── validatable.rb │ └── version.rb └── test ├── cff_test.rb ├── citable_test.rb ├── entity_test.rb ├── errors_test.rb ├── file_test.rb ├── files ├── bad │ ├── CITATION.cff │ └── incomplete.cff ├── complete.cff ├── formatted │ ├── TUe-excellent-buildings_BSO-toolbox.apa │ ├── TUe-excellent-buildings_BSO-toolbox.bibtex │ ├── TUe-excellent-buildings_BSO-toolbox_invalid_date.apa │ ├── TUe-excellent-buildings_BSO-toolbox_invalid_date.bibtex │ ├── bjmorgan_bsym.apa │ ├── bjmorgan_bsym.bibtex │ ├── citation-file-format_citation-file-format.apa │ ├── citation-file-format_citation-file-format.bibtex │ ├── esalmela_HaploWinder.apa │ ├── esalmela_HaploWinder.bibtex │ ├── example-1.apa │ ├── example-1.bibtex │ ├── ls1mardyn_ls1-mardyn.apa │ ├── ls1mardyn_ls1-mardyn.bibtex │ ├── preferred-citation-advance.apa │ ├── preferred-citation-advance.bibtex │ ├── preferred-citation-book-missing.apa │ ├── preferred-citation-book-missing.bibtex │ ├── preferred-citation-book.apa │ ├── preferred-citation-book.bibtex │ ├── preferred-citation-conference-paper-2.apa │ ├── preferred-citation-conference-paper-2.bibtex │ ├── preferred-citation-conference-paper-missing.apa │ ├── preferred-citation-conference-paper-missing.bibtex │ ├── preferred-citation-conference-paper-with-escapes.apa │ ├── preferred-citation-conference-paper-with-escapes.bibtex │ ├── preferred-citation-conference-paper.apa │ ├── preferred-citation-conference-paper.bibtex │ ├── preferred-citation-in-prep.apa │ ├── preferred-citation-in-prep.bibtex │ ├── preferred-citation-in-press.apa │ ├── preferred-citation-in-press.bibtex │ ├── preferred-citation-journal-with-escapes.apa │ ├── preferred-citation-journal-with-escapes.bibtex │ ├── preferred-citation-manual.apa │ ├── preferred-citation-manual.bibtex │ ├── preferred-citation-masters-thesis-no-type.apa │ ├── preferred-citation-masters-thesis-no-type.bibtex │ ├── preferred-citation-masters-thesis.apa │ ├── preferred-citation-masters-thesis.bibtex │ ├── preferred-citation-no-issue.apa │ ├── preferred-citation-no-issue.bibtex │ ├── preferred-citation-no-month.apa │ ├── preferred-citation-no-month.bibtex │ ├── preferred-citation-no-vol.apa │ ├── preferred-citation-no-vol.bibtex │ ├── preferred-citation-pamphlet.apa │ ├── preferred-citation-pamphlet.bibtex │ ├── preferred-citation-phd-thesis-no-type.apa │ ├── preferred-citation-phd-thesis-no-type.bibtex │ ├── preferred-citation-phd-thesis.apa │ ├── preferred-citation-phd-thesis.bibtex │ ├── preferred-citation-report-no-affiliation.apa │ ├── preferred-citation-report-no-affiliation.bibtex │ ├── preferred-citation-report-no-institution.apa │ ├── preferred-citation-report-no-institution.bibtex │ ├── preferred-citation-report.apa │ ├── preferred-citation-report.bibtex │ ├── preferred-citation-submitted.apa │ ├── preferred-citation-submitted.bibtex │ ├── preferred-citation-unpublished.apa │ ├── preferred-citation-unpublished.bibtex │ ├── reprozip.apa │ ├── reprozip.bibtex │ ├── short-with-aliases.apa │ ├── short-with-aliases.bibtex │ ├── smith-et-al.apa │ ├── smith-et-al.bibtex │ ├── software-missing-family-name.apa │ ├── software-missing-family-name.bibtex │ ├── software-missing-given-name.apa │ ├── software-missing-given-name.bibtex │ ├── software-with-alias.apa │ ├── software-with-alias.bibtex │ ├── software-with-escapes.apa │ ├── software-with-escapes.bibtex │ ├── tidyverse-joss-paper.apa │ ├── tidyverse-joss-paper.bibtex │ ├── tidyverse-software.apa │ ├── tidyverse-software.bibtex │ ├── xenon-middleware_xenon-adaptors-cloud.apa │ └── xenon-middleware_xenon-adaptors-cloud.bibtex ├── formatter │ ├── TUe-excellent-buildings_BSO-toolbox.cff │ ├── TUe-excellent-buildings_BSO-toolbox_invalid_date.cff │ ├── bjmorgan_bsym.cff │ ├── citation-file-format_citation-file-format.cff │ ├── esalmela_HaploWinder.cff │ ├── example-1.cff │ ├── ls1mardyn_ls1-mardyn.cff │ ├── ls1mardyn_ls1-mardyn_invalid_author_array.cff │ ├── preferred-citation-advance.cff │ ├── preferred-citation-book-missing.cff │ ├── preferred-citation-book.cff │ ├── preferred-citation-conference-paper-2.cff │ ├── preferred-citation-conference-paper-missing.cff │ ├── preferred-citation-conference-paper-with-escapes.cff │ ├── preferred-citation-conference-paper.cff │ ├── preferred-citation-in-prep.cff │ ├── preferred-citation-in-press.cff │ ├── preferred-citation-journal-with-escapes.cff │ ├── preferred-citation-manual.cff │ ├── preferred-citation-masters-thesis-no-type.cff │ ├── preferred-citation-masters-thesis.cff │ ├── preferred-citation-no-issue.cff │ ├── preferred-citation-no-month.cff │ ├── preferred-citation-no-vol.cff │ ├── preferred-citation-pamphlet.cff │ ├── preferred-citation-phd-thesis-no-type.cff │ ├── preferred-citation-phd-thesis.cff │ ├── preferred-citation-report-no-affiliation.cff │ ├── preferred-citation-report-no-institution.cff │ ├── preferred-citation-report.cff │ ├── preferred-citation-submitted.cff │ ├── preferred-citation-unpublished.cff │ ├── reprozip.cff │ ├── short-with-aliases.cff │ ├── smith-et-al.cff │ ├── software-missing-family-name.cff │ ├── software-missing-given-name.cff │ ├── software-with-alias.cff │ ├── software-with-escapes.cff │ ├── tidyverse-joss-paper.cff │ ├── tidyverse-software.cff │ └── xenon-middleware_xenon-adaptors-cloud.cff ├── minimal.cff ├── short.cff └── validation │ ├── aliases.cff │ └── partial-reference.cff ├── formatters ├── apalike_test.rb ├── bibtex_test.rb └── formatter_test.rb ├── formatters_test.rb ├── identifier_test.rb ├── index_test.rb ├── person_test.rb ├── reference_test.rb ├── test_helper.rb ├── util_test.rb └── validatable_test.rb /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | docs: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout rubyzip code 13 | uses: actions/checkout@v3 14 | 15 | - name: Install and set up ruby 16 | uses: ruby/setup-ruby@v1 17 | with: 18 | ruby-version: 2.6 19 | bundler-cache: true 20 | 21 | - name: Run RDoc 22 | run: bundle exec rake rdoc 23 | 24 | - name: Deploy 25 | uses: JamesIves/github-pages-deploy-action@v4 26 | with: 27 | branch: gh-pages 28 | folder: html 29 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Linter 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout rubyzip code 10 | uses: actions/checkout@v3 11 | 12 | - name: Install and set up ruby 13 | uses: ruby/setup-ruby@v1 14 | with: 15 | ruby-version: 2.6 16 | bundler-cache: true 17 | 18 | - name: Rubocop 19 | run: bundle exec rubocop 20 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | os: [ubuntu] 11 | ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', head, jruby, jruby-head, truffleruby, truffleruby-head] 12 | include: 13 | - os: macos 14 | ruby: '3.0' 15 | - os: windows 16 | ruby: '3.0' 17 | runs-on: ${{ matrix.os }}-latest 18 | continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.os == 'windows' }} 19 | steps: 20 | - name: Checkout rubyzip code 21 | uses: actions/checkout@v3 22 | 23 | - name: Install and set up ruby 24 | uses: ruby/setup-ruby@v1 25 | with: 26 | ruby-version: ${{ matrix.ruby }} 27 | bundler-cache: true 28 | 29 | - name: Run the tests 30 | env: 31 | RUBYOPT: -v 32 | JRUBY_OPTS: --debug 33 | run: bundle exec rake 34 | 35 | - name: Coveralls 36 | if: matrix.os == 'ubuntu' && !endsWith(matrix.ruby, 'head') 37 | uses: coverallsapp/github-action@master 38 | with: 39 | github-token: ${{ secrets.github_token }} 40 | flag-name: ${{ matrix.ruby }} 41 | parallel: true 42 | 43 | test-isolated: 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Checkout rubyzip code 47 | uses: actions/checkout@v3 48 | 49 | - name: Install and set up ruby 50 | uses: ruby/setup-ruby@v1 51 | with: 52 | ruby-version: '2.7' 53 | bundler-cache: true 54 | 55 | - name: Run isolated tests 56 | run: bundle exec rake test:isolated 57 | 58 | test-yjit: 59 | strategy: 60 | fail-fast: false 61 | matrix: 62 | os: [ubuntu, macos] 63 | ruby: ['3.1', '3.2', head] 64 | runs-on: ${{ matrix.os }}-latest 65 | continue-on-error: true 66 | steps: 67 | - name: Checkout rubyzip code 68 | uses: actions/checkout@v3 69 | 70 | - name: Install and set up ruby 71 | uses: ruby/setup-ruby@v1 72 | with: 73 | ruby-version: ${{ matrix.ruby }} 74 | bundler-cache: true 75 | 76 | - name: Run the tests 77 | env: 78 | RUBYOPT: --enable-yjit -v 79 | run: bundle exec rake 80 | 81 | finish: 82 | needs: test 83 | runs-on: ubuntu-latest 84 | steps: 85 | - name: Coveralls Finished 86 | uses: coverallsapp/github-action@master 87 | with: 88 | github-token: ${{ secrets.github_token }} 89 | parallel-finished: true 90 | -------------------------------------------------------------------------------- /.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 | ## Documentation cache and generated files: 14 | /.yardoc/ 15 | /_yardoc/ 16 | /doc/ 17 | /rdoc/ 18 | /html/ 19 | 20 | ## Environment normalization: 21 | /.bundle/ 22 | /vendor/bundle 23 | /lib/bundler/man/ 24 | .ruby-version 25 | .ruby-gemset 26 | 27 | # for a library or gem, you might want to ignore these files since the code is 28 | # intended to run in multiple environments; otherwise, check them in: 29 | Gemfile.lock 30 | 31 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 32 | .rvmrc 33 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - rubocop-minitest 3 | - rubocop-performance 4 | - rubocop-rake 5 | 6 | # Set our base version of ruby and enable all cops. 7 | AllCops: 8 | TargetRubyVersion: 2.6 9 | NewCops: enable 10 | 11 | # Turn this off for certain files where we have extra documentation 12 | # towards the end of the file, after a block of private methods. 13 | Lint/UselessAccessModifier: 14 | Exclude: 15 | - 'lib/cff/index.rb' 16 | - 'lib/cff/model.rb' 17 | - 'lib/cff/reference.rb' 18 | 19 | # I think 'has_key?' looks better than 'key?'. 20 | Style/PreferredHashMethods: 21 | EnforcedStyle: verbose 22 | 23 | # Allow a non-standard error type. 24 | Style/RaiseArgs: 25 | AllowedCompactTypes: 26 | - ValidationError 27 | - CFF::ValidationError 28 | 29 | # Allow long lines in the tests. 30 | Layout/LineLength: 31 | Max: 100 32 | Exclude: 33 | - 'test/**/*.rb' 34 | 35 | # Force ruby19 style hash keys, but be consistent within a hash. 36 | Style/HashSyntax: 37 | EnforcedStyle: ruby19_no_mixed_keys 38 | 39 | # Enforce %w notation in the library code, but be less strict in tests. 40 | Style/WordArray: 41 | Exclude: 42 | - 'test/**/*.rb' 43 | 44 | # Ignore ABC failures in the tests. 45 | Metrics/AbcSize: 46 | Exclude: 47 | - 'test/**/*.rb' 48 | 49 | # Ignore block length failures in the tests. 50 | Metrics/BlockLength: 51 | Exclude: 52 | - 'cff.gemspec' 53 | - 'test/**/*.rb' 54 | 55 | # Set a more reasonable method length and ignore failures in the tests. 56 | Metrics/MethodLength: 57 | Max: 20 58 | Exclude: 59 | - 'test/**/*.rb' 60 | 61 | # Set a more reasonable class length and ignore failures in the tests. 62 | Metrics/ClassLength: 63 | Max: 150 64 | Exclude: 65 | - 'test/**/*.rb' 66 | 67 | # This is still too high, but we'll get there. 68 | Minitest/MultipleAssertions: 69 | Max: 10 70 | 71 | Style/DocumentDynamicEvalDefinition: 72 | Enabled: true 73 | -------------------------------------------------------------------------------- /.simplecov: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2021 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'simplecov-lcov' 18 | 19 | SimpleCov::Formatter::LcovFormatter.config do |c| 20 | c.output_directory = 'coverage' 21 | c.lcov_file_name = 'lcov.info' 22 | c.report_with_single_file = true 23 | c.single_report_path = 'coverage/lcov.info' 24 | end 25 | 26 | SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new( 27 | [ 28 | SimpleCov::Formatter::HTMLFormatter, 29 | SimpleCov::Formatter::LcovFormatter 30 | ] 31 | ) 32 | 33 | SimpleCov.start do 34 | enable_coverage :branch 35 | add_filter '/test/' 36 | end 37 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # This CITATION.cff file was created by ruby-cff (v 1.3.0). 2 | # Gem: https://rubygems.org/gems/cff 3 | # CFF: https://citation-file-format.github.io/ 4 | 5 | cff-version: 1.2.0 6 | message: If you use ruby-cff in your work, please cite it using the following metadata 7 | title: Ruby CFF Library 8 | abstract: This library provides a Ruby interface to manipulate Citation File Format files 9 | authors: 10 | - family-names: Haines 11 | given-names: Robert 12 | orcid: https://orcid.org/0000-0002-9538-7919 13 | affiliation: The University of Manchester, UK 14 | - name: The Ruby Citation File Format Developers 15 | keywords: 16 | - ruby 17 | - credit 18 | - software citation 19 | - research software 20 | - software sustainability 21 | - metadata 22 | - citation file format 23 | - CFF 24 | version: 1.3.0 25 | doi: 10.5281/zenodo.1184077 26 | date-released: 2024-10-26 27 | license: Apache-2.0 28 | repository-artifact: https://rubygems.org/gems/cff 29 | repository-code: https://github.com/citation-file-format/ruby-cff 30 | references: 31 | - type: software 32 | title: Citation File Format 33 | authors: 34 | - family-names: Druskat 35 | given-names: Stephan 36 | orcid: https://orcid.org/0000-0003-4925-7248 37 | - family-names: Spaaks 38 | given-names: Jurriaan H. 39 | orcid: https://orcid.org/0000-0002-7064-4069 40 | - family-names: Chue Hong 41 | given-names: Neil 42 | orcid: https://orcid.org/0000-0002-8876-7606 43 | - family-names: Haines 44 | given-names: Robert 45 | orcid: https://orcid.org/0000-0002-9538-7919 46 | - family-names: Baker 47 | given-names: James 48 | orcid: https://orcid.org/0000-0002-2682-6922 49 | - family-names: Bliven 50 | given-names: Spencer 51 | orcid: https://orcid.org/0000-0002-1200-1698 52 | email: spencer.bliven@gmail.com 53 | - family-names: Willighagen 54 | given-names: Egon 55 | orcid: https://orcid.org/0000-0001-7542-0286 56 | - family-names: Pérez-Suárez 57 | given-names: David 58 | orcid: https://orcid.org/0000-0003-0784-6909 59 | website: https://dpshelio.github.io 60 | - family-names: Konovalov 61 | given-names: Alexander 62 | orcid: https://orcid.org/0000-0001-5299-3292 63 | identifiers: 64 | - type: doi 65 | value: 10.5281/zenodo.1003149 66 | description: The concept DOI for the collection containing all versions of the Citation File Format. 67 | - type: doi 68 | value: 10.5281/zenodo.5171937 69 | description: The versioned DOI for the version 1.2.0 of the Citation File Format. 70 | keywords: 71 | - citation file format 72 | - CFF 73 | - citation files 74 | - software citation 75 | - file format 76 | - YAML 77 | - software sustainability 78 | - research software 79 | - credit 80 | abstract: CITATION.cff files are plain text files with human- and machine-readable citation information for software. Code developers can include them in their repositories to let others know how to correctly cite their software. This is the specification for the Citation File Format. 81 | date-released: 2021-08-09 82 | license: CC-BY-4.0 83 | version: 1.2.0 84 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at rhaines@manchester.ac.uk. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Ruby CFF Library 2 | ## Introduction 3 | 4 | **Thank you** for considering a contribution to the **Ruby CFF Library**! 5 | 6 | If you intended to contribute to another part of the Citation File Format project, for example the Citation File Format specification itself, please contribute to the respective repository ([list of repositories in the `citation-file-format` GitHub organization](https://github.com/orgs/citation-file-format/repositories)). 7 | 8 | **Please follow these guidelines.** Their purpose is to make both contributing and accepting contributions easier for all parties involved. 9 | 10 | There are many ways to contribute, e.g.: 11 | 12 | * Tell a friend or colleague about the Citation File Format and Ruby CFF, or tweet about it 13 | * Write blog posts, tutorials, etc. about the Citation File Format and Ruby CFF 14 | * Review the format and its schema and documentation 15 | * Improve wording in any prose output, including the specifications 16 | * Create a new, better version of the schema and specifications 17 | * Improve automated tests, continuous integration, documentation, etc. 18 | 19 | ## Ground Rules 20 | 21 | Your contribution to Ruby CFF is valued, and it should be an enjoyable experience. To ensure this there is the Ruby CFF 22 | [Code of Conduct](https://github.com/citation-file-format/ruby-cff/blob/main/CODE_OF_CONDUCT.md) which you are required to follow. 23 | 24 | Please always start any contribution that will change the contents of this repository from [an issue](https://github.com/citation-file-format/ruby-cff/issues). This may mean [creating a new issue](https://github.com/citation-file-format/ruby-cff/issues/new) if it's something that hasn't been requested so far. This way, 25 | 26 | * you can make sure that you don't invest your valuable time in something that may not be merged; and 27 | * we can make sure that your contribution is something that will improve Ruby CFF, is in scope, and aligns with the roadmap for the Ruby CFF and the Citation File Format. 28 | 29 | ## Your First Contribution 30 | 31 | If you are unsure where to begin with your contribution to CFF, have a look at the [open issues in this repository](https://github.com/citation-file-format/ruby-cff/issues), and see if you can identify one that you would like to work on. 32 | 33 | If you have never contributed to an open source project, you may find this tutorial helpful: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github). 34 | 35 | ## Getting started 36 | 37 | This is the workflow for contributions to this repository: 38 | 39 | 1. Take note of the [code of conduct](https://github.com/citation-file-format/ruby-cff/blob/main/CODE_OF_CONDUCT.md) 40 | 1. [Create a new issue](https://github.com/citation-file-format/ruby-cff/issues/new) if needs be, and discuss the changes you want to make with the maintainers and community 41 | 1. Fork the repository 42 | 1. Create a branch in your fork of the repository 43 | 1. Make changes in the new branch in your fork 44 | * Please don't forget tests! 45 | * If you add any classes, modules, methods, attributes, or constants, please document them 46 | 1. Create a pull request 47 | 1. Address any comments that come up during review 48 | 1. If and when your pull request has been merged, you can delete your branch (or the whole forked repository) 49 | 50 | This workflow is loosely based on GitHub flow, and you can find more information in the [GitHub flow documentation](https://docs.github.com/en/get-started/quickstart/github-flow). 51 | 52 | ### Working with tests and documentation 53 | 54 | There is a comprehensive test suite for Ruby CFF, which also contains a collection of test `CITATION.cff` files - both valid and invalid. Please add tests (and new test `CITATION.cff` files if appropriate) for any new features you add, or bugs you squash. It is advised to run these tests locally on your computer prior to submitting a pull request. However, if that's not possible, you still can submit the pull request and later check the status of the tests for your pull request on GitHub. 55 | 56 | To run the tests, assuming that you have all the dependencies installed, simply run: 57 | ```shell 58 | $ rake 59 | ``` 60 | 61 | To rebuild the documentation, if you have added to it or changed it: 62 | ```shell 63 | $ rake rdoc 64 | ``` 65 | Then load `html/index.html` into a Web browser and double check it. 66 | 67 | ## FAQ 68 | 69 | - **These guidelines do not address aspect XYZ! What should I do now?** 70 | 71 | Please [submit an issue](https://github.com/citation-file-format/ruby-cff/issues/new), asking for clarification of and/or an addition to the guidelines. 72 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'bundler/gem_tasks' 18 | require 'minitest/test_task' 19 | require 'rdoc/task' 20 | require 'rubocop/rake_task' 21 | 22 | task default: :test 23 | 24 | Minitest::TestTask.create do |test| 25 | test.test_globs = 'test/**/*_test.rb' 26 | end 27 | 28 | RDoc::Task.new do |r| 29 | r.main = 'README.md' 30 | r.rdoc_files.include( 31 | 'README.md', 'LICENCE', 'CODE_OF_CONDUCT.md', 'CONTRIBUTING.md', 32 | 'CHANGES.md', 'lib/**/*.rb' 33 | ) 34 | r.options << '--markup=markdown' 35 | r.options << '--tab-width=2' 36 | r.options << "-t Ruby CFF Library (version #{::CFF::VERSION})" 37 | end 38 | 39 | RuboCop::RakeTask.new 40 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'bundler/setup' 5 | require 'cff' 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require 'irb' 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | -------------------------------------------------------------------------------- /cff.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'lib/cff/version' 18 | 19 | Gem::Specification.new do |spec| 20 | spec.name = 'cff' 21 | spec.version = CFF::VERSION 22 | spec.authors = [ 23 | 'Robert Haines', 24 | 'The Ruby Citation File Format Developers' 25 | ] 26 | spec.email = ['robert.haines@manchester.ac.uk'] 27 | 28 | spec.summary = 'A Ruby library for manipulating CITATION.cff files.' 29 | spec.description = 'See https://citation-file-format.github.io/ ' \ 30 | 'for more info.' 31 | spec.homepage = 'https://github.com/citation-file-format/ruby-cff' 32 | spec.license = 'Apache-2.0' 33 | 34 | spec.metadata = { 35 | 'bug_tracker_uri' => 'https://github.com/citation-file-format/ruby-cff/issues', 36 | 'changelog_uri' => 'https://github.com/citation-file-format/ruby-cff/blob/main/CHANGES.md', 37 | 'documentation_uri' => 'https://citation-file-format.github.io/ruby-cff/', 38 | 'source_code_uri' => 'https://github.com/citation-file-format/ruby-cff', 39 | 'rubygems_mfa_required' => 'true' 40 | } 41 | 42 | spec.files = `git ls-files -z`.split("\x0").reject do |f| 43 | f.match(%r{^((test|spec|features)/|\.)}) 44 | end 45 | 46 | spec.bindir = 'exe' 47 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 48 | spec.require_paths = ['lib'] 49 | 50 | spec.required_ruby_version = '>= 2.6' 51 | 52 | spec.add_runtime_dependency 'json_schema', '~> 0.20.4' 53 | spec.add_runtime_dependency 'language_list', '~> 1.2.1' 54 | 55 | spec.add_development_dependency 'minitest', '~> 5.16.0' 56 | spec.add_development_dependency 'rake', '~> 13.0' 57 | spec.add_development_dependency 'rdoc', '~> 6.4.0' 58 | spec.add_development_dependency 'rubocop', '~> 1.35.0' 59 | spec.add_development_dependency 'rubocop-minitest', '~> 0.21.0' 60 | spec.add_development_dependency 'rubocop-performance', '~> 1.14.0' 61 | spec.add_development_dependency 'rubocop-rake', '~> 0.6.0' 62 | spec.add_development_dependency 'simplecov', '0.18.3' 63 | spec.add_development_dependency 'simplecov-lcov', '~> 0.8.0' 64 | spec.add_development_dependency 'test_construct', '~> 2.0' 65 | end 66 | -------------------------------------------------------------------------------- /lib/cff.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This library provides a Ruby interface to manipulate CITATION.cff files. The 18 | # primary entry points are Index and File. 19 | # 20 | # See the [CITATION.cff documentation](https://citation-file-format.github.io/) 21 | # for more details. 22 | module CFF; end 23 | 24 | require_relative 'cff/file' 25 | -------------------------------------------------------------------------------- /lib/cff/citable.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'formatters' 18 | 19 | ## 20 | module CFF 21 | # Methods to enable turning a CFF model or file into a citation. 22 | # 23 | # The core functionality is in the `citation` method. In addition, each 24 | # available output format has a `to_{format}` method generated for it as 25 | # well, e.g. `to_bibtex` or `to_apalike`. These methods take a single 26 | # parameter, `preferred_citation:`, which defaults to `true` as in the 27 | # `citation` method. 28 | module Citable 29 | # :call-seq: 30 | # citation(format, preferred_citation: true) -> String 31 | # 32 | # Output this Index in the specified format. Setting 33 | # `preferred_citation: true` will honour the `preferred_citation` field in 34 | # the index if one is present (default). 35 | # 36 | # `format` can be supplied as a String or a Symbol. 37 | # 38 | # Formats that are built-in to Ruby CFF are: 39 | # 40 | # * APAlike (e.g. `:apalike`, `'apalike'` or `'APAlike'`) 41 | # * BibTeX (e.g. `:bibtex`, `'bibtex'` or `'BibTeX'`) 42 | # 43 | # *Note:* This method assumes that this Index is valid when called. 44 | def citation(format, preferred_citation: true) 45 | formatter = Formatters.formatter_for(format) 46 | return '' if formatter.nil? 47 | 48 | formatter.format(model: self, preferred_citation: preferred_citation) 49 | end 50 | 51 | def self.add_to_format_method(format) # :nodoc: 52 | method = "to_#{format}" 53 | return if method_defined?(method) 54 | 55 | class_eval( 56 | # def to_bibtex(preferred_citation: true) 57 | # citation(:bibtex, preferred_citation: preferred_citation) 58 | # end 59 | <<-END_TO_FORMAT, __FILE__, __LINE__ + 1 60 | def #{method}(preferred_citation: true) 61 | citation(:#{format}, preferred_citation: preferred_citation) 62 | end 63 | END_TO_FORMAT 64 | ) 65 | end 66 | 67 | # Add the formatters we know about already upfront. 68 | Formatters.formatters.each do |format| 69 | add_to_format_method(format) 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /lib/cff/entity.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'model_part' 18 | require_relative 'schema' 19 | 20 | ## 21 | module CFF 22 | # An Entity can represent different types of entities, e.g., a publishing 23 | # company, or conference. Like a Person, an Entity might have a number of 24 | # roles, such as author, contact, editor, etc. 25 | # 26 | # Entity implements all of the fields listed in the 27 | # [CFF standard](https://citation-file-format.github.io/). All fields 28 | # are simple strings and can be set as such. A field which has not been set 29 | # will return the empty string. The simple fields are (with defaults in 30 | # parentheses): 31 | # 32 | # * `address` 33 | # * `alias` 34 | # * `city` 35 | # * `country` 36 | # * `date_end` - *Note:* returns a `Date` object 37 | # * `date_start` - *Note:* returns a `Date` object 38 | # * `email` 39 | # * `fax` 40 | # * `location` 41 | # * `name` 42 | # * `orcid` 43 | # * `post_code` 44 | # * `region` 45 | # * `tel` 46 | # * `website` 47 | class Entity < ModelPart 48 | ALLOWED_FIELDS = SCHEMA_FILE['definitions']['entity']['properties'].keys.freeze # :nodoc: 49 | 50 | attr_date :date_end, :date_start 51 | 52 | # :call-seq: 53 | # new(name) -> Entity 54 | # new(name) { |entity| block } -> Entity 55 | # 56 | # Create a new Entity with the supplied name. 57 | def initialize(param) 58 | super() 59 | 60 | if param.is_a?(Hash) 61 | @fields = param 62 | else 63 | @fields = {} 64 | @fields['name'] = param 65 | end 66 | 67 | yield self if block_given? 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/cff/errors.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ## 18 | module CFF 19 | # Error is the base class for all errors raised by this library. 20 | class Error < RuntimeError 21 | def initialize(message = nil) # :nodoc: 22 | super 23 | end 24 | end 25 | 26 | # ValidationError is raised when a CFF file fails validation. It contains 27 | # details of each failure that was detected by the underlying JsonSchema 28 | # library, which is used to perform the validation. 29 | # 30 | # Additionally, the `invalid_filename` flag is used to indicate whether the 31 | # CFF file is named correctly. This is only used when validating a File; 32 | # validating a Index directly will not set this flag to `true`. 33 | class ValidationError < Error 34 | # The list of JsonSchema::ValidationErrors found by the validator. 35 | attr_reader :errors 36 | 37 | # If a File was validated, was its filename invalid? 38 | attr_reader :invalid_filename 39 | 40 | def initialize(errors, invalid_filename: false) # :nodoc: 41 | super('Validation error') 42 | @errors = errors 43 | @invalid_filename = invalid_filename 44 | end 45 | 46 | def to_s # :nodoc: 47 | "#{super}: (Invalid filename: #{@invalid_filename}) #{@errors.join(' ')}" 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/cff/file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2024 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'errors' 18 | require_relative 'index' 19 | require_relative 'version' 20 | 21 | require 'date' 22 | 23 | ## 24 | module CFF 25 | # File provides direct access to a CFF Index, with the addition of some 26 | # filesystem utilities. 27 | # 28 | # To be a fully compliant and valid CFF file its filename should be 29 | # 'CITATION.cff'. This class allows you to create files with any filename, 30 | # and to validate the contents of those files independently of the preferred 31 | # filename. 32 | class File 33 | # A comment to be inserted at the top of the resultant CFF file. 34 | attr_reader :comment 35 | 36 | # The filename of this CFF file. 37 | attr_reader :filename 38 | 39 | YAML_HEADER = "---\n" # :nodoc: 40 | CFF_COMMENT = [ 41 | "This CITATION.cff file was created by ruby-cff (v #{CFF::VERSION}).", 42 | 'Gem: https://rubygems.org/gems/cff', 43 | 'CFF: https://citation-file-format.github.io/' 44 | ].freeze # :nodoc: 45 | CFF_VALID_FILENAME = 'CITATION.cff' # :nodoc: 46 | 47 | # :call-seq: 48 | # new(filename, title) -> File 49 | # new(filename, index) -> File 50 | # 51 | # Create a new File. Either a pre-existing Index can be passed in or, as 52 | # with Index itself, a title can be supplied to initalize a new File. 53 | # 54 | # All methods provided by Index are also available directly on File 55 | # objects. 56 | def initialize(filename, param, comment = CFF_COMMENT, create: false) 57 | param = Index.new(param) unless param.is_a?(Index) 58 | 59 | @filename = filename 60 | @index = param 61 | @comment = comment 62 | @dirty = create 63 | end 64 | 65 | # :call-seq: 66 | # read(filename) -> File 67 | # 68 | # Read a file and parse it for subsequent manipulation. 69 | def self.read(file) 70 | content = ::File.read(file) 71 | comment = File.parse_comment(content) 72 | 73 | new(file, Util.parse_yaml(content), comment) 74 | end 75 | 76 | # :call-seq: 77 | # open(filename) -> File 78 | # open(filename) { |cff| block } 79 | # 80 | # With no associated block, File.open is a synonym for ::read. If the 81 | # optional code block is given, it will be passed the opened file as an 82 | # argument and the File object will automatically be written (if edited) 83 | # and closed when the block terminates. 84 | # 85 | # File.open will create a new file if one does not already exist with the 86 | # provided file name. 87 | def self.open(file) 88 | if ::File.exist?(file) 89 | content = ::File.read(file) 90 | comment = File.parse_comment(content) 91 | yaml = Util.parse_yaml(content) 92 | else 93 | comment = CFF_COMMENT 94 | yaml = '' 95 | end 96 | 97 | cff = new(file, yaml, comment, create: (yaml == '')) 98 | return cff unless block_given? 99 | 100 | begin 101 | yield cff 102 | ensure 103 | cff.write 104 | end 105 | end 106 | 107 | # :call-seq: 108 | # validate(filename, fail_on_filename: true) -> Array 109 | # 110 | # Read a file and return an array with the result. The result array is a 111 | # three-element array, with `true`/`false` at index 0 to indicate 112 | # pass/fail, an array of schema validation errors at index 1 (if any), and 113 | # `true`/`false` at index 2 to indicate whether the filename passed/failed 114 | # validation. 115 | # 116 | # You can choose whether filename validation failure should cause overall 117 | # validation failure with the `fail_on_filename` parameter (default: true). 118 | def self.validate(file, fail_on_filename: true) 119 | File.read(file).validate(fail_on_filename: fail_on_filename) 120 | end 121 | 122 | # :call-seq: 123 | # validate!(filename, fail_on_filename: true) 124 | # 125 | # Read a file and raise a ValidationError upon failure. If an error is 126 | # raised it will contain the detected validation failures for further 127 | # inspection. 128 | # 129 | # You can choose whether filename validation failure should cause overall 130 | # validation failure with the `fail_on_filename` parameter (default: true). 131 | def self.validate!(file, fail_on_filename: true) 132 | File.read(file).validate!(fail_on_filename: fail_on_filename) 133 | end 134 | 135 | # :call-seq: 136 | # write(filename, File) 137 | # write(filename, Index) 138 | # write(filename, yaml) 139 | # 140 | # Write the supplied File, Index or yaml string to `file`. 141 | def self.write(file, cff, comment = '') 142 | comment = cff.comment if cff.respond_to?(:comment) 143 | cff = cff.to_yaml unless cff.is_a?(String) 144 | content = File.format_comment(comment) + cff[YAML_HEADER.length...-1] 145 | 146 | ::File.write(file, content) 147 | end 148 | 149 | # :call-seq: 150 | # validate(fail_fast: false, fail_on_filename: true) -> Array 151 | # 152 | # Validate this file and return an array with the result. The result array 153 | # is a three-element array, with `true`/`false` at index 0 to indicate 154 | # pass/fail, an array of schema validation errors at index 1 (if any), and 155 | # `true`/`false` at index 2 to indicate whether the filename passed/failed 156 | # validation. 157 | # 158 | # You can choose whether filename validation failure should cause overall 159 | # validation failure with the `fail_on_filename` parameter (default: true). 160 | def validate(fail_fast: false, fail_on_filename: true) 161 | valid_filename = (::File.basename(@filename) == CFF_VALID_FILENAME) 162 | result = (@index.validate(fail_fast: fail_fast) << valid_filename) 163 | result[0] &&= valid_filename if fail_on_filename 164 | 165 | result 166 | end 167 | 168 | # :call-seq: 169 | # validate!(fail_fast: false, fail_on_filename: true) 170 | # 171 | # Validate this file and raise a ValidationError upon failure. If an error 172 | # is raised it will contain the detected validation failures for further 173 | # inspection. 174 | # 175 | # You can choose whether filename validation failure should cause overall 176 | # validation failure with the `fail_on_filename` parameter (default: true). 177 | def validate!(fail_fast: false, fail_on_filename: true) 178 | result = validate( 179 | fail_fast: fail_fast, fail_on_filename: fail_on_filename 180 | ) 181 | return if result[0] 182 | 183 | raise ValidationError.new(result[1], invalid_filename: !result[2]) 184 | end 185 | 186 | # :call-seq: 187 | # write(save_as: filename) 188 | # 189 | # Write this CFF File. The `save_as` parameter can be used to save a new 190 | # copy of this CFF File under a different filename, leaving the original 191 | # file untouched. If `save_as` is used then the internal filename of the 192 | # File will be updated to the supplied filename. 193 | def write(save_as: nil) 194 | unless save_as.nil? 195 | @filename = save_as 196 | @dirty = true 197 | end 198 | 199 | File.write(@filename, @index, @comment) if @dirty 200 | @dirty = false 201 | end 202 | 203 | # :call-seq: 204 | # comment = string or array 205 | # 206 | # A comment to be inserted at the top of the resultant CFF file. This can 207 | # be supplied as a simple string or an array of strings. When the file is 208 | # saved this comment is formatted as follows: 209 | # 210 | # * a simple string is split into 75 character lines and `'# '` is prepended 211 | # to each line; 212 | # * an array of strings is joined into a single string with `'\n'` and 213 | # `'# '` is prepended to each line; 214 | # 215 | # If you care about formatting, use an array of strings for your comment, 216 | # if not, use a single string. 217 | def comment=(comment) 218 | @dirty = true 219 | @comment = comment 220 | end 221 | 222 | def to_yaml # :nodoc: 223 | @index.to_yaml 224 | end 225 | 226 | def method_missing(name, *args) # :nodoc: 227 | if @index.respond_to?(name) 228 | @dirty = true if name.to_s.end_with?('=') # Remove to_s when Ruby >2.6. 229 | @index.send(name, *args) 230 | else 231 | super 232 | end 233 | end 234 | 235 | def respond_to_missing?(name, *all) # :nodoc: 236 | @index.respond_to?(name, *all) 237 | end 238 | 239 | def self.format_comment(comment) # :nodoc: 240 | return '' if comment.empty? 241 | 242 | comment = comment.scan(/.{1,75}/) if comment.is_a?(String) 243 | c = comment.map do |l| 244 | l.empty? ? '#' : "# #{l}" 245 | end.join("\n") 246 | 247 | "#{c}\n\n" 248 | end 249 | 250 | def self.parse_comment(content) # :nodoc: 251 | content = content.split("\n") 252 | 253 | content.reduce([]) do |acc, line| 254 | break acc unless line.start_with?('#') 255 | 256 | acc << line.sub(/^#+/, '').strip 257 | end 258 | end 259 | end 260 | end 261 | -------------------------------------------------------------------------------- /lib/cff/formatters.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ## 18 | module CFF 19 | # A registry of output formatters for converting CFF files into citations. 20 | module Formatters 21 | @formatters = {} 22 | 23 | # :call-seq: 24 | # formatters -> Array 25 | # 26 | # Return the list of formatters that are available. 27 | def self.formatters 28 | @formatters.keys 29 | end 30 | 31 | # :call-seq: 32 | # register_formatter(class) 33 | # 34 | # Register a citation formatter. To be registered as a formatter, a 35 | # class should at least provide the following class methods: 36 | # 37 | # * `format`, which takes the model to be formatted 38 | # as a named parameter, and the option to cite a CFF file's 39 | # `preferred-citation`: 40 | # ```ruby 41 | # def self.format(model:, preferred_citation: true); end 42 | # ``` 43 | # * `label`, which returns a short name for the formatter, e.g. 44 | # `'BibTeX'`. If your formatter class subclasses `CFF::Formatter`, 45 | # then `label` is provided for you. 46 | def self.register_formatter(clazz) 47 | return unless clazz.singleton_methods.include?(:format) 48 | return if @formatters.has_value?(clazz) 49 | 50 | format = clazz.label.downcase.to_sym 51 | @formatters[format] = clazz 52 | Citable.add_to_format_method(format) if defined?(Citable) 53 | end 54 | 55 | def self.formatter_for(format) # :nodoc: 56 | @formatters[format.downcase.to_sym] 57 | end 58 | end 59 | end 60 | 61 | require_relative 'formatters/all' 62 | -------------------------------------------------------------------------------- /lib/cff/formatters/all.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'apalike' 18 | require_relative 'bibtex' 19 | 20 | ## 21 | module CFF 22 | module Formatters # :nodoc: 23 | register_formatter(APALike) 24 | register_formatter(BibTeX) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/cff/formatters/apalike.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'formatter' 18 | 19 | ## 20 | module CFF 21 | module Formatters # :nodoc: 22 | # Generates an APALIKE citation string 23 | class APALike < Formatter # :nodoc: 24 | def self.format(model:, preferred_citation: true) # rubocop:disable Metrics/AbcSize 25 | model = select_and_check_model(model, preferred_citation) 26 | return if model.nil? 27 | 28 | output = [] 29 | output << combine_authors( 30 | model.authors.map { |author| format_author(author) } 31 | ) 32 | 33 | date = month_and_year_from_model(model) 34 | output << "(#{date})" unless date.empty? 35 | 36 | version = " (Version #{model.version})" unless model.version.to_s.empty? 37 | output << "#{model.title}#{version}#{type_label(model)}" 38 | output << publication_data_from_model(model) 39 | output << url(model) 40 | 41 | output.reject(&:empty?).join('. ') 42 | end 43 | 44 | def self.publication_data_from_model(model) # rubocop:disable Metrics 45 | case model.type 46 | when 'article' 47 | [ 48 | model.journal, 49 | volume_from_model(model), 50 | pages_from_model(model, dash: '–'), 51 | note_from_model(model) || '' 52 | ].reject(&:empty?).join(', ') 53 | when 'book' 54 | model.publisher.empty? ? '' : model.publisher.name 55 | when 'conference-paper' 56 | [ 57 | model.collection_title, 58 | volume_from_model(model), 59 | pages_from_model(model, dash: '–') 60 | ].reject(&:empty?).join(', ') 61 | when 'report' 62 | if model.institution.empty? 63 | model.authors.first.affiliation 64 | else 65 | model.institution.name 66 | end 67 | when 'phdthesis' 68 | type_and_school_from_model(model, 'Doctoral dissertation') 69 | when 'mastersthesis' 70 | type_and_school_from_model(model, "Master's thesis") 71 | when 'unpublished' 72 | note_from_model(model) || '' 73 | else 74 | '' 75 | end 76 | end 77 | 78 | def self.type_and_school_from_model(model, type) 79 | type = model.thesis_type == '' ? type : model.thesis_type 80 | school = model.institution.empty? ? model.authors.first.affiliation : model.institution.name 81 | "[#{type}, #{school}]" 82 | end 83 | 84 | def self.volume_from_model(model) 85 | issue = model.issue.to_s.empty? ? '' : "(#{model.issue})" 86 | model.volume.to_s.empty? ? '' : "#{model.volume}#{issue}" 87 | end 88 | 89 | # If we're citing a conference paper, try and use the date of the 90 | # conference. Otherwise use the specified month and year, or the date 91 | # of release. 92 | def self.month_and_year_from_model(model) 93 | if model.type == 'conference-paper' && !model.conference.empty? 94 | start = model.conference.date_start 95 | unless start == '' 96 | finish = model.conference.date_end 97 | return month_and_year_from_date(start)[1] if finish == '' || start >= finish 98 | 99 | return date_range(start, finish) 100 | end 101 | end 102 | 103 | super[1] 104 | end 105 | 106 | def self.date_range(start, finish) 107 | start_str = '%Y, %B %-d' 108 | finish_str = '%-d' 109 | finish_str = "%B #{finish_str}" unless start.month == finish.month 110 | finish_str = "%Y, #{finish_str}" unless start.year == finish.year 111 | 112 | "#{start.strftime(start_str)}–#{finish.strftime(finish_str)}" 113 | end 114 | 115 | # Prefer a DOI over the other URI options. 116 | def self.url(model) 117 | model.doi.empty? ? super : "https://doi.org/#{model.doi}" 118 | end 119 | 120 | def self.type_label(model) 121 | return ' [Data set]' if model.type.include?('data') 122 | return ' [Conference paper]' if model.type.include?('conference') 123 | return '' if model.is_a?(Reference) && !model.type.include?('software') 124 | 125 | ' [Computer software]' 126 | end 127 | 128 | def self.combine_authors(authors) 129 | return authors[0].chomp('.') if authors.length == 1 130 | 131 | "#{authors[0..-2].join(', ')}, & #{authors[-1]}".chomp('.') 132 | end 133 | 134 | def self.format_author(author) 135 | return author.name if author.is_a?(Entity) 136 | 137 | particle = 138 | author.name_particle.empty? ? '' : "#{author.name_particle} " 139 | suffix = author.name_suffix.empty? ? '' : ", #{author.name_suffix}" 140 | 141 | "#{particle}#{format_name(author)}#{suffix}" 142 | end 143 | 144 | # Format a name using an alias if needs be. 145 | # https://blog.apastyle.org/apastyle/2012/02/how-to-cite-pseudonyms.html 146 | def self.format_name(author) 147 | if author.family_names.empty? 148 | if author.given_names.empty? 149 | author.alias 150 | else 151 | author.given_names 152 | end 153 | elsif author.given_names.empty? 154 | author.family_names 155 | else 156 | "#{author.family_names}, #{initials(author.given_names)}." 157 | end 158 | end 159 | end 160 | end 161 | end 162 | -------------------------------------------------------------------------------- /lib/cff/formatters/bibtex.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2024 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'formatter' 18 | 19 | ## 20 | module CFF 21 | module Formatters # :nodoc: 22 | # Generates an BibTeX citation string 23 | class BibTeX < Formatter # :nodoc: 24 | # Fields without `!` have a simple one-to-one mapping between CFF and 25 | # BibTeX. Those with `!` call out to a more complex getter. 26 | ENTRY_TYPE_MAP = { 27 | 'article' => %w[doi journal note! number! pages! volume], 28 | 'book' => %w[address! doi editor! isbn number! pages! publisher! volume], 29 | 'booklet' => %w[address! doi], 30 | 'inproceedings' => %w[address! booktitle! doi editor! pages! publisher! series!], 31 | 'manual' => %w[address! doi], 32 | 'mastersthesis' => %w[address! doi school! type!], 33 | 'misc' => %w[doi pages!], 34 | 'phdthesis' => %w[address! doi school! type!], 35 | 'proceedings' => %w[address! booktitle! doi editor! pages! publisher! series!], 36 | 'software' => %w[doi license version], 37 | 'techreport' => %w[address! doi institution! number!], 38 | 'unpublished' => %w[doi note!] 39 | }.freeze 40 | 41 | # Convert months to three letter abbreviations, as per 42 | # https://www.bibtex.com/f/month-field/. Need to downcase from the 43 | # built-in set. 44 | MONTHS_MAP = Date::ABBR_MONTHNAMES.map do |month| 45 | month.downcase unless month.nil? 46 | end.freeze 47 | 48 | # We need to escape these characters in titles and names, as per 49 | # https://tex.stackexchange.com/questions/34580/escape-character-in-latex 50 | ESCAPE_CHARS = Regexp.new(/([&%$#_{}])/) 51 | 52 | def self.format(model:, preferred_citation: true) # rubocop:disable Metrics 53 | model = select_and_check_model(model, preferred_citation) 54 | return if model.nil? 55 | 56 | values = {} 57 | values['author'] = actor_list(model.authors) 58 | values['title'] = "{#{l(model.title)}}" 59 | 60 | publication_type = bibtex_type(model) 61 | publication_data_from_model(model, publication_type, values) 62 | 63 | month, year = month_and_year_from_model(model) 64 | values['month'] = MONTHS_MAP[month.to_i] unless month.empty? 65 | values['year'] = year 66 | 67 | values['url'] = url(model) 68 | 69 | values['note'] ||= model.notes unless model.is_a?(Index) 70 | 71 | values.reject! { |_, v| v.empty? } 72 | sorted_values = values.sort.map do |key, value| 73 | value = "{#{value}}" unless key == 'month' 74 | "#{key} = #{value}" 75 | end 76 | sorted_values.insert(0, generate_citekey(values)) 77 | 78 | "@#{publication_type}{#{sorted_values.join(",\n")}\n}" 79 | end 80 | 81 | # Get various bits of information about the reference publication. 82 | # Reference: https://www.bibtex.com/format/ 83 | def self.publication_data_from_model(model, type, fields) 84 | ENTRY_TYPE_MAP[type].each do |field| 85 | if model.respond_to?(field) 86 | fields[field] = l(model.send(field).to_s) 87 | else 88 | field = field.chomp('!') 89 | fields[field] = send("#{field}_from_model", model) 90 | end 91 | end 92 | end 93 | 94 | # BibTeX 'number' is CFF 'issue'. 95 | def self.number_from_model(model) 96 | model.issue.to_s 97 | end 98 | 99 | # BibTeX 'address' is taken from the publisher (book, others) or the 100 | # conference (inproceedings). 101 | def self.address_from_model(model) 102 | entity = if model.type == 'conference-paper' 103 | model.conference 104 | else 105 | model.publisher 106 | end 107 | return '' if entity.empty? 108 | 109 | [entity.city, entity.region, entity.country].reject(&:empty?).join(', ') 110 | end 111 | 112 | # BibTeX 'institution' could be grabbed from an author's affiliation, or 113 | # provided explicitly. 114 | def self.institution_from_model(model) 115 | return l(model.institution.name) unless model.institution.empty? 116 | 117 | l(model.authors.first.affiliation) 118 | end 119 | 120 | # BibTeX 'school' is CFF 'institution'. 121 | def self.school_from_model(model) 122 | institution_from_model(model) 123 | end 124 | 125 | # BibTeX 'type' for theses is CFF 'thesis-type'. 126 | def self.type_from_model(model) 127 | model.thesis_type 128 | end 129 | 130 | # BibTeX 'booktitle' is CFF 'collection-title'. 131 | def self.booktitle_from_model(model) 132 | l(model.collection_title) 133 | end 134 | 135 | # BibTeX 'editor' is CFF 'editors' or 'editors-series'. 136 | def self.editor_from_model(model) 137 | if model.editors.empty? 138 | model.editors_series.empty? ? '' : actor_list(model.editors_series) 139 | else 140 | actor_list(model.editors) 141 | end 142 | end 143 | 144 | def self.publisher_from_model(model) 145 | model.publisher.empty? ? '' : l(model.publisher.name) 146 | end 147 | 148 | def self.series_from_model(model) 149 | model.conference.empty? ? '' : l(model.conference.name) 150 | end 151 | 152 | # If we're citing a conference paper, try and use the date of the 153 | # conference. Otherwise use the specified month and year, or the date 154 | # of release. 155 | def self.month_and_year_from_model(model) 156 | if model.type == 'conference-paper' && !model.conference.empty? 157 | date = model.conference.date_start 158 | return month_and_year_from_date(date) unless date == '' 159 | end 160 | 161 | super 162 | end 163 | 164 | # Do what we can to map between CFF reference types and bibtex types. 165 | # References: 166 | # * https://www.bibtex.com/e/entry-types/ 167 | # * https://ctan.gutenberg.eu.org/macros/latex/contrib/biblatex-contrib/biblatex-software/software-biblatex.pdf 168 | def self.bibtex_type(model) # rubocop:disable Metrics/CyclomaticComplexity 169 | return 'software' if model.type.empty? || model.type.include?('software') 170 | 171 | case model.type 172 | when 'article', 'book', 'manual', 'unpublished', 'phdthesis', 'mastersthesis' 173 | model.type 174 | when 'conference', 'proceedings' 175 | 'proceedings' 176 | when 'conference-paper' 177 | 'inproceedings' 178 | when 'magazine-article', 'newspaper-article' 179 | 'article' 180 | when 'pamphlet' 181 | 'booklet' 182 | when 'report' 183 | 'techreport' 184 | else 185 | 'misc' 186 | end 187 | end 188 | 189 | def self.format_actor(author) # rubocop:disable Metrics/AbcSize 190 | return "{#{l(author.name)}}" if author.is_a?(Entity) 191 | return l(author.alias) if author.family_names.empty? && author.given_names.empty? 192 | 193 | particle = 194 | author.name_particle.empty? ? '' : "#{author.name_particle} " 195 | 196 | [ 197 | "#{particle}#{author.family_names}", 198 | author.name_suffix, 199 | author.given_names 200 | ].reject(&:empty?).join(', ') 201 | end 202 | 203 | def self.actor_list(actors) 204 | actors.map { |actor| format_actor(actor) }.join(' and ') 205 | end 206 | 207 | def self.generate_citekey(fields) 208 | reference = [ 209 | fields['author'].split(',', 2)[0], 210 | fields['title'].split[0..2], 211 | fields['year'] 212 | ].compact.join('_') 213 | 214 | Util.parameterize(reference) 215 | end 216 | 217 | # Escape a string to preserve special characters in LaTeX output. 218 | # Used in many places, so short method name to preserve reading flow. 219 | def self.l(string) 220 | string.gsub(ESCAPE_CHARS, '\\\\\1') 221 | end 222 | end 223 | end 224 | end 225 | -------------------------------------------------------------------------------- /lib/cff/formatters/formatter.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2023 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'date' 18 | 19 | ## 20 | module CFF 21 | module Formatters # :nodoc: 22 | # Formatter base class 23 | class Formatter # :nodoc: 24 | STATUS_TEXT_MAP = { 25 | 'advance-online' => 'Advance online publication', 26 | 'in-preparation' => 'Manuscript in preparation.', 27 | 'submitted' => 'Manuscript submitted for publication.' 28 | }.freeze 29 | 30 | def self.label 31 | @label ||= name.split('::')[-1] 32 | end 33 | 34 | def self.select_and_check_model(model, preferred_citation) 35 | if preferred_citation && model.preferred_citation.is_a?(Reference) 36 | model = model.preferred_citation 37 | end 38 | 39 | # Safe to assume valid `Index`s and `Reference`s will have these fields. 40 | model.authors.empty? || model.title.empty? ? nil : model 41 | end 42 | 43 | def self.initials(name) 44 | name.split.map { |part| part[0].capitalize }.join('. ') 45 | end 46 | 47 | def self.note_from_model(model) 48 | STATUS_TEXT_MAP[model.status] 49 | end 50 | 51 | # Prefer `repository_code` over `url` 52 | def self.url(model) 53 | model.repository_code.empty? ? model.url : model.repository_code 54 | end 55 | 56 | def self.month_and_year_from_model(model) # rubocop:disable Metrics 57 | return ['', 'in press'] if model.respond_to?(:status) && model.status == 'in-press' 58 | if model.respond_to?(:year) && !model.year.to_s.empty? 59 | return [model.month, model.year].map(&:to_s) 60 | end 61 | 62 | date = month_and_year_from_date(model.date_released) 63 | if date == ['', ''] && model.respond_to?(:date_published) 64 | date = month_and_year_from_date(model.date_published) 65 | end 66 | date 67 | end 68 | 69 | def self.month_and_year_from_date(value) 70 | return ['', ''] unless value.is_a?(Date) 71 | 72 | [value.month, value.year].map(&:to_s) 73 | end 74 | 75 | # CFF 'pages' is the number of pages, which has no equivalent in BibTeX 76 | # or APA. References: https://www.bibtex.com/f/pages-field/, 77 | # https://apastyle.apa.org/style-grammar-guidelines/references/examples 78 | def self.pages_from_model(model, dash: '--') 79 | return '' if !model.respond_to?(:start) || model.start.to_s.empty? 80 | 81 | start = model.start.to_s 82 | finish = model.end.to_s 83 | if finish.empty? 84 | start 85 | else 86 | start == finish ? start : "#{start}#{dash}#{finish}" 87 | end 88 | end 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /lib/cff/identifier.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'model_part' 18 | require_relative 'schema' 19 | 20 | ## 21 | module CFF 22 | # An Identifier represents an identifier in a CITATION.cff file. 23 | # 24 | # Identifier implements all of the fields listed in the 25 | # [CFF standard](https://citation-file-format.github.io/). All fields 26 | # are simple strings and can be set as such. A field which has not been set 27 | # will return the empty string. The simple fields are (with defaults in 28 | # parentheses): 29 | # 30 | # * `description` 31 | # * `type` 32 | # * `value` 33 | class Identifier < ModelPart 34 | ALLOWED_FIELDS = # :nodoc: 35 | SCHEMA_FILE['definitions']['identifier']['anyOf'].first['properties'].keys.dup.freeze 36 | 37 | # The [defined set of identifier types](https://github.com/citation-file-format/citation-file-format/blob/main/README.md#identifier-type-strings). 38 | IDENTIFIER_TYPES = SCHEMA_FILE['definitions']['identifier']['anyOf'].map do |id| 39 | id['properties']['type']['enum'].first 40 | end.freeze 41 | 42 | # :call-seq: 43 | # new -> Identifier 44 | # new { |id| block } -> Identifier 45 | # new(type, value) -> Identifier 46 | # new(type, value) { |id| block } -> Identifier 47 | # 48 | # Create a new Identifier with the optionally supplied type and value. 49 | # If the supplied type is invalid, then neither the type or value are set. 50 | def initialize(param = nil, *more) 51 | super() 52 | 53 | if param.is_a?(Hash) 54 | @fields = param 55 | else 56 | @fields = {} 57 | 58 | unless param.nil? 59 | self.type = param 60 | @fields['value'] = more[0] unless @fields['type'].nil? 61 | end 62 | end 63 | 64 | yield self if block_given? 65 | end 66 | 67 | # :call-seq: 68 | # type = type 69 | # 70 | # Sets the type of this Identifier. The type is restricted to a 71 | # [defined set of identifier types](https://github.com/citation-file-format/citation-file-format/blob/main/README.md#identifier-type-strings). 72 | def type=(type) 73 | type = type.downcase 74 | @fields['type'] = type if IDENTIFIER_TYPES.include?(type) 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /lib/cff/index.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2024 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'util' 18 | require_relative 'model_part' 19 | require_relative 'entity' 20 | require_relative 'identifier' 21 | require_relative 'licensable' 22 | require_relative 'person' 23 | require_relative 'reference' 24 | require_relative 'schema' 25 | require_relative 'validatable' 26 | require_relative 'citable' 27 | 28 | ## 29 | module CFF 30 | # Index is the core data structure for a CITATION.cff file. It can be 31 | # accessed direcly, or via File. 32 | # 33 | # Index implements all of the fields listed in the 34 | # [CFF standard](https://citation-file-format.github.io/). Complex 35 | # fields - `authors`, `contact`, `identifiers`, `keywords`, 36 | # `preferred-citation`, `references` and `type` - are documented below. All 37 | # other fields are simple strings and can be set as such. A field which has 38 | # not been set will return the empty string. The simple fields are (with 39 | # defaults in parentheses): 40 | # 41 | # * `abstract` 42 | # * `cff_version` 43 | # * `commit` 44 | # * `date_released` - *Note:* returns a `Date` object 45 | # * `doi` 46 | # * `license` 47 | # * `license_url` 48 | # * `message` (If you use this software in your work, please cite it using 49 | # the following metadata) 50 | # * `repository` 51 | # * `repository_artifact` 52 | # * `repository_code` 53 | # * `title` 54 | # * `url` 55 | # * `version` 56 | class Index < ModelPart 57 | include Citable 58 | include Licensable 59 | include Validatable 60 | 61 | ALLOWED_FIELDS = SCHEMA_FILE['properties'].keys.freeze # :nodoc: 62 | 63 | # The allowed CFF [types](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#type). 64 | MODEL_TYPES = SCHEMA_FILE['properties']['type']['enum'].dup.freeze 65 | 66 | # The default message to use if none is explicitly set. 67 | DEFAULT_MESSAGE = 'If you use this software in your work, please cite ' \ 68 | 'it using the following metadata' 69 | 70 | attr_date :date_released 71 | 72 | # :call-seq: 73 | # new(title) -> Index 74 | # new(title) { |index| block } -> Index 75 | # 76 | # Initialize a new Index with the supplied title. 77 | def initialize(param) 78 | super() 79 | 80 | if param.is_a?(Hash) 81 | @fields = build_index(param) 82 | else 83 | @fields = {} 84 | @fields['cff-version'] = DEFAULT_SPEC_VERSION 85 | @fields['message'] = DEFAULT_MESSAGE 86 | @fields['title'] = param 87 | end 88 | 89 | %w[authors contact identifiers keywords references].each do |field| 90 | @fields[field] = [] if @fields[field].nil? || @fields[field].empty? 91 | end 92 | 93 | yield self if block_given? 94 | end 95 | 96 | # :call-seq: 97 | # read(String) -> Index 98 | # 99 | # Read a CFF Index from a String and parse it for subsequent manipulation. 100 | def self.read(index) 101 | new(Util.parse_yaml(index)) 102 | end 103 | 104 | # :call-seq: 105 | # open(String) -> Index 106 | # open(String) { |cff| block } -> Index 107 | # 108 | # With no associated block, Index.open is a synonym for ::read. If the 109 | # optional code block is given, it will be passed the parsed index as an 110 | # argument and the Index will be returned when the block terminates. 111 | def self.open(index) 112 | cff = Index.read(index) 113 | 114 | yield cff if block_given? 115 | 116 | cff 117 | end 118 | 119 | # :call-seq: 120 | # type = type 121 | # 122 | # Sets the type of this CFF Index. The type is currently restricted to one 123 | # of `software` or `dataset`. If this field is not set then you should 124 | # assume that the type is `software`. 125 | def type=(type) 126 | type = type.downcase 127 | @fields['type'] = type if MODEL_TYPES.include?(type) 128 | end 129 | 130 | def to_yaml # :nodoc: 131 | YAML.dump fields, line_width: -1, indentation: 2 132 | end 133 | 134 | private 135 | 136 | def fields 137 | %w[authors contact identifiers references].each do |field| 138 | Util.normalize_modelpart_array!(@fields[field]) 139 | end 140 | 141 | Util.fields_to_hash(@fields) 142 | end 143 | 144 | def build_index(fields) # rubocop:disable Metrics 145 | Util.build_actor_collection!(fields['authors'] || []) 146 | Util.build_actor_collection!(fields['contact'] || []) 147 | (fields['identifiers'] || []).map! do |i| 148 | Identifier.new(i) 149 | end 150 | (fields['references'] || []).map! do |r| 151 | Reference.new(r) 152 | end 153 | fields['preferred-citation'] &&= 154 | Reference.new(fields['preferred-citation']) 155 | 156 | # Only attempt an update of the `cff-version` field if it is present. 157 | fields['cff-version'] &&= Util.update_cff_version(fields['cff-version']) 158 | 159 | fields 160 | end 161 | 162 | public 163 | 164 | # Some documentation of "hidden" methods is provided here, out of the 165 | # way of the main class code. 166 | 167 | ## 168 | # :method: authors 169 | # :call-seq: 170 | # authors -> Array 171 | # 172 | # Return the list of authors for this citation. To add an author to the 173 | # list, use: 174 | # 175 | # ``` 176 | # index.authors << author 177 | # ``` 178 | # 179 | # Authors can be a Person or Entity. 180 | 181 | ## 182 | # :method: authors= 183 | # :call-seq: 184 | # authors = array_of_authors -> Array 185 | # 186 | # Replace the list of authors for this citation. 187 | # 188 | # Authors can be a Person or Entity. 189 | 190 | ## 191 | # :method: contact 192 | # :call-seq: 193 | # contact -> Array 194 | # 195 | # Return the list of contacts for this citation. To add a contact to the 196 | # list, use: 197 | # 198 | # ``` 199 | # index.contact << contact 200 | # ``` 201 | # 202 | # Contacts can be a Person or Entity. 203 | 204 | ## 205 | # :method: contact= 206 | # :call-seq: 207 | # contact = array_of_contacts -> Array 208 | # 209 | # Replace the list of contacts for this citation. 210 | # 211 | # Contacts can be a Person or Entity. 212 | 213 | ## 214 | # :method: identifiers 215 | # :call-seq: 216 | # identifiers -> Array 217 | # 218 | # Return the list of identifiers for this citation. To add a identifier to 219 | # the list, use: 220 | # 221 | # ``` 222 | # index.identifiers << identifier 223 | # ``` 224 | 225 | ## 226 | # :method: identifiers= 227 | # :call-seq: 228 | # identifiers = array_of_identifiers -> Array 229 | # 230 | # Replace the list of identifiers for this citation. 231 | 232 | ## 233 | # :method: keywords 234 | # :call-seq: 235 | # keywords -> Array 236 | # 237 | # Return the list of keywords for this citation. To add a keyword to the 238 | # list, use: 239 | # 240 | # ``` 241 | # index.keywords << keyword 242 | # ``` 243 | # 244 | # Keywords will be converted to Strings on output. 245 | 246 | ## 247 | # :method: keywords= 248 | # :call-seq: 249 | # keywords = array_of_keywords -> Array 250 | # 251 | # Replace the list of keywords for this citation. 252 | # 253 | # Keywords will be converted to Strings on output. 254 | 255 | ## 256 | # :method: preferred_citation 257 | # :call-seq: 258 | # preferred_citation -> Reference 259 | # 260 | # Return the preferred citation for this citation. 261 | 262 | ## 263 | # :method: preferred_citation= 264 | # :call-seq: 265 | # preferred_citation = Reference 266 | # 267 | # Replace the preferred citation for this citation. 268 | 269 | ## 270 | # :method: references 271 | # :call-seq: 272 | # references -> Array 273 | # 274 | # Return the list of references for this citation. To add a reference to the 275 | # list, use: 276 | # 277 | # ``` 278 | # index.references << reference 279 | # ``` 280 | 281 | ## 282 | # :method: references= 283 | # :call-seq: 284 | # references = array_of_references -> Array 285 | # 286 | # Replace the list of references for this citation. 287 | end 288 | end 289 | -------------------------------------------------------------------------------- /lib/cff/licensable.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'schema' 18 | 19 | ## 20 | module CFF 21 | # Functionality to add licence(s) to parts of the CFF model. 22 | module Licensable 23 | LICENSES = SCHEMA_FILE['definitions']['license-enum']['enum'].dup.freeze # :nodoc: 24 | 25 | # :call-seq: 26 | # license = license 27 | # license = Array 28 | # 29 | # Set the license, or licenses, of this work. Only licenses that conform 30 | # to the [SPDX License List](https://spdx.org/licenses/) will be accepted. 31 | # If you need specify a different license you should set `license-url` 32 | # with a link to the license instead. 33 | def license=(lic) 34 | list = [*lic].select { |l| LICENSES.include?(l) } 35 | @fields['license'] = case list.length 36 | when 0 37 | @fields['license'] 38 | when 1 39 | list[0] 40 | else 41 | list 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/cff/model_part.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2023 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'date' 18 | 19 | ## 20 | module CFF 21 | # ModelPart is the superclass of anything that makes up part of the CFF Index. 22 | # This includes Index, Person, Entity and Reference. 23 | # 24 | # ModelPart provides only one method for the public API: `empty?`. 25 | class ModelPart 26 | # :stopdoc: 27 | attr_reader :fields 28 | 29 | def method_missing(name, *args) 30 | n = method_to_field(name.id2name) 31 | super unless self.class::ALLOWED_FIELDS.include?(n.chomp('=')) 32 | 33 | if n.end_with?('=') 34 | @fields[n.chomp('=')] = args[0] || '' 35 | else 36 | @fields[n].nil? ? '' : @fields[n] 37 | end 38 | end 39 | 40 | def respond_to_missing?(name, *) 41 | n = method_to_field(name.id2name) 42 | self.class::ALLOWED_FIELDS.include?(n.chomp('=')) || super 43 | end 44 | # :startdoc: 45 | 46 | # :call-seq: 47 | # empty? -> false 48 | # 49 | # Define `empty?` for CFF classes so that they can be tested in the 50 | # same way as strings and arrays. 51 | # 52 | # This always returns `false` because CFF classes always return something 53 | # from all of their methods. 54 | def empty? 55 | false 56 | end 57 | 58 | def self.attr_date(*symbols) # :nodoc: 59 | symbols.each do |symbol| 60 | field = symbol.to_s.tr('_', '-') 61 | 62 | date_getter(symbol, field) 63 | date_setter(symbol, field) 64 | end 65 | end 66 | 67 | def self.date_getter(symbol, field) 68 | class_eval( 69 | # def date_end 70 | # date = @fields['date-end'] 71 | # return date if date.is_a?(Date) 72 | # 73 | # begin 74 | # Date.parse(date) 75 | # rescue 76 | # '' 77 | # end 78 | # end 79 | <<-END_GETTER, __FILE__, __LINE__ + 1 80 | def #{symbol} 81 | date = @fields['#{field}'] 82 | return date if date.is_a?(Date) 83 | 84 | begin 85 | Date.parse(date) 86 | rescue 87 | '' 88 | end 89 | end 90 | END_GETTER 91 | ) 92 | end 93 | 94 | def self.date_setter(symbol, field) 95 | class_eval( 96 | # def date_end=(date) 97 | # date = (date.is_a?(Date) ? date.dup : Date.parse(date)) 98 | # 99 | # @fields['date-end'] = date 100 | # end 101 | <<-END_SETTER, __FILE__, __LINE__ + 1 102 | def #{symbol}=(date) 103 | date = (date.is_a?(Date) ? date.dup : Date.parse(date)) 104 | 105 | @fields['#{field}'] = date 106 | end 107 | END_SETTER 108 | ) 109 | end 110 | 111 | private_class_method :date_getter, :date_setter 112 | 113 | private 114 | 115 | def method_to_field(name) 116 | name.tr('_', '-') 117 | end 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /lib/cff/person.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'model_part' 18 | require_relative 'schema' 19 | 20 | ## 21 | module CFF 22 | # A Person represents a person in a CITATION.cff file. A Person might have a 23 | # number of roles, such as author, contact, editor, etc. 24 | # 25 | # Person implements all of the fields listed in the 26 | # [CFF standard](https://citation-file-format.github.io/). All fields 27 | # are simple strings and can be set as such. A field which has not been set 28 | # will return the empty string. The simple fields are (with defaults in 29 | # parentheses): 30 | # 31 | # * `address` 32 | # * `affiliation` 33 | # * `alias` 34 | # * `city` 35 | # * `country` 36 | # * `email` 37 | # * `family_names` 38 | # * `fax` 39 | # * `given_names` 40 | # * `name_particle` 41 | # * `name_suffix` 42 | # * `orcid` 43 | # * `post_code` 44 | # * `region` 45 | # * `tel` 46 | # * `website` 47 | class Person < ModelPart 48 | ALLOWED_FIELDS = SCHEMA_FILE['definitions']['person']['properties'].keys.freeze # :nodoc: 49 | 50 | # :call-seq: 51 | # new -> Person 52 | # new { |person| block } -> Person 53 | # new(given_name, family_name) -> Person 54 | # new(given_name, family_name) { |person| block } -> Person 55 | # 56 | # Create a new Person with the optionally supplied given and family names. 57 | def initialize(param = nil, *more) 58 | super() 59 | 60 | if param.is_a?(Hash) 61 | @fields = param 62 | else 63 | @fields = {} 64 | 65 | unless param.nil? 66 | @fields['family-names'] = more[0] 67 | @fields['given-names'] = param 68 | end 69 | end 70 | 71 | yield self if block_given? 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /lib/cff/schema.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'json' 18 | 19 | ## 20 | module CFF 21 | SCHEMA_PATH = ::File.join(__dir__, 'schemas', '1.2.0.json') # :nodoc: 22 | SCHEMA_FILE = JSON.parse(::File.read(SCHEMA_PATH)) # :nodoc: 23 | end 24 | -------------------------------------------------------------------------------- /lib/cff/util.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2024 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'entity' 18 | require_relative 'person' 19 | require_relative 'version' 20 | 21 | require 'rubygems' 22 | require 'yaml' 23 | 24 | ## 25 | module CFF 26 | # Util provides utility methods useful throughout the rest of the CFF library. 27 | # 28 | # Util does not provide any methods or fields for the public API. 29 | module Util 30 | # :stopdoc: 31 | 32 | module_function 33 | 34 | def parse_yaml(string) 35 | YAML.safe_load(string, aliases: true, permitted_classes: [Date, Time]) 36 | end 37 | 38 | def update_cff_version(version) 39 | return '' if version.nil? || version.empty? 40 | 41 | if Gem::Version.new(version) < Gem::Version.new(MIN_VALIDATABLE_VERSION) 42 | MIN_VALIDATABLE_VERSION 43 | else 44 | version 45 | end 46 | end 47 | 48 | # Currently need to make some sort of guess as to whether an actor 49 | # is a Person or Entity. This isn't perfect, but works 99.99% I think. 50 | def build_actor_collection!(source) 51 | source.map! do |s| 52 | next s if s.is_a?(Person) || s.is_a?(Entity) 53 | 54 | s.has_key?('name') ? Entity.new(s) : Person.new(s) 55 | end 56 | end 57 | 58 | def normalize_modelpart_array!(array) 59 | array.select! { |i| i.respond_to?(:fields) } 60 | end 61 | 62 | def fields_to_hash(fields) 63 | hash = {} 64 | 65 | fields.each do |field, value| 66 | if value.respond_to?(:map) 67 | unless value.empty? 68 | hash[field] = value.map do |v| 69 | v.respond_to?(:fields) ? v.fields : v.to_s 70 | end 71 | end 72 | else 73 | hash[field] = value.respond_to?(:fields) ? value.fields : value 74 | end 75 | end 76 | 77 | hash 78 | end 79 | 80 | DEFAULT_CHAR_APPROXIMATIONS = { 81 | 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 82 | 'Æ' => 'AE', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 83 | 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N', 84 | 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', '×' => 'x', 85 | 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 86 | 'Þ' => 'Th', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 87 | 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 88 | 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 89 | 'ï' => 'i', 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 90 | 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 91 | 'ü' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y', 'Ā' => 'A', 'ā' => 'a', 92 | 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a', 'Ć' => 'C', 'ć' => 'c', 93 | 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c', 94 | 'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd', 'Ē' => 'E', 'ē' => 'e', 95 | 'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 96 | 'Ě' => 'E', 'ě' => 'e', 'ệ' => 'e', 'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G', 97 | 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g', 'Ĥ' => 'H', 98 | 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I', 99 | 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 100 | 'ı' => 'i', 'IJ' => 'IJ', 'ij' => 'ij', 'Ĵ' => 'J', 'ĵ' => 'j', 101 | 'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 102 | 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L', 103 | 'ł' => 'l', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N', 104 | 'ň' => 'n', 'ʼn' => "'n", 'Ŋ' => 'NG', 'ŋ' => 'ng', 'Ō' => 'O', 105 | 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o', 'Œ' => 'OE', 106 | 'œ' => 'oe', 'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 107 | 'ř' => 'r', 'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 108 | 'ş' => 's', 'Š' => 'S', 'š' => 's', 'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T', 109 | 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U', 110 | 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U', 111 | 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u', 'Ŵ' => 'W', 'ŵ' => 'w', 'Ŷ' => 'Y', 112 | 'ŷ' => 'y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 113 | 'Ž' => 'Z', 'ž' => 'z' 114 | }.freeze 115 | 116 | def transliterate(string, fallback: '') 117 | string.gsub(/[^\x00-\x7f]/u) do |char| 118 | DEFAULT_CHAR_APPROXIMATIONS[char] || fallback 119 | end 120 | end 121 | 122 | def parameterize(string, separator: '_') 123 | # Normalize into ASCII. 124 | param = transliterate(string) 125 | 126 | # Remove unwanted chars by turning them into the separator. 127 | param.gsub!(/[^a-z0-9\-_]+/i, separator) 128 | 129 | # Only one separator at a time. 130 | param.gsub!(/#{separator}{2,}/, separator) 131 | 132 | # No leading/trailing separators. 133 | param.gsub(/^#{separator}|#{separator}$/i, '') 134 | end 135 | 136 | # :startdoc: 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /lib/cff/validatable.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'errors' 18 | require_relative 'schema' 19 | 20 | require 'json_schema' 21 | 22 | ## 23 | module CFF 24 | # Methods to validate CFF files/models against a formal schema. 25 | module Validatable 26 | SCHEMA = JsonSchema.parse!(SCHEMA_FILE) # :nodoc: 27 | 28 | # :call-seq: 29 | # validate!(fail_fast: false) 30 | # 31 | # Validate a CFF file or model (Index) and raise a ValidationError upon 32 | # failure. If an error is raised it will contain the detected validation 33 | # failures for further inspection. Setting `fail_fast` to true will fail 34 | # validation at the first detected failure, rather than gathering and 35 | # returning all failures. 36 | def validate!(fail_fast: false) 37 | result = validate(fail_fast: fail_fast) 38 | return if result[0] 39 | 40 | raise ValidationError.new(result[1]) 41 | end 42 | 43 | # :call-seq: 44 | # validate(fail_fast: false) -> Array 45 | # 46 | # Validate a CFF file or model (Index) and return an array with the result. 47 | # The result array is a two-element array, with `true`/`false` at index 0 48 | # to indicate pass/fail, and an array of errors at index 1 (if any). 49 | # Setting `fail_fast` to true will fail validation at the first detected 50 | # failure, rather than gathering and returning all failures. 51 | def validate(fail_fast: false) 52 | SCHEMA.validate(fields, fail_fast: fail_fast) 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/cff/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ## 18 | module CFF 19 | # :nodoc: 20 | VERSION = '1.3.0' 21 | DEFAULT_SPEC_VERSION = '1.2.0' 22 | MIN_VALIDATABLE_VERSION = '1.2.0' 23 | end 24 | -------------------------------------------------------------------------------- /test/cff_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/version' 20 | 21 | class CFFTest < Minitest::Test 22 | def test_that_it_has_a_version_number 23 | refute_nil ::CFF::VERSION 24 | end 25 | 26 | def test_that_it_has_a_spec_version_number 27 | refute_nil ::CFF::DEFAULT_SPEC_VERSION 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /test/citable_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/citable' 20 | 21 | class CFFCitableTest < Minitest::Test 22 | def test_to_methods_present 23 | methods = CFF::Citable.instance_methods 24 | 25 | CFF::Formatters.formatters.each do |format| 26 | # Depending on the order that tests are run, we may have an extra 27 | # formatter hanging around. 28 | next if format == :testformatterlabel 29 | 30 | assert_includes(methods, "to_#{format}".to_sym) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/entity_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'yaml' 20 | require 'cff/entity' 21 | 22 | class CFFEntityTest < Minitest::Test 23 | include TestUtil 24 | 25 | def setup 26 | @entity = ::CFF::Entity.new('Some Company') 27 | end 28 | 29 | def test_bad_methods_not_allowed 30 | refute_respond_to(@entity, :aaaaaaa) 31 | assert_raises(NoMethodError) do 32 | @entity.aaaaaaa 33 | end 34 | 35 | refute_respond_to(@entity, :Address) 36 | assert_raises(NoMethodError) do 37 | @entity.Address = 'A Street' 38 | end 39 | end 40 | 41 | def test_simple_fields_set_and_output_correctly 42 | data = [ 43 | ['address', 'A Street'], 44 | ['alias', 'UoM'], 45 | ['city', 'Manchester'], 46 | ['country', 'GB'], 47 | ['email', 'email@example.org'], 48 | ['location', 'Classified'], 49 | ['orcid', 'https://orcid.org/0000-0001-2345-6789'], 50 | ['post-code', 'M13 9PL'], 51 | ['region', 'Greater Manchester'], 52 | ['website', 'https://home.example.org'] 53 | ] 54 | 55 | data.each do |method, value| 56 | assert_equal('', @entity.send(method)) 57 | @entity.send("#{method}=", value) 58 | assert_equal(value, @entity.send(method)) 59 | end 60 | 61 | y = @entity.fields.to_yaml 62 | 63 | data.each do |method, value| 64 | assert_includes(y, "#{method_to_field(method)}: #{value}\n") 65 | end 66 | end 67 | 68 | def test_date_fields_set_and_output_correctly 69 | date = Date.today 70 | @entity.date_end = date 71 | @entity.date_start = date 72 | 73 | assert_equal(date, @entity.date_end) 74 | assert_equal(date, @entity.date_start) 75 | 76 | y = @entity.fields.to_yaml 77 | 78 | assert_includes(y, "date-end: #{date}\n") 79 | assert_includes(y, "date-start: #{date}\n") 80 | end 81 | 82 | def test_date_fields_set_and_output_correctly_with_text 83 | date = '1999-12-31' 84 | @entity.date_end = date 85 | @entity.date_start = date 86 | 87 | assert_equal(Date.parse(date), @entity.date_end) 88 | assert_equal(Date.parse(date), @entity.date_start) 89 | 90 | y = @entity.fields.to_yaml 91 | 92 | assert_includes(y, "date-end: #{date}\n") 93 | assert_includes(y, "date-start: #{date}\n") 94 | end 95 | 96 | def test_tel_fax_fields_set_and_output_correctly 97 | number = '+44 (0) 161-234-5678' 98 | @entity.fax = number 99 | @entity.tel = number 100 | 101 | assert_equal(number, @entity.fax) 102 | assert_equal(number, @entity.tel) 103 | 104 | y = @entity.fields.to_yaml 105 | 106 | assert_includes(y, "fax: \"#{number}\"\n") 107 | assert_includes(y, "tel: \"#{number}\"\n") 108 | end 109 | 110 | def test_new_with_block 111 | entity = ::CFF::Entity.new('My Company') do |e| 112 | assert_equal('My Company', e.name) 113 | e.tel = '+44 (0) 161-234-5678' 114 | end 115 | 116 | assert_equal('My Company', entity.name) 117 | assert_equal('+44 (0) 161-234-5678', entity.tel) 118 | assert entity.is_a?(::CFF::Entity) 119 | end 120 | 121 | def test_empty? 122 | refute_empty(@entity) 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /test/errors_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/errors' 20 | 21 | class CFFErrorsTest < Minitest::Test 22 | def test_validation_error 23 | error = ::CFF::ValidationError.new(['test']) 24 | assert_equal( 25 | 'Validation error: (Invalid filename: false) test', 26 | error.message 27 | ) 28 | end 29 | 30 | def test_validation_error_with_filename 31 | error = ::CFF::ValidationError.new(['test'], invalid_filename: true) 32 | assert_equal( 33 | 'Validation error: (Invalid filename: true) test', 34 | error.message 35 | ) 36 | end 37 | 38 | def test_rescue_validation_error_as_standard_error 39 | raise ::CFF::ValidationError.new([]) 40 | rescue StandardError 41 | # Catch. 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /test/files/bad/CITATION.cff: -------------------------------------------------------------------------------- 1 | # A CFF file that's missing the `cff-version` field. 2 | 3 | message: If you use this software in your work, please cite it using the following metadata 4 | title: Ruby CFF Library 5 | authors: 6 | - family-names: Haines 7 | given-names: Robert 8 | affiliation: The University of Manchester, UK 9 | version: 0.4.0 10 | date-released: 2018-07-22 11 | -------------------------------------------------------------------------------- /test/files/bad/incomplete.cff: -------------------------------------------------------------------------------- 1 | # A CFF file with the required 'authors' fields missing. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | version: 0.4.0 7 | date-released: 2018-07-22 8 | -------------------------------------------------------------------------------- /test/files/formatted/TUe-excellent-buildings_BSO-toolbox.apa: -------------------------------------------------------------------------------- 1 | Boonstra, S., & Hofmeyer, H. (2020). BSO Toolbox (Version 1.0) [Computer software]. https://doi.org/10.5281/zenodo.3823893 2 | -------------------------------------------------------------------------------- /test/files/formatted/TUe-excellent-buildings_BSO-toolbox.bibtex: -------------------------------------------------------------------------------- 1 | @software{Boonstra_BSO_Toolbox_2020, 2 | author = {Boonstra, Sjonnie and Hofmeyer, Hèrm}, 3 | doi = {10.5281/zenodo.3823893}, 4 | month = may, 5 | title = {{BSO Toolbox}}, 6 | version = {1.0}, 7 | year = {2020} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/TUe-excellent-buildings_BSO-toolbox_invalid_date.apa: -------------------------------------------------------------------------------- 1 | Boonstra, S., & Hofmeyer, H. BSO Toolbox (Version 1.0) [Computer software]. https://doi.org/10.5281/zenodo.3823893 2 | -------------------------------------------------------------------------------- /test/files/formatted/TUe-excellent-buildings_BSO-toolbox_invalid_date.bibtex: -------------------------------------------------------------------------------- 1 | @software{Boonstra_BSO_Toolbox, 2 | author = {Boonstra, Sjonnie and Hofmeyer, Hèrm}, 3 | doi = {10.5281/zenodo.3823893}, 4 | title = {{BSO Toolbox}}, 5 | version = {1.0} 6 | } 7 | -------------------------------------------------------------------------------- /test/files/formatted/bjmorgan_bsym.apa: -------------------------------------------------------------------------------- 1 | Morgan, B. J. bsym (Version 1.1.0) [Computer software]. https://doi.org/10.5281/zenodo.596912 2 | -------------------------------------------------------------------------------- /test/files/formatted/bjmorgan_bsym.bibtex: -------------------------------------------------------------------------------- 1 | @software{Morgan_bsym, 2 | author = {Morgan, Benjamin J.}, 3 | doi = {10.5281/zenodo.596912}, 4 | license = {MIT}, 5 | title = {{bsym}}, 6 | url = {https://github.com/bjmorgan/bsym}, 7 | version = {1.1.0} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/citation-file-format_citation-file-format.apa: -------------------------------------------------------------------------------- 1 | Druskat, S., Spaaks, J. H., Chue Hong, N., Haines, R., Baker, J., Bliven, S., Willighagen, E., Pérez-Suárez, D., & Konovalov, A. (2021). Citation File Format (Version 1.1.0) [Computer software]. https://doi.org/10.5281/zenodo.4751536 2 | -------------------------------------------------------------------------------- /test/files/formatted/citation-file-format_citation-file-format.bibtex: -------------------------------------------------------------------------------- 1 | @software{Druskat_Citation_File_Format_2021, 2 | author = {Druskat, Stephan and Spaaks, Jurriaan H. and Chue Hong, Neil and Haines, Robert and Baker, James and Bliven, Spencer and Willighagen, Egon and Pérez-Suárez, David and Konovalov, Alexander}, 3 | doi = {10.5281/zenodo.4751536}, 4 | license = {CC-BY-4.0}, 5 | month = may, 6 | title = {{Citation File Format}}, 7 | version = {1.1.0}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/esalmela_HaploWinder.apa: -------------------------------------------------------------------------------- 1 | Salmela, E. (2008). HaploWinder (Version 1.11) [Computer software]. https://doi.org/10.5281/zenodo.3901323 2 | -------------------------------------------------------------------------------- /test/files/formatted/esalmela_HaploWinder.bibtex: -------------------------------------------------------------------------------- 1 | @software{Salmela_HaploWinder_2008, 2 | author = {Salmela, Elina}, 3 | doi = {10.5281/zenodo.3901323}, 4 | license = {MIT}, 5 | month = sep, 6 | title = {{HaploWinder}}, 7 | version = {1.11}, 8 | year = {2008} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/example-1.apa: -------------------------------------------------------------------------------- 1 | Druskat, S., XV. (2017). My Research Software (Version 2.0.4) [Computer software]. https://doi.org/10.5281/zenodo.1234 2 | -------------------------------------------------------------------------------- /test/files/formatted/example-1.bibtex: -------------------------------------------------------------------------------- 1 | @software{Druskat_My_Research_Software_2017, 2 | author = {Druskat, XV, Stephan}, 3 | doi = {10.5281/zenodo.1234}, 4 | month = dec, 5 | title = {{My Research Software}}, 6 | version = {2.0.4}, 7 | year = {2017} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/ls1mardyn_ls1-mardyn.apa: -------------------------------------------------------------------------------- 1 | Boltzmann-Zuse Society for Computational Molecular Engineering. (2018). ls1 mardyn (Version Internal development version, situated between release 1.1.1 and prospective future release 1.2) [Computer software]. https://projects.hlrs.de/projects/ls1/ 2 | -------------------------------------------------------------------------------- /test/files/formatted/ls1mardyn_ls1-mardyn.bibtex: -------------------------------------------------------------------------------- 1 | @software{Boltzmann-Zuse_Society_for_Computational_Molecular_Engineering_ls1_mardyn_2018, 2 | author = {{Boltzmann-Zuse Society for Computational Molecular Engineering}}, 3 | month = sep, 4 | title = {{ls1 mardyn}}, 5 | url = {https://projects.hlrs.de/projects/ls1/}, 6 | version = {Internal development version, situated between release 1.1.1 and prospective future release 1.2}, 7 | year = {2018} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-advance.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (2019). Welcome to the Tidyverse. Journal of Open Source Software, Advance online publication. https://doi.org/10.21105/joss.01686 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-advance.bibtex: -------------------------------------------------------------------------------- 1 | @article{Wickham_Welcome_to_the_2019, 2 | author = {Wickham, Hadley}, 3 | doi = {10.21105/joss.01686}, 4 | journal = {Journal of Open Source Software}, 5 | note = {Advance online publication}, 6 | title = {{Welcome to the Tidyverse}}, 7 | year = {2019} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-book-missing.apa: -------------------------------------------------------------------------------- 1 | Bueler, E. (2021). PETSc for Partial Differential Equations: Numerical Solutions in C and Python. https://github.com/bueler/p4pdes 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-book-missing.bibtex: -------------------------------------------------------------------------------- 1 | @book{Bueler_PETSc_for_Partial_2021, 2 | author = {Bueler, Ed}, 3 | isbn = {978111976304}, 4 | title = {{PETSc for Partial Differential Equations: Numerical Solutions in C and Python}}, 5 | url = {https://github.com/bueler/p4pdes}, 6 | year = {2021} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-book.apa: -------------------------------------------------------------------------------- 1 | Bueler, E. (2021). PETSc for Partial Differential Equations: Numerical Solutions in C and Python. SIAM Press. https://github.com/bueler/p4pdes 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-book.bibtex: -------------------------------------------------------------------------------- 1 | @book{Bueler_PETSc_for_Partial_2021, 2 | address = {Philadelphia}, 3 | author = {Bueler, Ed}, 4 | editor = {InChief, Ed and Assist, Ed}, 5 | isbn = {978111976304}, 6 | publisher = {SIAM Press}, 7 | title = {{PETSc for Partial Differential Equations: Numerical Solutions in C and Python}}, 8 | url = {https://github.com/bueler/p4pdes}, 9 | year = {2021} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-2.apa: -------------------------------------------------------------------------------- 1 | Gamblin, T., LeGendre, M., Collette, M. R., Lee, G. L., Moody, A., de Supinski, B. R., & Futral, S. (2015, November 15–20). The Spack Package Manager: Bringing Order to HPC Software Chaos [Conference paper]. Proceedings of Supercomputing 2015. https://doi.org/10.1244/2886907.2879400 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-2.bibtex: -------------------------------------------------------------------------------- 1 | @inproceedings{Gamblin_The_Spack_Package_2015, 2 | address = {Austin, Texas, USA}, 3 | author = {Gamblin, Todd and LeGendre, Matthew and Collette, Michael R. and Lee, Gregory L. and Moody, Adam and de Supinski, Bronis R. and Futral, Scott}, 4 | booktitle = {Proceedings of Supercomputing 2015}, 5 | doi = {10.1244/2886907.2879400}, 6 | editor = {InChief, Ed and Assist, Ed}, 7 | month = nov, 8 | publisher = {ACM/IEEE}, 9 | series = {Supercomputing 2015 (SC’15)}, 10 | title = {{The Spack Package Manager: Bringing Order to HPC Software Chaos}}, 11 | year = {2015} 12 | } 13 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-missing.apa: -------------------------------------------------------------------------------- 1 | Gamblin, T., LeGendre, M., Collette, M. R., Lee, G. L., Moody, A., de Supinski, B. R., & Futral, S. (2015). The Spack Package Manager: Bringing Order to HPC Software Chaos [Conference paper]. Proceedings of Supercomputing 2015. https://doi.org/10.1244/2886907.2879400 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-missing.bibtex: -------------------------------------------------------------------------------- 1 | @inproceedings{Gamblin_The_Spack_Package_2015, 2 | author = {Gamblin, Todd and LeGendre, Matthew and Collette, Michael R. and Lee, Gregory L. and Moody, Adam and de Supinski, Bronis R. and Futral, Scott}, 3 | booktitle = {Proceedings of Supercomputing 2015}, 4 | doi = {10.1244/2886907.2879400}, 5 | editor = {InChief, Ed and Assist, Ed}, 6 | month = nov, 7 | title = {{The Spack Package Manager: Bringing Order to HPC Software Chaos}}, 8 | year = {2015} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-with-escapes.apa: -------------------------------------------------------------------------------- 1 | Haines, R., & The {curly_braces} Collective. (2021). CFF is #1, 100% [Conference paper]. Software Credit for Fun & Profit ($$$). https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper-with-escapes.bibtex: -------------------------------------------------------------------------------- 1 | @inproceedings{Haines_CFF_is_1_2021, 2 | author = {Haines, Robert and {The \{curly\_braces\} Collective}}, 3 | booktitle = {Software Credit for Fun \& Profit (\$\$\$)}, 4 | doi = {10.5281/zenodo.1184077}, 5 | month = sep, 6 | publisher = {The CFF \& Friends}, 7 | series = {Software Credit \#1}, 8 | title = {{CFF is \#1, 100\%}}, 9 | url = {https://github.com/citation-file-format/ruby-cff}, 10 | year = {2021} 11 | } 12 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper.apa: -------------------------------------------------------------------------------- 1 | Rampin, R., Freire, J., Chirigati, F., & Shasha, D. (2016). ReproZip: Computational Reproducibility With Ease [Conference paper]. Proceedings of the 2016 ACM SIGMOD International Conference on Management of Data (SIGMOD), 2085–2088. https://doi.org/10.1145/2882903.2899401 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-conference-paper.bibtex: -------------------------------------------------------------------------------- 1 | @inproceedings{Rampin_ReproZip_Computational_Reproducibility_2016, 2 | address = {San Francisco, US}, 3 | author = {Rampin, Rémi and Freire, Juliana and Chirigati, Fernando and Shasha, Dennis}, 4 | booktitle = {Proceedings of the 2016 ACM SIGMOD International Conference on Management of Data (SIGMOD)}, 5 | doi = {10.1145/2882903.2899401}, 6 | month = jun, 7 | pages = {2085--2088}, 8 | publisher = {ACM}, 9 | series = {SIGMOD '16}, 10 | title = {{ReproZip: Computational Reproducibility With Ease}}, 11 | year = {2016} 12 | } 13 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-in-prep.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (2019). Welcome to the Tidyverse. Manuscript in preparation. 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-in-prep.bibtex: -------------------------------------------------------------------------------- 1 | @unpublished{Wickham_Welcome_to_the_2019, 2 | author = {Wickham, Hadley}, 3 | note = {Manuscript in preparation.}, 4 | title = {{Welcome to the Tidyverse}}, 5 | year = {2019} 6 | } 7 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-in-press.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (in press). Welcome to the Tidyverse. Journal of Open Source Software 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-in-press.bibtex: -------------------------------------------------------------------------------- 1 | @article{Wickham_Welcome_to_the_in_press, 2 | author = {Wickham, Hadley}, 3 | journal = {Journal of Open Source Software}, 4 | title = {{Welcome to the Tidyverse}}, 5 | year = {in press} 6 | } 7 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-journal-with-escapes.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2024). CFF for the $%&#_{} win. Journal of Maths & Philosophy, 1(1) 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-journal-with-escapes.bibtex: -------------------------------------------------------------------------------- 1 | @article{Haines_CFF_for_the_2024, 2 | author = {Haines, Robert}, 3 | journal = {Journal of Maths \& Philosophy}, 4 | month = jan, 5 | number = {1}, 6 | title = {{CFF for the \$\%\&\#\_\{\} win}}, 7 | volume = {1}, 8 | year = {2024} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-manual.apa: -------------------------------------------------------------------------------- 1 | Hernangómez, D. (2021). cffr: Generate Citation File Format ('cff') Metadata for R Packages. https://doi.org/10.5281/zenodo.5509766 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-manual.bibtex: -------------------------------------------------------------------------------- 1 | @manual{Hernangomez_cffr_Generate_Citation_2021, 2 | author = {Hernangómez, Diego}, 3 | doi = {10.5281/zenodo.5509766}, 4 | title = {{cffr: Generate Citation File Format ('cff') Metadata for R Packages}}, 5 | url = {https://dieghernan.github.io/cffr/}, 6 | year = {2021} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-masters-thesis-no-type.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. [Master's thesis, The CFF Institute]. https://doi.org/10.5281/zenodo.1184077 -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-masters-thesis-no-type.bibtex: -------------------------------------------------------------------------------- 1 | @mastersthesis{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | school = {The CFF Institute}, 6 | title = {{The benefits of using CFF files}}, 7 | url = {https://github.com/citation-file-format/ruby-cff}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-masters-thesis.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. [MA thesis, The CFF Institute]. https://doi.org/10.5281/zenodo.1184077 -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-masters-thesis.bibtex: -------------------------------------------------------------------------------- 1 | @mastersthesis{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | school = {The CFF Institute}, 6 | title = {{The benefits of using CFF files}}, 7 | type = {MA thesis}, 8 | url = {https://github.com/citation-file-format/ruby-cff}, 9 | year = {2021} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-issue.apa: -------------------------------------------------------------------------------- 1 | Fagundes, M. A. R., Mendonça-Tinti, I., Iescheck, A. L., Akos, D. M., & Geremia-Nievinski, F. (2021). An open-source low-cost sensor for SNR-based GNSS reflectometry: design and long-term validation towards sea-level altimetry. GPS Solutions, 25, 73. https://doi.org/10.1007/s10291-021-01087-1 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-issue.bibtex: -------------------------------------------------------------------------------- 1 | @article{Fagundes_An_open-source_low-cost_2021, 2 | author = {Fagundes, Manuella A. R. and Mendonça-Tinti, Iuri and Iescheck, Andrea L. and Akos, Dennis M. and Geremia-Nievinski, Felipe}, 3 | doi = {10.1007/s10291-021-01087-1}, 4 | journal = {GPS Solutions}, 5 | month = mar, 6 | pages = {73}, 7 | title = {{An open-source low-cost sensor for SNR-based GNSS reflectometry: design and long-term validation towards sea-level altimetry}}, 8 | volume = {25}, 9 | year = {2021} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-month.apa: -------------------------------------------------------------------------------- 1 | Lisa, M. (2021). My awesome research software. Journal Title 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-month.bibtex: -------------------------------------------------------------------------------- 1 | @article{Lisa_My_awesome_research_2021, 2 | author = {Lisa, Mona}, 3 | journal = {Journal Title}, 4 | title = {{My awesome research software}}, 5 | year = {2021} 6 | } 7 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-vol.apa: -------------------------------------------------------------------------------- 1 | Hartmann, J., Wong, M., Gallo, E., & Gilmour, D. (2020). An image-based data-driven analysis of cellular architecture in a developing tissue. eLife, 888. https://doi.org/10.7554/eLife.55913 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-no-vol.bibtex: -------------------------------------------------------------------------------- 1 | @article{Hartmann_An_image-based_data-driven_2020, 2 | author = {Hartmann, Jonas and Wong, Mie and Gallo, Elisa and Gilmour, Darren}, 3 | doi = {10.7554/eLife.55913}, 4 | journal = {eLife}, 5 | month = jun, 6 | pages = {888}, 7 | title = {{An image-based data-driven analysis of cellular architecture in a developing tissue}}, 8 | url = {https://elifesciences.org/articles/55913}, 9 | year = {2020} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-pamphlet.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). Why and how to use CFF. https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-pamphlet.bibtex: -------------------------------------------------------------------------------- 1 | @booklet{Haines_Why_and_how_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | title = {{Why and how to use CFF}}, 6 | url = {https://github.com/citation-file-format/ruby-cff}, 7 | year = {2021} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-phd-thesis-no-type.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. [Doctoral dissertation, The CFF Institute]. https://doi.org/10.5281/zenodo.1184077 -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-phd-thesis-no-type.bibtex: -------------------------------------------------------------------------------- 1 | @phdthesis{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | school = {The CFF Institute}, 6 | title = {{The benefits of using CFF files}}, 7 | url = {https://github.com/citation-file-format/ruby-cff}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-phd-thesis.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. [Habilitation thesis, The CFF Institute]. https://doi.org/10.5281/zenodo.1184077 -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-phd-thesis.bibtex: -------------------------------------------------------------------------------- 1 | @phdthesis{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | school = {The CFF Institute}, 6 | title = {{The benefits of using CFF files}}, 7 | type = {Habilitation thesis}, 8 | url = {https://github.com/citation-file-format/ruby-cff}, 9 | year = {2021} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report-no-affiliation.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report-no-affiliation.bibtex: -------------------------------------------------------------------------------- 1 | @techreport{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | title = {{The benefits of using CFF files}}, 6 | url = {https://github.com/citation-file-format/ruby-cff}, 7 | year = {2021} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report-no-institution.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. The University of Manchester. https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report-no-institution.bibtex: -------------------------------------------------------------------------------- 1 | @techreport{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | institution = {The University of Manchester}, 5 | month = sep, 6 | title = {{The benefits of using CFF files}}, 7 | url = {https://github.com/citation-file-format/ruby-cff}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). The benefits of using CFF files. The CFF Institute. https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-report.bibtex: -------------------------------------------------------------------------------- 1 | @techreport{Haines_The_benefits_of_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | institution = {The CFF Institute}, 5 | month = sep, 6 | title = {{The benefits of using CFF files}}, 7 | url = {https://github.com/citation-file-format/ruby-cff}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-submitted.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (2019). Welcome to the Tidyverse. Manuscript submitted for publication. 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-submitted.bibtex: -------------------------------------------------------------------------------- 1 | @unpublished{Wickham_Welcome_to_the_2019, 2 | author = {Wickham, Hadley}, 3 | note = {Manuscript submitted for publication.}, 4 | title = {{Welcome to the Tidyverse}}, 5 | year = {2019} 6 | } 7 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-unpublished.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2021). Why and how to use CFF. https://doi.org/10.5281/zenodo.1184077 2 | -------------------------------------------------------------------------------- /test/files/formatted/preferred-citation-unpublished.bibtex: -------------------------------------------------------------------------------- 1 | @unpublished{Haines_Why_and_how_2021, 2 | author = {Haines, Robert}, 3 | doi = {10.5281/zenodo.1184077}, 4 | month = sep, 5 | note = {Self-published by the author.}, 6 | title = {{Why and how to use CFF}}, 7 | url = {https://github.com/citation-file-format/ruby-cff}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/reprozip.apa: -------------------------------------------------------------------------------- 1 | Rampin, R., Freire, J., Chirigati, F., & Shasha, D. (2016). ReproZip: Computational Reproducibility With Ease. https://doi.org/10.1145/2882903.2899401 2 | -------------------------------------------------------------------------------- /test/files/formatted/reprozip.bibtex: -------------------------------------------------------------------------------- 1 | @proceedings{Rampin_ReproZip_Computational_Reproducibility_2016, 2 | author = {Rampin, Remi and Freire, Juliana and Chirigati, Fernando and Shasha, Dennis}, 3 | doi = {10.1145/2882903.2899401}, 4 | month = jun, 5 | series = {SIGMOD '16}, 6 | title = {{ReproZip: Computational Reproducibility With Ease}}, 7 | year = {2016} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/short-with-aliases.apa: -------------------------------------------------------------------------------- 1 | Haines, R. (2018). Ruby CFF Library (Version 0.4.0) [Computer software] 2 | -------------------------------------------------------------------------------- /test/files/formatted/short-with-aliases.bibtex: -------------------------------------------------------------------------------- 1 | @software{Haines_Ruby_CFF_Library_2018, 2 | author = {Haines, Robert}, 3 | license = {Apache-2.0}, 4 | month = jul, 5 | title = {{Ruby CFF Library}}, 6 | version = {0.4.0}, 7 | year = {2018} 8 | } 9 | -------------------------------------------------------------------------------- /test/files/formatted/smith-et-al.apa: -------------------------------------------------------------------------------- 1 | Smith, A. M., Katz, D. S., Niemeyer, K. E., & FORCE11 Software Citation Working Group. (2016). Software citation principles. PeerJ Computer Science, 2(123), e86. https://doi.org/10.7717/peerj-cs.86 2 | -------------------------------------------------------------------------------- /test/files/formatted/smith-et-al.bibtex: -------------------------------------------------------------------------------- 1 | @article{Smith_Software_citation_principles_2016, 2 | author = {Smith, A. M. and Katz, D. S. and Niemeyer, K. E. and {FORCE11 Software Citation Working Group}}, 3 | doi = {10.7717/peerj-cs.86}, 4 | journal = {PeerJ Computer Science}, 5 | month = sep, 6 | number = {123}, 7 | pages = {e86}, 8 | title = {{Software citation principles}}, 9 | volume = {2}, 10 | year = {2016} 11 | } 12 | -------------------------------------------------------------------------------- /test/files/formatted/software-missing-family-name.apa: -------------------------------------------------------------------------------- 1 | Harmon, Roesslein, J., & other contributors. Tweepy [Computer software]. https://doi.org/10.5281/zenodo.7259945 2 | -------------------------------------------------------------------------------- /test/files/formatted/software-missing-family-name.bibtex: -------------------------------------------------------------------------------- 1 | @software{Harmon_and_Roesslein_Tweepy, 2 | author = {Harmon and Roesslein, Joshua and {other contributors}}, 3 | doi = {10.5281/zenodo.7259945}, 4 | license = {MIT}, 5 | title = {{Tweepy}}, 6 | url = {https://github.com/tweepy/tweepy} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/software-missing-given-name.apa: -------------------------------------------------------------------------------- 1 | Roesslein, J., Harmon, & other contributors. Tweepy [Computer software]. https://doi.org/10.5281/zenodo.7259945 2 | -------------------------------------------------------------------------------- /test/files/formatted/software-missing-given-name.bibtex: -------------------------------------------------------------------------------- 1 | @software{Roesslein_Tweepy, 2 | author = {Roesslein, Joshua and Harmon and {other contributors}}, 3 | doi = {10.5281/zenodo.7259945}, 4 | license = {MIT}, 5 | title = {{Tweepy}}, 6 | url = {https://github.com/tweepy/tweepy} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/software-with-alias.apa: -------------------------------------------------------------------------------- 1 | Harmon758, Roesslein, J., & other contributors. Tweepy [Computer software]. https://doi.org/10.5281/zenodo.7259945 2 | -------------------------------------------------------------------------------- /test/files/formatted/software-with-alias.bibtex: -------------------------------------------------------------------------------- 1 | @software{Harmon758_and_Roesslein_Tweepy, 2 | author = {Harmon758 and Roesslein, Joshua and {other contributors}}, 3 | doi = {10.5281/zenodo.7259945}, 4 | license = {MIT}, 5 | title = {{Tweepy}}, 6 | url = {https://github.com/tweepy/tweepy} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/software-with-escapes.apa: -------------------------------------------------------------------------------- 1 | Haines, R., & The {curly_braces} Collective. (2024). Software that uses the following symbols: &, %, $, # (Version 0.0.1-alpha) [Computer software] 2 | -------------------------------------------------------------------------------- /test/files/formatted/software-with-escapes.bibtex: -------------------------------------------------------------------------------- 1 | @software{Haines_Software_that_uses_2024, 2 | author = {Haines, Robert and {The \{curly\_braces\} Collective}}, 3 | month = jan, 4 | title = {{Software that uses the following symbols: \&, \%, \$, \#}}, 5 | version = {0.0.1-alpha}, 6 | year = {2024} 7 | } 8 | -------------------------------------------------------------------------------- /test/files/formatted/tidyverse-joss-paper.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (2019). Welcome to the Tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686 2 | -------------------------------------------------------------------------------- /test/files/formatted/tidyverse-joss-paper.bibtex: -------------------------------------------------------------------------------- 1 | @article{Wickham_Welcome_to_the_2019, 2 | author = {Wickham, Hadley}, 3 | doi = {10.21105/joss.01686}, 4 | journal = {Journal of Open Source Software}, 5 | month = nov, 6 | number = {43}, 7 | pages = {1686}, 8 | title = {{Welcome to the Tidyverse}}, 9 | volume = {4}, 10 | year = {2019} 11 | } 12 | -------------------------------------------------------------------------------- /test/files/formatted/tidyverse-software.apa: -------------------------------------------------------------------------------- 1 | Wickham, H. (2021). Tidyverse (Version 1.3.1) [Computer software]. https://github.com/tidyverse/tidyverse -------------------------------------------------------------------------------- /test/files/formatted/tidyverse-software.bibtex: -------------------------------------------------------------------------------- 1 | @software{Wickham_Tidyverse_2021, 2 | author = {Wickham, Hadley}, 3 | license = {MIT}, 4 | month = apr, 5 | title = {{Tidyverse}}, 6 | url = {https://github.com/tidyverse/tidyverse}, 7 | version = {1.3.1}, 8 | year = {2021} 9 | } 10 | -------------------------------------------------------------------------------- /test/files/formatted/xenon-middleware_xenon-adaptors-cloud.apa: -------------------------------------------------------------------------------- 1 | Verhoeven, S., Maassen, J., & van der Ploeg, A. (2019). Cloud related adaptors for Xenon (Version 3.0.2) [Computer software]. https://doi.org/10.5281/zenodo.3245389 2 | -------------------------------------------------------------------------------- /test/files/formatted/xenon-middleware_xenon-adaptors-cloud.bibtex: -------------------------------------------------------------------------------- 1 | @software{Verhoeven_Cloud_related_adaptors_2019, 2 | author = {Verhoeven, Stefan and Maassen, Jason and van der Ploeg, Atze}, 3 | doi = {10.5281/zenodo.3245389}, 4 | license = {Apache-2.0}, 5 | month = aug, 6 | title = {{Cloud related adaptors for Xenon}}, 7 | url = {https://github.com/xenon-middleware/xenon-adaptors-cloud}, 8 | version = {3.0.2}, 9 | year = {2019} 10 | } 11 | -------------------------------------------------------------------------------- /test/files/formatter/TUe-excellent-buildings_BSO-toolbox.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.1.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Boonstra 5 | given-names: Sjonnie 6 | orcid: https://orcid.org/0000-0001-9911-4507 7 | - family-names: Hofmeyer 8 | given-names: Hèrm 9 | title: "BSO Toolbox" 10 | version: "1.0" 11 | doi: 10.5281/zenodo.3823893 12 | date-released: 2020-05-01 13 | -------------------------------------------------------------------------------- /test/files/formatter/TUe-excellent-buildings_BSO-toolbox_invalid_date.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.1.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Boonstra 5 | given-names: Sjonnie 6 | orcid: https://orcid.org/0000-0001-9911-4507 7 | - family-names: Hofmeyer 8 | given-names: Hèrm 9 | title: "BSO Toolbox" 10 | version: 1.0 11 | doi: 10.5281/zenodo.3823893 12 | date-released: 2020-05-xx -------------------------------------------------------------------------------- /test/files/formatter/bjmorgan_bsym.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.0.3 2 | message: If you use this software, please cite both the software repository and the JOSS paper. 3 | authors: 4 | - family-names: Morgan 5 | given-names: Benjamin J. 6 | orcid: https://orcid.org/0000-0002-3056-8233 7 | title: bsym 8 | version: 1.1.0 9 | doi: 10.5281/zenodo.596912 10 | repository-code: https://github.com/bjmorgan/bsym 11 | license: MIT 12 | references: 13 | - type: article 14 | authors: 15 | - family-names: Morgan 16 | given-names: Benjamin J. 17 | title: "bsym: A basic symmetry module" 18 | year: 2017 19 | journal: Journal of Open Source Software 20 | volume: 2 21 | issue: "16" 22 | doi: 10.21105/joss.00370 -------------------------------------------------------------------------------- /test/files/formatter/citation-file-format_citation-file-format.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.1.0 2 | message: "If you use CFF in your research, please cite it using these metadata." 3 | abstract: CITATION.cff files are plain text files with human- and machine-readable citation information for software. Code developers can include them in their repositories to let others know how to correctly cite their software. This is the specification for the Citation File Format. 4 | authors: 5 | - family-names: Druskat 6 | given-names: Stephan 7 | orcid: https://orcid.org/0000-0003-4925-7248 8 | - family-names: Spaaks 9 | given-names: Jurriaan H. 10 | orcid: https://orcid.org/0000-0002-7064-4069 11 | - family-names: Chue Hong 12 | given-names: Neil 13 | orcid: https://orcid.org/0000-0002-8876-7606 14 | - family-names: Haines 15 | given-names: Robert 16 | orcid: https://orcid.org/0000-0002-9538-7919 17 | - family-names: Baker 18 | given-names: James 19 | orcid: https://orcid.org/0000-0002-2682-6922 20 | - family-names: Bliven 21 | given-names: Spencer 22 | orcid: https://orcid.org/0000-0002-1200-1698 23 | email: spencer.bliven@gmail.com 24 | - family-names: Willighagen 25 | given-names: Egon 26 | orcid: https://orcid.org/0000-0001-7542-0286 27 | - family-names: Pérez-Suárez 28 | given-names: David 29 | orcid: https://orcid.org/0000-0003-0784-6909 30 | website: https://dpshelio.github.io 31 | - family-names: Konovalov 32 | given-names: Alexander 33 | orcid: https://orcid.org/0000-0001-5299-3292 34 | title: Citation File Format 35 | version: 1.1.0 36 | doi: 10.5281/zenodo.4751536 37 | date-released: 2021-05-12 38 | keywords: 39 | - citation file format 40 | - CFF 41 | - citation files 42 | - software citation 43 | - file format 44 | - YAML 45 | - software sustainability 46 | - research software 47 | - credit 48 | license: "CC-BY-4.0" -------------------------------------------------------------------------------- /test/files/formatter/esalmela_HaploWinder.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.1.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Salmela 5 | given-names: Elina 6 | orcid: https://orcid.org/0000-0003-1326-4462 7 | title: HaploWinder 8 | version: "1.11" 9 | date-released: 2008-09-01 10 | license: MIT 11 | doi: 10.5281/zenodo.3901323 12 | references: 13 | - type: software 14 | authors: 15 | - family-names: Salmela 16 | given-names: Elina 17 | title: HaploWinder 18 | doi: 10.5281/zenodo.3901323 19 | url: https://github.com/esalmela/HaploWinder 20 | - type: article 21 | authors: 22 | - family-names: Lappalainen 23 | given-names: Tuuli 24 | - family-names: Hannelius 25 | given-names: Ulf 26 | - family-names: Salmela 27 | given-names: Elina 28 | - family-names: von Döbeln 29 | given-names: Ulrika 30 | - family-names: Lindgren 31 | given-names: Cecilia M. 32 | - family-names: Huoponen 33 | given-names: Kirsi 34 | - family-names: Savontaus 35 | given-names: Marja-Liisa 36 | - family-names: Kere 37 | given-names: Juha 38 | - family-names: Lahermo 39 | given-names: Päivi 40 | title: "Population structure in contemporary Sweden – A Y-chromosomal and mitochondrial DNA analysis" 41 | journal: "Annals of Human Genetics" 42 | year: 2009 43 | volume: 73 44 | issue: 1 45 | start: 61 46 | end: 73 47 | doi: 10.1111/j.1469-1809.2008.00487.x 48 | -------------------------------------------------------------------------------- /test/files/formatter/example-1.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.1.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: Druskat 5 | given-names: Stephan 6 | name-suffix: XV 7 | orcid: https://orcid.org/0000-0003-4925-7248 8 | title: "My Research Software" 9 | version: 2.0.4 10 | doi: 10.5281/zenodo.1234 11 | date-released: 2017-12-18 12 | -------------------------------------------------------------------------------- /test/files/formatter/ls1mardyn_ls1-mardyn.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.0.3 2 | message: >- 3 | This file contains CFF citation information, cf. 4 | https://citation-file-format.github.io/, for the ls1 mardyn molecular dynamics 5 | code developed by the Boltzmann-Zuse Society for Computational Molecular 6 | Engineering. 7 | title: ls1 mardyn 8 | url: 'http://www.ls1-mardyn.de/' 9 | repository-code: 'https://projects.hlrs.de/projects/ls1/' 10 | date-released: 2018-09-05 11 | commit: Revision 6473. 12 | version: >- 13 | Internal development version, situated between release 1.1.1 and prospective 14 | future release 1.2 15 | license-url: 'http://www.ls1-mardyn.de/license.html' 16 | abstract: >- 17 | The molecular dynamics code ls1 mardyn (large systems 1: molecular dynamics), 18 | developed by the Boltzmann-Zuse Society for Computational Molecular 19 | Engineering, is a scalable massively-parallel molecular modelling and 20 | simulation code for classical-mechanical intermolecular pair potential models 21 | of low-molecular fluids. 22 | contact: 23 | - given-names: Philipp 24 | family-names: Neumann 25 | authors: 26 | - name: Boltzmann-Zuse Society for Computational Molecular Engineering 27 | country: DE 28 | references: 29 | - type: article 30 | title: >- 31 | ls1 mardyn: The massively parallel molecular dynamics code for large 32 | systems 33 | year: 2014 34 | authors: 35 | - given-names: Christoph 36 | family-names: Niethammer 37 | - given-names: Stefan 38 | family-names: Becker 39 | - given-names: Martin 40 | family-names: Bernreuther 41 | - given-names: Martin 42 | family-names: Buchholz 43 | - given-names: Wolfgang 44 | family-names: Eckhardt 45 | - given-names: Alexander 46 | family-names: Heinecke 47 | - given-names: Stephan 48 | family-names: Werth 49 | - given-names: Hans-Joachim 50 | family-names: Bungartz 51 | - given-names: Colin W. 52 | family-names: Glass 53 | - given-names: Hans 54 | family-names: Hasse 55 | - given-names: Jadran 56 | family-names: Vrabec 57 | - given-names: Martin 58 | family-names: Horsch 59 | journal: Journal of Chemical Theory and Computation 60 | volume: 10 61 | issue: 10 62 | pages: 4455-4464 63 | doi: 10.1021/ct500169q 64 | -------------------------------------------------------------------------------- /test/files/formatter/ls1mardyn_ls1-mardyn_invalid_author_array.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.0.3 2 | message: This file contains CFF citation information, cf. https://citation-file-format.github.io/, for the ls1 mardyn molecular dynamics code developed by the Boltzmann-Zuse Society for Computational Molecular Engineering. 3 | title: ls1 mardyn 4 | url: http://www.ls1-mardyn.de/ 5 | repository-code: https://projects.hlrs.de/projects/ls1/ 6 | date-released: 2018-09-05 7 | commit: Revision 6473. 8 | version: Internal development version, situated between release 1.1.1 and prospective future release 1.2 9 | license-url: http://www.ls1-mardyn.de/license.html 10 | abstract: "The molecular dynamics code ls1 mardyn (large systems 1: molecular dynamics), developed by the Boltzmann-Zuse Society for Computational Molecular Engineering, is a scalable massively-parallel molecular modelling and simulation code for classical-mechanical intermolecular pair potential models of low-molecular fluids." 11 | contact: 12 | - given-names: Philipp 13 | family-names: Neumann 14 | author: 15 | - name: Boltzmann-Zuse Society for Computational Molecular Engineering 16 | country: DE 17 | references: 18 | - type: article 19 | title: "ls1 mardyn: The massively parallel molecular dynamics code for large systems" 20 | year: 2014 21 | authors: 22 | - given-names: Christoph 23 | family-names: Niethammer 24 | - given-names: Stefan 25 | family-names: Becker 26 | - given-names: Martin 27 | family-names: Bernreuther 28 | - given-names: Martin 29 | family-names: Buchholz 30 | - given-names: Wolfgang 31 | family-names: Eckhardt 32 | - given-names: Alexander 33 | family-names: Heinecke 34 | - given-names: Stephan 35 | family-names: Werth 36 | - given-names: Hans-Joachim 37 | family-names: Bungartz 38 | - given-names: Colin W. 39 | family-names: Glass 40 | - given-names: Hans 41 | family-names: Hasse 42 | - given-names: Jadran 43 | family-names: Vrabec 44 | - given-names: Martin 45 | family-names: Horsch 46 | journal: Journal of Chemical Theory and Computation 47 | volume: 10 48 | issue: 10 49 | pages: 4455-4464 50 | doi: 10.1021/ct500169q -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-advance.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | 15 | # JOSS paper as preferred citation 16 | preferred-citation: 17 | authors: 18 | - family-names: Wickham 19 | given-names: Hadley 20 | orcid: https://orcid.org/0000-0003-4757-117X 21 | doi: "10.21105/joss.01686" 22 | journal: "Journal of Open Source Software" 23 | title: "Welcome to the Tidyverse" 24 | type: article 25 | status: advance-online 26 | year: 2019 27 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-book-missing.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite my book below. 3 | authors: 4 | - family-names: Bueler 5 | given-names: Ed 6 | title: "PETSc for Partial Differential Equations: Numerical Solutions in C and Python" 7 | date-released: 2021 8 | url: https://github.com/bueler/p4pdes 9 | preferred-citation: 10 | type: book 11 | authors: 12 | - family-names: Bueler 13 | given-names: Ed 14 | title: "PETSc for Partial Differential Equations: Numerical Solutions in C and Python" 15 | url: https://github.com/bueler/p4pdes 16 | isbn: 978111976304 17 | year: 2021 18 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-book.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite my book below. 3 | authors: 4 | - family-names: Bueler 5 | given-names: Ed 6 | title: "PETSc for Partial Differential Equations: Numerical Solutions in C and Python" 7 | date-released: 2021 8 | url: https://github.com/bueler/p4pdes 9 | preferred-citation: 10 | type: book 11 | authors: 12 | - family-names: Bueler 13 | given-names: Ed 14 | editors: 15 | - family-names: InChief 16 | given-names: Ed 17 | - family-names: Assist 18 | given-names: Ed 19 | title: "PETSc for Partial Differential Equations: Numerical Solutions in C and Python" 20 | publisher: 21 | name: SIAM Press 22 | city: Philadelphia 23 | url: https://github.com/bueler/p4pdes 24 | isbn: 978111976304 25 | year: 2021 26 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-conference-paper-2.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: This is a (partially) made up CFF - especially the dates. 3 | authors: 4 | - family-names: "Gamblin" 5 | given-names: "Todd" 6 | title: This won't be seen 7 | preferred-citation: 8 | type: conference-paper 9 | collection-title: Proceedings of Supercomputing 2015 10 | authors: 11 | - family-names: "Gamblin" 12 | given-names: "Todd" 13 | - family-names: "LeGendre" 14 | given-names: "Matthew" 15 | - family-names: "Collette" 16 | given-names: "Michael R." 17 | - family-names: "Lee" 18 | given-names: "Gregory L." 19 | - family-names: "Moody" 20 | given-names: "Adam" 21 | - family-names: "de Supinski" 22 | given-names: "Bronis R." 23 | - family-names: "Futral" 24 | given-names: "Scott" 25 | title: "The Spack Package Manager: Bringing Order to HPC Software Chaos" 26 | conference: 27 | name: "Supercomputing 2015 (SC’15)" 28 | date-start: 2015-11-15 29 | date-end: 2015-11-20 30 | city: "Austin" 31 | region: "Texas" 32 | country: "USA" 33 | publisher: 34 | name: ACM/IEEE 35 | editors-series: 36 | - family-names: InChief 37 | given-names: Ed 38 | - family-names: Assist 39 | given-names: Ed 40 | year: 2016 41 | month: 12 42 | doi: 10.1244/2886907.2879400 43 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-conference-paper-missing.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: This is a (partially) made up CFF. 3 | authors: 4 | - family-names: "Gamblin" 5 | given-names: "Todd" 6 | title: This won't be seen 7 | preferred-citation: 8 | type: conference-paper 9 | collection-title: Proceedings of Supercomputing 2015 10 | authors: 11 | - family-names: "Gamblin" 12 | given-names: "Todd" 13 | - family-names: "LeGendre" 14 | given-names: "Matthew" 15 | - family-names: "Collette" 16 | given-names: "Michael R." 17 | - family-names: "Lee" 18 | given-names: "Gregory L." 19 | - family-names: "Moody" 20 | given-names: "Adam" 21 | - family-names: "de Supinski" 22 | given-names: "Bronis R." 23 | - family-names: "Futral" 24 | given-names: "Scott" 25 | editors: 26 | - family-names: InChief 27 | given-names: Ed 28 | - family-names: Assist 29 | given-names: Ed 30 | editors-series: 31 | - family-names: NotListed 32 | given-names: Ed 33 | title: "The Spack Package Manager: Bringing Order to HPC Software Chaos" 34 | year: 2015 35 | month: 11 36 | doi: 10.1244/2886907.2879400 37 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-conference-paper-with-escapes.cff: -------------------------------------------------------------------------------- 1 | # A report preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: conference-paper 22 | conference: 23 | name: "Software Credit #1" 24 | title: "CFF is #1, 100%" 25 | authors: 26 | - family-names: Haines 27 | given-names: Robert 28 | affiliation: The University of Manchester 29 | - name: "The {curly_braces} Collective" 30 | publisher: 31 | name: The CFF & Friends 32 | collection-title: Software Credit for Fun & Profit ($$$) 33 | month: 9 34 | year: 2021 35 | url: https://github.com/citation-file-format/ruby-cff 36 | doi: 10.5281/zenodo.1184077 37 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-conference-paper.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this code, please cite the associated paper (see preferred-citation)." 3 | authors: 4 | - family-names: Rampin 5 | given-names: Rémi 6 | affiliation: New York University 7 | orcid: https://orcid.org/0000-0002-0524-2282 8 | website: https://remi.rampin.org/ 9 | title: This won't be seen 10 | preferred-citation: 11 | type: conference-paper 12 | doi: 10.1145/2882903.2899401 13 | conference: 14 | name: "SIGMOD '16" 15 | website: https://www.sigmod2016.org/ 16 | city: San Francisco 17 | country: US 18 | collection-title: Proceedings of the 2016 ACM SIGMOD International Conference on Management of Data (SIGMOD) 19 | authors: 20 | - family-names: Rampin 21 | given-names: Rémi 22 | affiliation: New York University 23 | orcid: https://orcid.org/0000-0002-0524-2282 24 | website: https://remi.rampin.org/ 25 | - family-names: Freire 26 | given-names: Juliana 27 | affiliation: New York University 28 | orcid: https://orcid.org/0000-0003-3915-7075 29 | website: https://vgc.poly.edu/~juliana/ 30 | - family-names: Chirigati 31 | given-names: Fernando 32 | affiliation: New York University 33 | orcid: https://orcid.org/0000-0002-9566-5835 34 | website: http://fchirigati.com/ 35 | - family-names: Shasha 36 | given-names: Dennis 37 | affiliation: New York University 38 | orcid: https://orcid.org/0000-0002-7036-3312 39 | website: http://cs.nyu.edu/shasha/ 40 | publisher: 41 | name: ACM 42 | date-published: 2016-06-26 43 | year: 2016 44 | month: 6 45 | title: "ReproZip: Computational Reproducibility With Ease" 46 | start: 2085 47 | end: 2088 48 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-in-prep.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | 15 | # JOSS paper as preferred citation 16 | preferred-citation: 17 | authors: 18 | - family-names: Wickham 19 | given-names: Hadley 20 | orcid: https://orcid.org/0000-0003-4757-117X 21 | title: "Welcome to the Tidyverse" 22 | type: unpublished 23 | status: in-preparation 24 | year: 2019 25 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-in-press.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | 15 | # JOSS paper as preferred citation 16 | preferred-citation: 17 | authors: 18 | - family-names: Wickham 19 | given-names: Hadley 20 | orcid: https://orcid.org/0000-0003-4757-117X 21 | journal: "Journal of Open Source Software" 22 | title: "Welcome to the Tidyverse" 23 | type: article 24 | status: in-press 25 | year: 2019 26 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-journal-with-escapes.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby-CFF 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | version: 0.1 10 | date-released: 2024-01-16 11 | 12 | # JOSS paper as preferred citation 13 | preferred-citation: 14 | authors: 15 | - family-names: Haines 16 | given-names: Robert 17 | journal: Journal of Maths & Philosophy 18 | month: 1 19 | title: "CFF for the $%&#_{} win" 20 | type: article 21 | volume: 1 22 | issue: 1 23 | year: 2024 24 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-manual.cff: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------- 2 | # CITATION file created with {cffr} R package, v0.0.1.9003 3 | # See also: https://dieghernan.github.io/cffr/ 4 | # ----------------------------------------------------------- 5 | 6 | cff-version: 1.2.0 7 | message: 'To cite package "cffr" in publications use:' 8 | type: software 9 | license: GPL-3.0-or-later 10 | title: 'cffr: Generate Citation File Format (''cff'') Metadata for R Packages' 11 | version: 0.0.1.9003 12 | doi: 10.5281/zenodo.5509766 13 | abstract: The Citation File Format version 1.2.0 (Druskat, S. et al. (2021) ) is a human and machine readable file format which provides citation metadata for software. This package provides core utilities to generate and validate this metadata. 14 | authors: 15 | - family-names: Hernangómez 16 | given-names: Diego 17 | email: diego.hernangomezherrero@gmail.com 18 | orcid: https://orcid.org/0000-0001-8457-4658 19 | preferred-citation: 20 | type: manual 21 | title: 'cffr: Generate Citation File Format (''cff'') Metadata for R Packages' 22 | authors: 23 | - family-names: Hernangómez 24 | given-names: Diego 25 | year: '2021' 26 | doi: 10.5281/zenodo.5509766 27 | url: https://dieghernan.github.io/cffr/ 28 | repository-code: https://github.com/dieghernan/cffr 29 | url: https://dieghernan.github.io/cffr/ 30 | contact: 31 | - family-names: Hernangómez 32 | given-names: Diego 33 | email: diego.hernangomezherrero@gmail.com 34 | orcid: https://orcid.org/0000-0001-8457-4658 35 | keywords: 36 | - attribution 37 | - citation 38 | - credit 39 | - citation-files 40 | - cff 41 | - metadata 42 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-masters-thesis-no-type.cff: -------------------------------------------------------------------------------- 1 | # A Master's thesis preferred citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: mastersthesis 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | institution: 28 | name: The CFF Institute 29 | month: 9 30 | year: 2021 31 | url: https://github.com/citation-file-format/ruby-cff 32 | doi: 10.5281/zenodo.1184077 33 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-masters-thesis.cff: -------------------------------------------------------------------------------- 1 | # A Master's thesis preferred citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: mastersthesis 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | institution: 28 | name: The CFF Institute 29 | thesis-type: MA thesis 30 | month: 9 31 | year: 2021 32 | url: https://github.com/citation-file-format/ruby-cff 33 | doi: 10.5281/zenodo.1184077 34 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-no-issue.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: "MPHW – Multipath Hardware" 3 | message: "Please always cite using the 'preferred-citation' (article); optionally, also cite the software/hardware work." 4 | type: software 5 | authors: 6 | - given-names: Felipe 7 | family-names: Geremia-Nievinski 8 | affiliation: Federal University of Rio Grande do Sul 9 | orcid: 'https://orcid.org/0000-0002-3325-1987' 10 | - given-names: Manuella A. R. 11 | family-names: Fagundes 12 | orcid: 'https://orcid.org/0000-0003-3447-8582' 13 | - given-names: Iuri 14 | family-names: Mendonça-Tinti 15 | orcid: 'https://orcid.org/0000-0002-6339-7426' 16 | identifiers: 17 | - type: url 18 | value: 'https://github.com/fgnievinski/mphw' 19 | date-released: "2019-05-07" 20 | preferred-citation: 21 | type: article 22 | title: "An open-source low-cost sensor for SNR-based GNSS reflectometry: design and long-term validation towards sea-level altimetry" 23 | authors: 24 | - given-names: Manuella A. R. 25 | family-names: Fagundes 26 | orcid: 'https://orcid.org/0000-0003-3447-8582' 27 | - given-names: Iuri 28 | family-names: Mendonça-Tinti 29 | orcid: 'https://orcid.org/0000-0002-6339-7426' 30 | - given-names: Andrea L. 31 | family-names: Iescheck 32 | orcid: 'https://orcid.org/0000-0002-8390-435X' 33 | - given-names: Dennis M. 34 | family-names: Akos 35 | orcid: 'https://orcid.org/0000-0003-4393-6442' 36 | - given-names: Felipe 37 | family-names: Geremia-Nievinski 38 | affiliation: Federal University of Rio Grande do Sul 39 | orcid: 'https://orcid.org/0000-0002-3325-1987' 40 | doi: 10.1007/s10291-021-01087-1 41 | journal: "GPS Solutions" 42 | volume: 25 43 | start: 73 44 | date-published: "2021-03-10" 45 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-no-month.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Lisa 5 | given-names: Mona 6 | title: My Research Software 7 | preferred-citation: 8 | type: article 9 | authors: 10 | - family-names: Lisa 11 | given-names: Mona 12 | journal: Journal Title 13 | title: My awesome research software 14 | year: 2021 15 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-no-vol.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this code, please cite the associated paper (see preferred-citation)." 3 | authors: 4 | - family-names: "Hartmann" 5 | given-names: "Jonas" 6 | orcid: "https://orcid.org/0000-0002-5600-8285" 7 | title: "data-driven-analysis-lateralline; code accompanying Hartmann et al., 2020" 8 | date-released: "2020-05-14" 9 | license: MIT 10 | repository-code: "https://github.com/WhoIsJack/data-driven-analysis-lateralline" 11 | preferred-citation: 12 | authors: 13 | - family-names: "Hartmann" 14 | given-names: "Jonas" 15 | orcid: "https://orcid.org/0000-0002-5600-8285" 16 | - family-names: "Wong" 17 | given-names: "Mie" 18 | - family-names: "Gallo" 19 | given-names: "Elisa" 20 | - family-names: "Gilmour" 21 | given-names: "Darren" 22 | orcid: "https://orcid.org/0000-0001-7613-090X" 23 | title: "An image-based data-driven analysis of cellular architecture in a developing tissue" 24 | type: article 25 | journal: eLife 26 | doi: "10.7554/eLife.55913" 27 | date-released: "2020-06-05" 28 | url: "https://elifesciences.org/articles/55913" 29 | start: 888 30 | end: 888 31 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-pamphlet.cff: -------------------------------------------------------------------------------- 1 | # A bound-but-not-published book preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | version: 0.4.0 15 | date-released: 2018-07-22 16 | license: Apache-2.0 17 | repository-artifact: https://rubygems.org/gems/cff 18 | type: software 19 | preferred-citation: 20 | type: pamphlet 21 | title: Why and how to use CFF 22 | authors: 23 | - family-names: Haines 24 | given-names: Robert 25 | affiliation: The University of Manchester, UK 26 | month: 9 27 | year: 2021 28 | url: https://github.com/citation-file-format/ruby-cff 29 | doi: 10.5281/zenodo.1184077 30 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-phd-thesis-no-type.cff: -------------------------------------------------------------------------------- 1 | # A PhD thesis preferred citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: phdthesis 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | institution: 28 | name: The CFF Institute 29 | month: 9 30 | year: 2021 31 | url: https://github.com/citation-file-format/ruby-cff 32 | doi: 10.5281/zenodo.1184077 33 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-phd-thesis.cff: -------------------------------------------------------------------------------- 1 | # A PhD thesis preferred citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: phdthesis 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | institution: 28 | name: The CFF Institute 29 | thesis-type: Habilitation thesis 30 | month: 9 31 | year: 2021 32 | url: https://github.com/citation-file-format/ruby-cff 33 | doi: 10.5281/zenodo.1184077 34 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-report-no-affiliation.cff: -------------------------------------------------------------------------------- 1 | # A report preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: report 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | month: 9 27 | year: 2021 28 | url: https://github.com/citation-file-format/ruby-cff 29 | doi: 10.5281/zenodo.1184077 30 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-report-no-institution.cff: -------------------------------------------------------------------------------- 1 | # A report preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: report 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | month: 9 28 | year: 2021 29 | url: https://github.com/citation-file-format/ruby-cff 30 | doi: 10.5281/zenodo.1184077 31 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-report.cff: -------------------------------------------------------------------------------- 1 | # A report preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | - cff 15 | version: 0.9.0 16 | date-released: 2021-09-21 17 | license: Apache-2.0 18 | repository-artifact: https://rubygems.org/gems/cff 19 | type: software 20 | preferred-citation: 21 | type: report 22 | title: The benefits of using CFF files 23 | authors: 24 | - family-names: Haines 25 | given-names: Robert 26 | affiliation: The University of Manchester 27 | institution: 28 | name: The CFF Institute 29 | month: 9 30 | year: 2021 31 | url: https://github.com/citation-file-format/ruby-cff 32 | doi: 10.5281/zenodo.1184077 33 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-submitted.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | 15 | # JOSS paper as preferred citation 16 | preferred-citation: 17 | authors: 18 | - family-names: Wickham 19 | given-names: Hadley 20 | orcid: https://orcid.org/0000-0003-4757-117X 21 | title: "Welcome to the Tidyverse" 22 | type: unpublished 23 | status: submitted 24 | year: 2019 25 | -------------------------------------------------------------------------------- /test/files/formatter/preferred-citation-unpublished.cff: -------------------------------------------------------------------------------- 1 | # An unpublished preferred-citation 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | version: 0.4.0 15 | date-released: 2018-07-22 16 | license: Apache-2.0 17 | repository-artifact: https://rubygems.org/gems/cff 18 | type: software 19 | preferred-citation: 20 | type: unpublished 21 | title: Why and how to use CFF 22 | authors: 23 | - family-names: Haines 24 | given-names: Robert 25 | affiliation: The University of Manchester, UK 26 | month: 9 27 | year: 2021 28 | url: https://github.com/citation-file-format/ruby-cff 29 | doi: 10.5281/zenodo.1184077 30 | notes: Self-published by the author. 31 | -------------------------------------------------------------------------------- /test/files/formatter/reprozip.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Rampin 5 | given-names: Remi 6 | affiliation: New York University 7 | orcid: https://orcid.org/0000-0002-0524-2282 8 | website: https://remi.rampin.org/ 9 | - family-names: Freire 10 | given-names: Juliana 11 | affiliation: New York University 12 | orcid: https://orcid.org/0000-0003-3915-7075 13 | website: https://vgc.poly.edu/~juliana/ 14 | - family-names: Chirigati 15 | given-names: Fernando 16 | affiliation: New York University 17 | orcid: https://orcid.org/0000-0002-9566-5835 18 | website: http://fchirigati.com/ 19 | - family-names: Shasha 20 | given-names: Dennis 21 | affiliation: New York University 22 | orcid: https://orcid.org/0000-0002-7036-3312 23 | website: http://cs.nyu.edu/shasha/ 24 | - family-names: Rampin 25 | given-names: Vicky 26 | affiliation: New York University 27 | orcid: https://orcid.org/0000-0003-4298-168X 28 | website: https://vicky.rampin.org/ 29 | license: BSD-3-Clause 30 | url: https://www.reprozip.org/ 31 | repository-code: https://github.com/VIDA-NYU/reprozip 32 | title: ReproZip 33 | abstract: | 34 | ReproZip is a tool aimed at simplifying the process of creating reproducible experiments from command-line executions, a frequently-used common denominator in computational science. It tracks operating system calls and creates a package that contains all the binaries, files and dependencies required to run a given command on the author's computational environment (packing step). 35 | keywords: [python, linux, docker, reproducibility, provenance, reproducible-research, reproducible-science] 36 | references: 37 | - type: proceedings 38 | doi: 10.1145/2882903.2899401 39 | conference: 40 | name: "SIGMOD '16" 41 | website: https://www.sigmod2016.org/ 42 | city: San Francisco 43 | country: US 44 | authors: 45 | - family-names: Rampin 46 | given-names: Remi 47 | affiliation: New York University 48 | orcid: https://orcid.org/0000-0002-0524-2282 49 | website: https://remi.rampin.org/ 50 | - family-names: Freire 51 | given-names: Juliana 52 | affiliation: New York University 53 | orcid: https://orcid.org/0000-0003-3915-7075 54 | website: https://vgc.poly.edu/~juliana/ 55 | - family-names: Chirigati 56 | given-names: Fernando 57 | affiliation: New York University 58 | orcid: https://orcid.org/0000-0002-9566-5835 59 | website: http://fchirigati.com/ 60 | - family-names: Shasha 61 | given-names: Dennis 62 | affiliation: New York University 63 | orcid: https://orcid.org/0000-0002-7036-3312 64 | website: http://cs.nyu.edu/shasha/ 65 | date-published: 2016-06-26 66 | year: 2016 67 | month: 6 68 | title: "ReproZip: Computational Reproducibility With Ease" 69 | abstract: | 70 | We present ReproZip, the recommended packaging tool for the SIGMOD Reproducibility Review. ReproZip was designed to simplify the process of making an existing computational experiment reproducible across platforms, even when the experiment was put together without reproducibility in mind. The tool creates a self-contained package for an experiment by automatically tracking and identifying all its required dependencies. The researcher can share the package with others, who can then use ReproZip to unpack the experiment, reproduce the findings on their favorite operating system, as well as modify the original experiment for reuse in new research, all with little effort. The demo will consist of examples of non-trivial experiments, showing how these can be packed in a Linux machine and reproduced on different machines and operating systems. Demo visitors will also be able to pack and reproduce their own experiments. 71 | - type: proceedings 72 | doi: 10.21105/joss.00107 73 | journal: Journal of Open Source Software 74 | authors: 75 | - family-names: Rampin 76 | given-names: Remi 77 | affiliation: New York University 78 | orcid: https://orcid.org/0000-0002-0524-2282 79 | website: https://remi.rampin.org/ 80 | - family-names: Freire 81 | given-names: Juliana 82 | affiliation: New York University 83 | orcid: https://orcid.org/0000-0003-3915-7075 84 | website: https://vgc.poly.edu/~juliana/ 85 | - family-names: Chirigati 86 | given-names: Fernando 87 | affiliation: New York University 88 | orcid: https://orcid.org/0000-0002-9566-5835 89 | website: http://fchirigati.com/ 90 | - family-names: Shasha 91 | given-names: Dennis 92 | affiliation: New York University 93 | orcid: https://orcid.org/0000-0002-7036-3312 94 | website: http://cs.nyu.edu/shasha/ 95 | - family-names: Rampin 96 | given-names: Vicky 97 | affiliation: New York University 98 | orcid: https://orcid.org/0000-0003-4298-168X 99 | website: https://vicky.rampin.org/ 100 | date-published: 2016-12-01 101 | year: 2016 102 | month: 12 103 | title: "ReproZip: The Reproducibility Packer" 104 | preferred-citation: 105 | type: proceedings 106 | doi: 10.1145/2882903.2899401 107 | conference: 108 | name: "SIGMOD '16" 109 | website: https://www.sigmod2016.org/ 110 | city: San Francisco 111 | country: US 112 | authors: 113 | - family-names: Rampin 114 | given-names: Remi 115 | affiliation: New York University 116 | orcid: https://orcid.org/0000-0002-0524-2282 117 | website: https://remi.rampin.org/ 118 | - family-names: Freire 119 | given-names: Juliana 120 | affiliation: New York University 121 | orcid: https://orcid.org/0000-0003-3915-7075 122 | website: https://vgc.poly.edu/~juliana/ 123 | - family-names: Chirigati 124 | given-names: Fernando 125 | affiliation: New York University 126 | orcid: https://orcid.org/0000-0002-9566-5835 127 | website: http://fchirigati.com/ 128 | - family-names: Shasha 129 | given-names: Dennis 130 | affiliation: New York University 131 | orcid: https://orcid.org/0000-0002-7036-3312 132 | website: http://cs.nyu.edu/shasha/ 133 | date-published: 2016-06-26 134 | year: 2016 135 | month: 6 136 | title: "ReproZip: Computational Reproducibility With Ease" 137 | abstract: | 138 | We present ReproZip, the recommended packaging tool for the SIGMOD Reproducibility Review. ReproZip was designed to simplify the process of making an existing computational experiment reproducible across platforms, even when the experiment was put together without reproducibility in mind. The tool creates a self-contained package for an experiment by automatically tracking and identifying all its required dependencies. The researcher can share the package with others, who can then use ReproZip to unpack the experiment, reproduce the findings on their favorite operating system, as well as modify the original experiment for reuse in new research, all with little effort. The demo will consist of examples of non-trivial experiments, showing how these can be packed in a Linux machine and reproduced on different machines and operating systems. Demo visitors will also be able to pack and reproduce their own experiments. 139 | version: "1.1" 140 | date-released: 2021-07-06 141 | doi: 10.5281/zenodo.5081097 142 | -------------------------------------------------------------------------------- /test/files/formatter/short-with-aliases.cff: -------------------------------------------------------------------------------- 1 | # An incomplete CFF file with aliases 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: &authors 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | keywords: &keywords 11 | - ruby 12 | - credit 13 | - citation 14 | version: 0.4.0 15 | date-released: 2018-07-22 16 | license: Apache-2.0 17 | repository-artifact: https://rubygems.org/gems/cff 18 | type: software 19 | references: 20 | - type: software 21 | title: Citation File Format 22 | authors: *authors 23 | keywords: *keywords 24 | -------------------------------------------------------------------------------- /test/files/formatter/smith-et-al.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: If you use this software, please cite it as below. 3 | authors: 4 | - family-names: Smith 5 | given-names: Arfon M. 6 | - family-names: Katz 7 | given-names: Daniel S. 8 | - family-names: Niemeyer 9 | given-names: Kyle E. 10 | - name: "FORCE11 Software Citation Working Group" 11 | title: "Software citation principles" 12 | preferred-citation: 13 | authors: 14 | - family-names: Smith 15 | given-names: A. M. 16 | - family-names: Katz 17 | given-names: D. S. 18 | - family-names: Niemeyer 19 | given-names: K. E. 20 | - name: "FORCE11 Software Citation Working Group" 21 | doi: "10.7717/peerj-cs.86" 22 | journal: "PeerJ Computer Science" 23 | month: 9 24 | start: e86 25 | title: "Software citation principles" 26 | type: article 27 | volume: 2 28 | issue: 123 29 | year: 2016 30 | -------------------------------------------------------------------------------- /test/files/formatter/software-missing-family-name.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: Tweepy 3 | message: "If you use Tweepy, please cite it using this metadata." 4 | abstract: "Tweepy is a Python library for interfacing with Twitter's API." 5 | authors: 6 | - given-names: Harmon 7 | alias: Harmon758 8 | orcid: "https://orcid.org/0000-0002-2632-0921" 9 | - given-names: Joshua 10 | family-names: Roesslein 11 | - name: "other contributors" 12 | doi: 10.5281/zenodo.7259945 13 | identifiers: 14 | - description: "The concept DOI for the collection containing all versions of Tweepy" 15 | type: doi 16 | value: 10.5281/zenodo.7259945 17 | - description: "The versioned DOI for version 4.12.0 of Tweepy" 18 | type: doi 19 | value: 10.5281/zenodo.7259946 20 | keywords: 21 | - Python 22 | - Twitter 23 | license: MIT 24 | repository-code: 'https://github.com/tweepy/tweepy' 25 | type: software 26 | url: 'https://www.tweepy.org/' 27 | -------------------------------------------------------------------------------- /test/files/formatter/software-missing-given-name.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: Tweepy 3 | message: "If you use Tweepy, please cite it using this metadata." 4 | abstract: "Tweepy is a Python library for interfacing with Twitter's API." 5 | authors: 6 | - given-names: Joshua 7 | family-names: Roesslein 8 | - family-names: Harmon 9 | alias: Harmon758 10 | orcid: "https://orcid.org/0000-0002-2632-0921" 11 | - name: "other contributors" 12 | doi: 10.5281/zenodo.7259945 13 | identifiers: 14 | - description: "The concept DOI for the collection containing all versions of Tweepy" 15 | type: doi 16 | value: 10.5281/zenodo.7259945 17 | - description: "The versioned DOI for version 4.12.0 of Tweepy" 18 | type: doi 19 | value: 10.5281/zenodo.7259946 20 | keywords: 21 | - Python 22 | - Twitter 23 | license: MIT 24 | repository-code: 'https://github.com/tweepy/tweepy' 25 | type: software 26 | url: 'https://www.tweepy.org/' 27 | -------------------------------------------------------------------------------- /test/files/formatter/software-with-alias.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: Tweepy 3 | message: "If you use Tweepy, please cite it using this metadata." 4 | abstract: "Tweepy is a Python library for interfacing with Twitter's API." 5 | authors: 6 | - alias: Harmon758 7 | orcid: "https://orcid.org/0000-0002-2632-0921" 8 | - given-names: Joshua 9 | family-names: Roesslein 10 | - name: "other contributors" 11 | doi: 10.5281/zenodo.7259945 12 | identifiers: 13 | - description: "The concept DOI for the collection containing all versions of Tweepy" 14 | type: doi 15 | value: 10.5281/zenodo.7259945 16 | - description: "The versioned DOI for version 4.12.0 of Tweepy" 17 | type: doi 18 | value: 10.5281/zenodo.7259946 19 | keywords: 20 | - Python 21 | - Twitter 22 | license: MIT 23 | repository-code: 'https://github.com/tweepy/tweepy' 24 | type: software 25 | url: 'https://www.tweepy.org/' 26 | -------------------------------------------------------------------------------- /test/files/formatter/software-with-escapes.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: Haines 5 | given-names: Robert 6 | - name: "The {curly_braces} Collective" 7 | title: "Software that uses the following symbols: &, %, $, #" 8 | version: 0.0.1-alpha 9 | date-released: 2024-01-16 10 | -------------------------------------------------------------------------------- /test/files/formatter/tidyverse-joss-paper.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | 15 | # JOSS paper as preferred citation 16 | preferred-citation: 17 | authors: 18 | - family-names: Wickham 19 | given-names: Hadley 20 | orcid: https://orcid.org/0000-0003-4757-117X 21 | doi: "10.21105/joss.01686" 22 | journal: "Journal of Open Source Software" 23 | month: 11 24 | start: 1686 25 | title: "Welcome to the Tidyverse" 26 | type: article 27 | volume: 4 28 | issue: 43 29 | year: 2019 30 | -------------------------------------------------------------------------------- /test/files/formatter/tidyverse-software.cff: -------------------------------------------------------------------------------- 1 | # Note this is a made up entry. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Tidyverse 6 | authors: 7 | - family-names: Wickham 8 | given-names: Hadley 9 | orcid: https://orcid.org/0000-0003-4757-117X 10 | version: 1.3.1 11 | date-released: 2021-04-15 12 | license: MIT 13 | repository-artifact: https://github.com/tidyverse/tidyverse 14 | url: https://github.com/tidyverse/tidyverse 15 | -------------------------------------------------------------------------------- /test/files/formatter/xenon-middleware_xenon-adaptors-cloud.cff: -------------------------------------------------------------------------------- 1 | # YAML 1.2 2 | # Metadata for citation of this software according to the CFF format (https://citation-file-format.github.io/) 3 | cff-version: 1.0.3 4 | message: If you use this software, please cite it as below. 5 | title: Cloud related adaptors for Xenon 6 | authors: 7 | - given-names: Stefan 8 | family-names: Verhoeven 9 | affiliation: Nederlands eScience Center 10 | orcid: https://orcid.org/0000-0002-5821-2060 11 | - given-names: Jason 12 | family-names: Maassen 13 | affiliation: Netherlands eScience Center 14 | - given-names: Atze 15 | family-names: Ploeg 16 | name-particle: van der 17 | affiliation: Netherlands eScience Center 18 | version: 3.0.2 19 | doi: 10.5281/zenodo.3245389 20 | date-released: '2019-08-07' 21 | repository-code: https://github.com/xenon-middleware/xenon-adaptors-cloud 22 | license: Apache-2.0 23 | references: 24 | - type: software 25 | doi: 10.5281/zenodo.597993 26 | title: Xenon 27 | authors: 28 | - given-names: Jason 29 | family-names: Maassen 30 | affiliation: Netherlands eScience Center 31 | - given-names: Stefan 32 | family-names: Verhoeven 33 | affiliation: Nederlands eScience Center 34 | - given-names: Joris 35 | family-names: Borgdorff 36 | affiliation: '@thehyve' 37 | - given-names: Niels 38 | family-names: Drost 39 | affiliation: Netherlands eScience Center 40 | - given-names: Jurriaan 41 | family-names: Spaaks 42 | name-particle: H. 43 | affiliation: Netherlands eScience Center 44 | - given-names: Christiaan 45 | family-names: Meijer 46 | affiliation: Netherlands eScience Center 47 | - given-names: Rob 48 | family-names: van Nieuwpoort 49 | name-particle: V. 50 | affiliation: Netherlands eScience center 51 | - given-names: Atze 52 | family-names: van der Ploeg 53 | affiliation: Netherlands eScience center 54 | - given-names: Piter 55 | family-names: de Boer 56 | name-particle: T. 57 | affiliation: Netherlands eScience center 58 | - given-names: Ben 59 | family-names: van Werkhoven 60 | affiliation: Netherlands eScience Center 61 | - given-names: Arnold 62 | family-names: Kuzniar 63 | affiliation: Netherlands eScience Center 64 | -------------------------------------------------------------------------------- /test/files/minimal.cff: -------------------------------------------------------------------------------- 1 | # A minimal CFF file with only the required fields included. 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | version: 0.4.0 11 | date-released: 2018-07-22 12 | -------------------------------------------------------------------------------- /test/files/short.cff: -------------------------------------------------------------------------------- 1 | # An incomplete CFF file 2 | 3 | cff-version: 1.0.3 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | keywords: 11 | - ruby 12 | - credit 13 | - citation 14 | version: 0.4.0 15 | date-released: 2018-07-22 16 | license: Apache-2.0 17 | repository-artifact: https://rubygems.org/gems/cff 18 | type: dataset 19 | -------------------------------------------------------------------------------- /test/files/validation/aliases.cff: -------------------------------------------------------------------------------- 1 | # An incomplete CFF file with aliases 2 | 3 | cff-version: 1.2.0 4 | message: If you use this software in your work, please cite it using the following metadata 5 | title: Ruby CFF Library 6 | authors: &authors 7 | - family-names: Haines 8 | given-names: Robert 9 | affiliation: The University of Manchester, UK 10 | keywords: &keywords 11 | - ruby 12 | - credit 13 | - citation 14 | version: 0.4.0 15 | date-released: 2018-07-22 16 | license: Apache-2.0 17 | repository-artifact: https://rubygems.org/gems/cff 18 | type: software 19 | references: 20 | - type: software 21 | title: Citation File Format 22 | authors: *authors 23 | keywords: *keywords 24 | -------------------------------------------------------------------------------- /test/files/validation/partial-reference.cff: -------------------------------------------------------------------------------- 1 | cff-version: "1.1.0" 2 | message: | 3 | To reference this project in scholarly work, please cite the following work. 4 | To reference a particular version of these standards, please see the entries 5 | under "references" 6 | title: "Methods Included: Standardizing Computational Reuse and Portability" 7 | identifiers: 8 | - type: url 9 | value: "https://example.org/abs/2105.07028" 10 | authors: 11 | - given-names: "Michael R." 12 | family-names: Crusoe 13 | affiliation: "VU Amsterdam, Department of Computer Science; Software Freedom Conservancy, Common Workflow Language project" 14 | orcid: "https://orcid.org/0000-0000-0000-0000" 15 | references: 16 | - type: standard 17 | title: "Common Workflow Language, v1.0" 18 | authors: 19 | - given-names: Peter 20 | family-names: Amstutz 21 | orcid: "https://orcid.org/0000-0000-0000-0000" 22 | affiliation: "Arvados Veritas" 23 | -------------------------------------------------------------------------------- /test/formatters/apalike_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../test_helper' 4 | 5 | require 'cff/formatters/apalike' 6 | require 'cff/file' 7 | 8 | class CFFApaFormatterTest < Minitest::Test 9 | describe 'all apa fixtures' do 10 | Dir[::File.join(FORMATTER_DIR, '*.cff')].each do |input_file| 11 | define_method("test_converter_for_#{File.basename(input_file)}") do 12 | cff = ::CFF::File.read(input_file) 13 | output_file = ::File.join(FORMATTED_DIR, "#{File.basename(input_file, '.*')}.apa") 14 | 15 | if ::File.exist?(output_file) 16 | assert_equal File.read(output_file).strip, cff.to_apalike 17 | else 18 | assert_nil cff.to_apalike 19 | end 20 | end 21 | end 22 | end 23 | 24 | def test_formatter_label 25 | assert_equal('APALike', CFF::Formatters::APALike.label) 26 | end 27 | 28 | def test_can_tolerate_invalid_file 29 | cff = CFF::Index.new(nil) 30 | assert_nil cff.to_apalike 31 | end 32 | 33 | def test_type_label_from_model 34 | index = ::CFF::Index.new('Title') 35 | assert_equal( 36 | ' [Computer software]', CFF::Formatters::APALike.type_label(index) 37 | ) 38 | 39 | index.type = 'wrong' 40 | assert_equal( 41 | ' [Computer software]', CFF::Formatters::APALike.type_label(index) 42 | ) 43 | 44 | index.type = 'software' 45 | assert_equal( 46 | ' [Computer software]', CFF::Formatters::APALike.type_label(index) 47 | ) 48 | 49 | index.type = 'dataset' 50 | assert_equal( 51 | ' [Data set]', CFF::Formatters::APALike.type_label(index) 52 | ) 53 | end 54 | 55 | def test_type_label_from_reference 56 | ref = ::CFF::Reference.new('Title') 57 | assert_equal('', CFF::Formatters::APALike.type_label(ref)) 58 | 59 | ref.type = 'book' 60 | assert_equal('', CFF::Formatters::APALike.type_label(ref)) 61 | 62 | ref.type = 'software' 63 | assert_equal( 64 | ' [Computer software]', CFF::Formatters::APALike.type_label(ref) 65 | ) 66 | 67 | ref.type = 'software-container' 68 | assert_equal( 69 | ' [Computer software]', CFF::Formatters::APALike.type_label(ref) 70 | ) 71 | 72 | ref.type = 'database' 73 | assert_equal(' [Data set]', CFF::Formatters::APALike.type_label(ref)) 74 | end 75 | 76 | def test_month_and_year_from_model 77 | date = Date.new(2021, 9, 21) 78 | conf = ::CFF::Entity.new('Conference') 79 | ref = ::CFF::Reference.new('Title', 'conference-paper') 80 | ref.year = 2019 81 | ref.month = 12 82 | 83 | # Conference type reference with no conference set. 84 | assert_equal('2019', CFF::Formatters::APALike.month_and_year_from_model(ref)) 85 | 86 | # Conference set, but no start date. 87 | ref.conference = conf 88 | assert_equal('2019', CFF::Formatters::APALike.month_and_year_from_model(ref)) 89 | 90 | # Conference with a start date but no end date. 91 | conf.date_start = date 92 | assert_equal('2021', CFF::Formatters::APALike.month_and_year_from_model(ref)) 93 | 94 | # Conference with the same start and end date. 95 | conf.date_end = date 96 | assert_equal('2021', CFF::Formatters::APALike.month_and_year_from_model(ref)) 97 | 98 | # Conference with a different start and end date. 99 | conf.date_end = date + 5 100 | assert_equal( 101 | '2021, September 21–26', 102 | CFF::Formatters::APALike.month_and_year_from_model(ref) 103 | ) 104 | 105 | # Conference with earlier end date than start date (bad range). 106 | conf.date_end = date - 1 107 | assert_equal('2021', CFF::Formatters::APALike.month_and_year_from_model(ref)) 108 | end 109 | 110 | def test_date_range 111 | start = Date.new(2021, 9, 21) 112 | finish = start + 3 113 | assert_equal( 114 | '2021, September 21–24', CFF::Formatters::APALike.date_range(start, finish) 115 | ) 116 | 117 | finish = start + 10 118 | assert_equal( 119 | '2021, September 21–October 1', 120 | CFF::Formatters::APALike.date_range(start, finish) 121 | ) 122 | 123 | start = Date.new(1999, 12, 31) 124 | finish = Date.new(2000, 1, 1) 125 | assert_equal( 126 | '1999, December 31–2000, January 1', 127 | CFF::Formatters::APALike.date_range(start, finish) 128 | ) 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /test/formatters/bibtex_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../test_helper' 4 | 5 | require 'cff/formatters/bibtex' 6 | require 'cff/file' 7 | 8 | class CFFBibtexFormatterTest < Minitest::Test 9 | describe 'all bibtex fixtures' do 10 | Dir[::File.join(FORMATTER_DIR, '*.cff')].each do |input_file| 11 | define_method("test_converter_for_#{File.basename(input_file)}") do 12 | cff = ::CFF::File.read(input_file) 13 | output_file = ::File.join(FORMATTED_DIR, "#{File.basename(input_file, '.*')}.bibtex") 14 | 15 | if ::File.exist?(output_file) 16 | assert_equal File.read(output_file).strip, cff.to_bibtex 17 | else 18 | assert_nil cff.to_bibtex 19 | end 20 | end 21 | end 22 | end 23 | 24 | def test_formatter_label 25 | assert_equal('BibTeX', CFF::Formatters::BibTeX.label) 26 | end 27 | 28 | def test_can_tolerate_invalid_file 29 | cff = CFF::Index.new(nil) 30 | assert_nil cff.to_bibtex 31 | end 32 | 33 | def test_bibtex_type 34 | index = ::CFF::Index.new('Title') 35 | assert_equal('software', CFF::Formatters::BibTeX.bibtex_type(index)) 36 | 37 | index.type = 'software' 38 | assert_equal('software', CFF::Formatters::BibTeX.bibtex_type(index)) 39 | 40 | index.type = 'dataset' 41 | assert_equal('misc', CFF::Formatters::BibTeX.bibtex_type(index)) 42 | 43 | ref = ::CFF::Reference.new('Title') 44 | assert_equal('misc', CFF::Formatters::BibTeX.bibtex_type(ref)) 45 | 46 | ref.type = 'newspaper-article' 47 | assert_equal('article', CFF::Formatters::BibTeX.bibtex_type(ref)) 48 | 49 | ref.type = 'conference' 50 | assert_equal('proceedings', CFF::Formatters::BibTeX.bibtex_type(ref)) 51 | 52 | ref.type = 'conference-paper' 53 | assert_equal('inproceedings', CFF::Formatters::BibTeX.bibtex_type(ref)) 54 | 55 | ref.type = 'proceedings' 56 | assert_equal('proceedings', CFF::Formatters::BibTeX.bibtex_type(ref)) 57 | 58 | ref.type = 'pamphlet' 59 | assert_equal('booklet', CFF::Formatters::BibTeX.bibtex_type(ref)) 60 | 61 | ['article', 'book', 'manual', 'unpublished'].each do |type| 62 | ref.type = type 63 | assert_equal(type, CFF::Formatters::BibTeX.bibtex_type(ref)) 64 | end 65 | end 66 | 67 | def test_generate_citekey 68 | [ 69 | [ 70 | { 71 | 'author' => 'von Haines, Jr, Robert and Robert, Haines', 72 | 'title' => 'My Family and Other Animals', 73 | 'year' => '2021' 74 | }, 75 | 'von_Haines_My_Family_and_2021' 76 | ], 77 | [ 78 | { 79 | 'year' => nil, 80 | 'author' => '{An Organisation}', 81 | 'title' => "Really?! 'Everyone' Disagrees?" 82 | }, 83 | 'An_Organisation_Really_Everyone_Disagrees' 84 | ], 85 | [ 86 | { 87 | 'author' => 'Solskjær, Ole Gunnar', 88 | 'title' => 'My Straße', 89 | 'year' => '2021' 90 | }, 91 | 'Solskjaer_My_Strasse_2021' 92 | ] 93 | ].each do |fields, reference| 94 | assert_equal(reference, CFF::Formatters::BibTeX.generate_citekey(fields)) 95 | end 96 | end 97 | end 98 | -------------------------------------------------------------------------------- /test/formatters/formatter_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2023 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative '../test_helper' 18 | 19 | require 'cff/formatters/formatter' 20 | require 'cff/index' 21 | 22 | class CFFFormatterTest < Minitest::Test 23 | def test_month_and_year_from_date 24 | [nil, '', ' ', 'nil'].each do |date| 25 | assert_equal(['', ''], CFF::Formatters::Formatter.month_and_year_from_date(date)) 26 | end 27 | 28 | assert_equal( 29 | ['8', '2021'], 30 | CFF::Formatters::Formatter.month_and_year_from_date(Date.parse('2021-08-05')) 31 | ) 32 | end 33 | 34 | def test_month_and_year_from_model 35 | date = Date.parse('2021-08-05') 36 | 37 | model = ::CFF::Index.new('Title') 38 | model.date_released = date 39 | assert_equal( 40 | ['8', '2021'], CFF::Formatters::Formatter.month_and_year_from_model(model) 41 | ) 42 | 43 | ref = ::CFF::Reference.new('Title') 44 | ref.date_released = date 45 | assert_equal( 46 | ['8', '2021'], CFF::Formatters::Formatter.month_and_year_from_model(ref) 47 | ) 48 | 49 | ref = ::CFF::Reference.new('Title') 50 | ref.month = 9 51 | ref.year = 2020 52 | assert_equal( 53 | ['9', '2020'], CFF::Formatters::Formatter.month_and_year_from_model(ref) 54 | ) 55 | 56 | # No dates. 57 | ref = ::CFF::Reference.new('Title') 58 | assert_equal( 59 | ['', ''], CFF::Formatters::Formatter.month_and_year_from_model(ref) 60 | ) 61 | 62 | # Ignore date_released if month and year set. 63 | ref = ::CFF::Reference.new('Title') 64 | ref.month = 9 65 | ref.year = 2020 66 | ref.date_released = date 67 | assert_equal( 68 | ['9', '2020'], CFF::Formatters::Formatter.month_and_year_from_model(ref) 69 | ) 70 | 71 | # Year missing, fall back to date_released. 72 | ref = ::CFF::Reference.new('Title') 73 | ref.month = 9 74 | ref.date_released = date 75 | assert_equal( 76 | ['8', '2021'], CFF::Formatters::Formatter.month_and_year_from_model(ref) 77 | ) 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /test/formatters_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/formatters' 20 | 21 | class CFFFormattersTest < Minitest::Test 22 | # Fake formatter. 23 | class TestFormatter 24 | def self.format; end 25 | 26 | def self.label 27 | 'TestFormatterLabel' 28 | end 29 | end 30 | 31 | # Another fake formatter, with the same label. 32 | class AnotherTestFormatter 33 | def self.format; end 34 | 35 | def self.label 36 | 'TestFormatterLabel' 37 | end 38 | end 39 | 40 | def setup 41 | CFF::Formatters.register_formatter(TestFormatter) 42 | end 43 | 44 | def test_register_formatter 45 | # Check that a new formatter with the same label overrides the incumbent. 46 | assert( 47 | CFF::Formatters.instance_variable_get(:@formatters).has_value?(TestFormatter) 48 | ) 49 | 50 | CFF::Formatters.register_formatter(AnotherTestFormatter) 51 | 52 | refute( 53 | CFF::Formatters.instance_variable_get(:@formatters).has_value?(TestFormatter) 54 | ) 55 | assert( 56 | CFF::Formatters.instance_variable_get(:@formatters).has_value?(AnotherTestFormatter) 57 | ) 58 | end 59 | 60 | def test_register_non_formatter 61 | CFF::Formatters.register_formatter(String) 62 | refute(CFF::Formatters.instance_variable_get(:@formatters).has_value?(String)) 63 | end 64 | 65 | def test_formatter_for 66 | # At this point we don't know which of our two test formatters is 67 | # registered because test execution order is random. 68 | refute_nil(CFF::Formatters.formatter_for(:testformatterlabel)) 69 | 70 | assert_nil(CFF::Formatters.formatter_for(:bad_test)) 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /test/identifier_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'yaml' 20 | require 'cff/identifier' 21 | 22 | class CFFIdentifierTest < Minitest::Test 23 | def test_new 24 | id = ::CFF::Identifier.new('doi', '10.5281/zenodo.1184077') 25 | assert_equal('doi', id.type) 26 | assert_equal('10.5281/zenodo.1184077', id.value) 27 | end 28 | 29 | def test_new_with_block 30 | id = ::CFF::Identifier.new('doi', '10.5281/zenodo.1184077') do |i| 31 | assert_equal('doi', i.type) 32 | assert_equal('10.5281/zenodo.1184077', i.value) 33 | i.value = '10.9999/zenodo.1234567' 34 | end 35 | 36 | assert_equal('doi', id.type) 37 | assert_equal('10.9999/zenodo.1234567', id.value) 38 | assert id.is_a?(::CFF::Identifier) 39 | end 40 | 41 | def test_new_no_params 42 | id = ::CFF::Identifier.new 43 | assert_empty(id.type) 44 | assert_empty(id.value) 45 | end 46 | 47 | def test_new_bad_type 48 | id = ::CFF::Identifier.new('xxx', '0123456789') 49 | assert_empty(id.type) 50 | assert_empty(id.value) 51 | 52 | id = ::CFF::Identifier.new('', '0123456789') 53 | assert_empty(id.type) 54 | assert_empty(id.value) 55 | 56 | id = ::CFF::Identifier.new(nil, '0123456789') 57 | assert_empty(id.type) 58 | assert_empty(id.value) 59 | end 60 | 61 | def test_bad_methods_not_allowed 62 | id = ::CFF::Identifier.new 63 | 64 | refute_respond_to(id, :aaaaaaa) 65 | assert_raises(NoMethodError) do 66 | id.aaaaaaa 67 | end 68 | 69 | refute_respond_to(id, :Type) 70 | assert_raises(NoMethodError) do 71 | id.Type = 'swh' 72 | end 73 | end 74 | 75 | def test_type_restricted_to_allowed_types 76 | id = ::CFF::Identifier.new 77 | 78 | id.type = 'doi' 79 | assert_equal('doi', id.type) 80 | 81 | id.type = 'xxx' 82 | assert_equal('doi', id.type) 83 | 84 | id.type = 'SWH' 85 | assert_equal('swh', id.type) 86 | end 87 | 88 | def test_simple_fields_set_and_output_correctly 89 | id = ::CFF::Identifier.new 90 | value = 'swh:1:rel:99f6850374dc6597af01bd0ee1d3fc0699301b9f' 91 | desc = 'Software Heritage ID' 92 | 93 | assert_equal('', id.value) 94 | id.value = value 95 | assert_equal(value, id.value) 96 | 97 | assert_equal('', id.description) 98 | id.description = desc 99 | assert_equal(desc, id.description) 100 | 101 | y = id.fields.to_yaml 102 | 103 | assert_includes(y, "value: #{value}\n") 104 | assert_includes(y, "description: #{desc}\n") 105 | end 106 | 107 | def test_empty? 108 | id = ::CFF::Identifier.new 109 | refute_empty(id) 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /test/person_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'yaml' 20 | require 'cff/person' 21 | 22 | class CFFPersonTest < Minitest::Test 23 | include TestUtil 24 | 25 | def setup 26 | @person = ::CFF::Person.new('Rob', 'Haines') 27 | end 28 | 29 | def test_bad_methods_not_allowed 30 | refute_respond_to(@person, :aaaaaaa) 31 | assert_raises(NoMethodError) do 32 | @person.aaaaaaa 33 | end 34 | 35 | refute_respond_to(@person, :Affiliation) 36 | assert_raises(NoMethodError) do 37 | @person.Affiliation = 'Company' 38 | end 39 | end 40 | 41 | def test_simple_fields_set_and_output_correctly 42 | data = [ 43 | ['address', 'A street'], 44 | ['affiliation', 'A University'], 45 | ['alias', 'A Pseudonym'], 46 | ['city', 'Manchester'], 47 | ['country', 'GB'], 48 | ['email', 'email@example.org'], 49 | ['name-particle', 'van der'], 50 | ['name-suffix', 'III'], 51 | ['orcid', 'https://orcid.org/0000-0001-2345-6789'], 52 | ['post-code', 'M13 9PL'], 53 | ['region', 'Greater Manchester'], 54 | ['website', 'https://home.example.org'] 55 | ] 56 | 57 | data.each do |method, value| 58 | assert_equal('', @person.send(method)) 59 | @person.send("#{method}=", value) 60 | assert_equal(value, @person.send(method)) 61 | end 62 | 63 | y = @person.fields.to_yaml 64 | 65 | data.each do |method, value| 66 | assert_includes(y, "#{method_to_field(method)}: #{value}\n") 67 | end 68 | end 69 | 70 | def test_tel_fax_fields_set_and_output_correctly 71 | number = '+44 (0) 161-234-5678' 72 | @person.fax = number 73 | @person.tel = number 74 | 75 | assert_equal(number, @person.fax) 76 | assert_equal(number, @person.tel) 77 | 78 | y = @person.fields.to_yaml 79 | 80 | assert_includes(y, "fax: \"#{number}\"\n") 81 | assert_includes(y, "tel: \"#{number}\"\n") 82 | end 83 | 84 | def test_new_with_block 85 | person = ::CFF::Person.new('Rob', 'Haines') do |p| 86 | assert_equal('Rob', p.given_names) 87 | assert_equal('Haines', p.family_names) 88 | p.email = 'email@example.org' 89 | end 90 | 91 | assert_equal('Rob', person.given_names) 92 | assert_equal('Haines', person.family_names) 93 | assert_equal('email@example.org', person.email) 94 | assert person.is_a?(::CFF::Person) 95 | end 96 | 97 | def test_new_no_params 98 | person = ::CFF::Person.new 99 | assert_empty(person.given_names) 100 | assert_empty(person.family_names) 101 | end 102 | 103 | def test_new_no_params_with_block 104 | person = ::CFF::Person.new do |p| 105 | assert_empty(p.given_names) 106 | assert_empty(p.family_names) 107 | p.alias = 'E.T.' 108 | end 109 | 110 | assert_equal('E.T.', person.alias) 111 | end 112 | 113 | def test_empty? 114 | refute_empty(@person) 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require 'simplecov' 18 | require 'test_construct' 19 | require 'minitest/autorun' 20 | 21 | Minitest::Test.make_my_diffs_pretty! 22 | 23 | FILES_DIR = ::File.expand_path('files', __dir__) 24 | OUT_FILES_DIR = ::File.join(FILES_DIR, 'out') 25 | COMPLETE_CFF = ::File.join(FILES_DIR, 'complete.cff') 26 | SHORT_CFF = ::File.join(FILES_DIR, 'short.cff') 27 | MINIMAL_CFF = ::File.join(FILES_DIR, 'minimal.cff') 28 | INCOMPLETE_CFF = ::File.join(FILES_DIR, 'bad', 'incomplete.cff') 29 | NO_CFF_VERSION_CFF = ::File.join(FILES_DIR, 'bad', 'CITATION.cff') 30 | VALID_FILENAME_CFF = ::File.join(__dir__, '..', 'CITATION.cff') 31 | OUTPUT_CFF = 'CITATION.cff' 32 | 33 | VALIDATION_DIR = ::File.join(FILES_DIR, 'validation') 34 | FORMATTER_DIR = ::File.join(FILES_DIR, 'formatter') 35 | FORMATTED_DIR = ::File.join(FILES_DIR, 'formatted') 36 | 37 | CONSTRUCT_OPTS = { 38 | keep_on_error: true 39 | }.freeze 40 | 41 | module TestUtil 42 | def method_to_field(name) 43 | name.tr('_', '-') 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/util_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2024 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/util' 20 | 21 | class CFFUtilTest < Minitest::Test 22 | include ::CFF::Util 23 | 24 | def test_update_cff_version 25 | assert_equal('', update_cff_version('')) 26 | assert_equal(::CFF::MIN_VALIDATABLE_VERSION, update_cff_version('1.0.3')) 27 | assert_equal(::CFF::MIN_VALIDATABLE_VERSION, update_cff_version('1.1.0')) 28 | assert_equal('1.2.0', update_cff_version('1.2.0')) 29 | assert_equal('1.2.1', update_cff_version('1.2.1')) 30 | end 31 | 32 | def test_build_actor_collection 33 | array = [ 34 | { 'family-names' => 'Second', 'given-names' => 'First' }, 35 | { 'name' => 'Company' }, 36 | ::CFF::Person.new('Firstname', 'Secondname'), 37 | ::CFF::Entity.new('Company Inc.') 38 | ] 39 | 40 | build_actor_collection!(array) 41 | assert_equal(4, array.length) 42 | assert_instance_of ::CFF::Person, array[0] 43 | assert_equal('First', array[0].given_names) 44 | assert_instance_of ::CFF::Entity, array[1] 45 | assert_equal('Company', array[1].name) 46 | assert_instance_of ::CFF::Person, array[2] 47 | assert_equal('Firstname', array[2].given_names) 48 | assert_instance_of ::CFF::Entity, array[3] 49 | assert_equal('Company Inc.', array[3].name) 50 | end 51 | 52 | def test_normalize_modelpart_array 53 | string = 'some text' 54 | data = [ 55 | ::CFF::Person.new('First', 'Second'), 56 | string, 57 | ::CFF::Entity.new('Company') 58 | ] 59 | 60 | normalize_modelpart_array!(data) 61 | 62 | assert_equal(2, data.length) 63 | assert_instance_of ::CFF::Person, data[0] 64 | assert_instance_of ::CFF::Entity, data[1] 65 | end 66 | 67 | def test_transliterate 68 | [ 69 | ['', '', nil], 70 | [' ', ' ', nil], 71 | ['abcdefg123456789', 'abcdefg123456789', nil], 72 | ['!$%^&*()#~@:;<>,./?|-_+={}[]', '!$%^&*()#~@:;<>,./?|-_+={}[]', nil], 73 | ['"\'\\`', '"\'\\`', nil], 74 | ['£', '', '?'], 75 | ['Å×ßijŋű', 'Axssijngu', nil], 76 | ['Straße', 'Strasse', nil], 77 | ['Bùi Viện', 'Bui Vien', nil], 78 | ['ŠKODA', 'SKODA', nil], 79 | ['áëëçüñżλφθΩ𠜎😸', 'aeecunz', 'aee?cunz??????'], 80 | ['雙屬', '', '??'], 81 | ["\x00\n\x1f\x7f", "\x00\n\x1f\x7f", nil] 82 | ].each do |before, after, fallback| 83 | assert_equal(after, transliterate(before)) 84 | assert_equal( 85 | fallback || after, transliterate(before, fallback: '?') 86 | ) 87 | end 88 | end 89 | 90 | def test_parameterize 91 | [ 92 | ['', ''], 93 | [' ', ''], 94 | ['_', ''], 95 | ['_abcdefg123456789_', 'abcdefg123456789'], 96 | ['!$%^&*()#~@:;<>,./?|+={}[]', ''], 97 | ['"\'\\`', ''], 98 | ['£', ''], 99 | ['Å×ßijŋű', 'Axssijngu'], 100 | ['Straße', 'Strasse'], 101 | ['Bùi Viện', 'Bui_Vien'], 102 | ['ŠKODA', 'SKODA'], 103 | ['áëëçüñżλφθΩ𠜎😸', 'aeecunz'], 104 | ['雙屬', ''], 105 | ["\x00\n\x1f\x7f", ''], 106 | ['3 simple words', '3_simple_words'], 107 | ['3-simple-words', '3-simple-words'] 108 | ].each do |before, after| 109 | assert_equal(after, parameterize(before)) 110 | end 111 | 112 | assert_equal( 113 | 'Bui-Vien', parameterize('Bùi Viện', separator: '-') 114 | ) 115 | assert_equal( 116 | 'Bui-Vien', parameterize('Bùi Viện--', separator: '-') 117 | ) 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /test/validatable_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2018-2022 The Ruby Citation File Format Developers. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require_relative 'test_helper' 18 | 19 | require 'cff/errors' 20 | require 'cff/index' 21 | require 'cff/file' 22 | 23 | class CFFValidatableTest < Minitest::Test 24 | def test_minimal_example_file_validate! 25 | cff = ::CFF::File.read(MINIMAL_CFF) 26 | 27 | assert_raises(::CFF::ValidationError) do 28 | cff.validate! 29 | end 30 | 31 | cff.validate!(fail_on_filename: false) 32 | end 33 | 34 | def test_minimal_example_file_validate 35 | cff = ::CFF::File.read(MINIMAL_CFF) 36 | 37 | result = cff.validate 38 | refute(result[0]) 39 | assert_empty(result[1]) 40 | refute(result[2]) 41 | 42 | result = cff.validate(fail_on_filename: false) 43 | assert(result[0]) 44 | assert_empty(result[1]) 45 | refute(result[2]) 46 | end 47 | 48 | def test_short_example_file_validate! 49 | cff = ::CFF::File.read(SHORT_CFF) 50 | 51 | assert_raises(::CFF::ValidationError) do 52 | cff.validate! 53 | end 54 | 55 | cff.validate!(fail_on_filename: false) 56 | end 57 | 58 | def test_short_example_file_validate 59 | cff = ::CFF::File.read(SHORT_CFF) 60 | 61 | result = cff.validate 62 | refute(result[0]) 63 | assert_empty(result[1]) 64 | refute(result[2]) 65 | 66 | result = cff.validate(fail_on_filename: false) 67 | assert(result[0]) 68 | assert_empty(result[1]) 69 | refute(result[2]) 70 | end 71 | 72 | def test_empty_cff_version_raises_error 73 | cff = ::CFF::File.read(MINIMAL_CFF) 74 | cff.cff_version = '' 75 | assert_raises(::CFF::ValidationError) do 76 | cff.validate!(fail_on_filename: false) 77 | end 78 | end 79 | 80 | def test_nil_cff_version_raises_error 81 | cff = ::CFF::File.read(MINIMAL_CFF) 82 | cff.cff_version = nil 83 | assert_raises(::CFF::ValidationError) do 84 | cff.validate!(fail_on_filename: false) 85 | end 86 | end 87 | 88 | def test_missing_cff_version_raises_error 89 | cff = ::CFF::File.read(NO_CFF_VERSION_CFF) 90 | assert_equal('', cff.cff_version) 91 | assert_raises(::CFF::ValidationError) do 92 | cff.validate!(fail_on_filename: false) 93 | end 94 | end 95 | 96 | def test_incomplete_example_file_raises_error 97 | cff = ::CFF::File.read(INCOMPLETE_CFF) 98 | assert_raises(::CFF::ValidationError) do 99 | cff.validate!(fail_on_filename: false) 100 | end 101 | end 102 | 103 | def test_incomplete_example_file_lists_correct_error 104 | cff = ::CFF::File.read(INCOMPLETE_CFF) 105 | result = cff.validate 106 | 107 | refute(result[0]) 108 | refute_empty(result[1]) 109 | refute(result[2]) 110 | assert_equal(1, result[1].length) 111 | 112 | error = result[1][0] 113 | assert_instance_of(::JsonSchema::ValidationError, error) 114 | assert_equal(:required_failed, error.type) 115 | end 116 | 117 | def test_file_validate 118 | assert_equal([false, [], false], ::CFF::File.validate(MINIMAL_CFF)) 119 | assert_equal( 120 | [true, [], false], 121 | ::CFF::File.validate(MINIMAL_CFF, fail_on_filename: false) 122 | ) 123 | 124 | result = ::CFF::File.validate(NO_CFF_VERSION_CFF) 125 | refute(result[0]) 126 | refute_empty(result[1]) 127 | assert(result[2]) 128 | assert_equal(1, result[1].length) 129 | 130 | error = result[1][0] 131 | assert_instance_of(::JsonSchema::ValidationError, error) 132 | assert_equal(:required_failed, error.type) 133 | end 134 | 135 | def test_file_validate! 136 | error = assert_raises(::CFF::ValidationError) do 137 | ::CFF::File.validate!(MINIMAL_CFF) 138 | end 139 | assert(error.invalid_filename) 140 | 141 | assert_nil(::CFF::File.validate!(MINIMAL_CFF, fail_on_filename: false)) 142 | 143 | # Don't raise error on invalid filename, but it should be detected. 144 | error = assert_raises(::CFF::ValidationError) do 145 | ::CFF::File.validate!(INCOMPLETE_CFF, fail_on_filename: false) 146 | end 147 | assert(error.invalid_filename) 148 | 149 | # Filename is good, but contents are bad. 150 | error = assert_raises(::CFF::ValidationError) do 151 | ::CFF::File.validate!(NO_CFF_VERSION_CFF) 152 | end 153 | refute(error.invalid_filename) 154 | end 155 | 156 | def test_validate_model 157 | cff = ::CFF::Index.new('My software') 158 | 159 | error = assert_raises(::CFF::ValidationError) do 160 | cff.validate! 161 | end 162 | refute(error.invalid_filename) 163 | 164 | cff.authors << ::CFF::Person.new('Robert', 'Haines') 165 | cff.validate! 166 | end 167 | 168 | def test_files_in_validation_directory 169 | Dir[::File.join(VALIDATION_DIR, '*.cff')].each do |input_file| 170 | ::CFF::File.validate!(input_file, fail_on_filename: false) 171 | end 172 | end 173 | 174 | def test_valid_filename_validates 175 | cff = ::CFF::File.read(VALID_FILENAME_CFF) 176 | 177 | cff.validate! 178 | result = cff.validate 179 | assert(result[0]) 180 | assert_empty(result[1]) 181 | assert(result[2]) 182 | end 183 | end 184 | --------------------------------------------------------------------------------