Improve references

This commit is contained in:
Alex Kotov 2024-10-19 00:33:39 +04:00
parent 735d382a53
commit 0d42f3e0bb
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
8 changed files with 222 additions and 32 deletions

View file

@ -1,6 +1,6 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config` # `rubocop --auto-gen-config`
# on 2024-10-18 19:44:25 UTC using RuboCop version 1.67.0. # on 2024-10-18 21:16:41 UTC using RuboCop version 1.67.0.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
@ -32,7 +32,7 @@ Metrics/AbcSize:
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Max: 10 Max: 10
# Offense count: 5 # Offense count: 6
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength: Metrics/MethodLength:
Max: 31 Max: 31

View file

@ -53,12 +53,6 @@ task :console do
File.expand_path(File.join('bin', 'console'), __dir__) File.expand_path(File.join('bin', 'console'), __dir__)
end end
desc 'Run tests'
task :tests do
sh 'bundle', 'exec',
File.expand_path(File.join('tests', 'examples.rb'), __dir__)
end
namespace :yard do namespace :yard do
desc 'Measure documentation coverage' desc 'Measure documentation coverage'
task :cov do task :cov do
@ -68,6 +62,23 @@ namespace :yard do
coverage = m[1].to_f.round(2) coverage = m[1].to_f.round(2)
puts "Documentation coverage: #{coverage}%" puts "Documentation coverage: #{coverage}%"
raise 'Not fully documented!' if coverage < 36 raise 'Not fully documented!' if coverage < 35
end
end
desc 'Run tests in "tests/"'
task tests: %i[tests:examples tests:bibtex]
namespace :tests do
desc 'Run "tests/examples.rb"'
task :examples do
sh 'bundle', 'exec',
File.expand_path(File.join('tests', 'examples.rb'), __dir__)
end
desc 'Run "tests/bibtex.rb"'
task :bibtex do
sh 'bundle', 'exec',
File.expand_path(File.join('tests', 'bibtex.rb'), __dir__)
end end
end end

117
examples/refs/bibtex.bib Normal file
View file

@ -0,0 +1,117 @@
@article{CitekeyArticle,
author = "P. J. Cohen",
title = "The independence of the continuum hypothesis",
journal = "Proceedings of the National Academy of Sciences",
year = 1963,
volume = "50",
number = "6",
pages = "1143--1148",
}
@book{CitekeyBook,
author = "Leonard Susskind and George Hrabovsky",
title = "Classical mechanics: the theoretical minimum",
publisher = "Penguin Random House",
address = "New York, NY",
year = 2014
}
@booklet{CitekeyBooklet,
title = "Canoe tours in {S}weden",
author = "Maria Swetla",
howpublished = "Distributed at the Stockholm Tourist Office",
month = jul,
year = 2015
}
@inbook{CitekeyInbook,
author = "Lisa A. Urry and Michael L. Cain and Steven A. Wasserman and Peter V. Minorsky and Jane B. Reece",
title = "Photosynthesis",
booktitle = "Campbell Biology",
year = "2016",
publisher = "Pearson",
address = "New York, NY",
pages = "187--221"
}
@incollection{CitekeyIncollection,
author = "Shapiro, Howard M.",
editor = "Hawley, Teresa S. and Hawley, Robert G.",
title = "Flow Cytometry: The Glass Is Half Full",
booktitle = "Flow Cytometry Protocols",
year = 2018,
publisher = "Springer",
address = "New York, NY",
pages = "1--10"
}
@inproceedings{CitekeyInproceedings,
author = "Holleis, Paul and Wagner, Matthias and Koolwaaij, Johan",
title = "Studying mobile context-aware social services in the wild",
booktitle = "Proc. of the 6th Nordic Conf. on Human-Computer Interaction",
series = "NordiCHI",
year = 2010,
pages = "207--216",
publisher = "ACM",
address = "New York, NY"
}
@manual{CitekeyManual,
title = "{R}: A Language and Environment for Statistical Computing",
author = "{R Core Team}",
organization = "R Foundation for Statistical Computing",
address = "Vienna, Austria",
year = 2018
}
@mastersthesis{CitekeyMastersthesis,
author = "Jian Tang",
title = "Spin structure of the nucleon in the asymptotic limit",
school = "Massachusetts Institute of Technology",
year = 1996,
address = "Cambridge, MA",
month = sep
}
@misc{CitekeyMisc,
title = "Pluto: The 'Other' Red Planet",
author = "{NASA}",
howpublished = "\url{https://www.nasa.gov/nh/pluto-the-other-red-planet}",
year = 2015,
note = "Accessed: 2018-12-06"
}
@phdthesis{CitekeyPhdthesis,
author = "Rempel, Robert Charles",
title = "Relaxation Effects for Coupled Nuclear Spins",
school = "Stanford University",
address = "Stanford, CA",
year = 1956,
month = jun
}
@proceedings{CitekeyProceedings,
editor = "Susan Stepney and Sergey Verlan",
title = "Proceedings of the 17th International Conference on Computation and Natural Computation, Fontainebleau, France",
series = "Lecture Notes in Computer Science",
volume = "10867",
publisher = "Springer",
address = "Cham, Switzerland",
year = 2018
}
@techreport{CitekeyTechreport,
title = "{W}asatch {S}olar {P}roject Final Report",
author = "Bennett, Vicki and Bowman, Kate and Wright, Sarah",
institution = "Salt Lake City Corporation",
address = "Salt Lake City, UT",
number = "DOE-SLC-6903-1",
year = 2018,
month = sep
}
@unpublished{CitekeyUnpublished,
author = "Mohinder Suresh",
title = "Evolution: a revised theory",
year = 2006
}

View file

@ -9,6 +9,7 @@ require 'uri'
require 'yaml' require 'yaml'
require 'addressable' require 'addressable'
require 'bibtex'
require_relative 'repubmark/highlight' require_relative 'repubmark/highlight'
require_relative 'repubmark/titled_ref' require_relative 'repubmark/titled_ref'
@ -75,10 +76,9 @@ require_relative 'repubmark/elems/footnote'
module Repubmark module Repubmark
FORMATS = %i[chapters gemtext html summary_plain word_count].freeze FORMATS = %i[chapters gemtext html summary_plain word_count].freeze
SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/ SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/
DOI_RE = %r{\A10(\.\d+)+/\w+(\.\w+)*\z} DOI_RE = %r{\A10(\.\d+)+/\w+(\.\w+)*\z}
ISBN_RE = /\A[0-9]{13}\z/ ISBN_RE = /\A[0-9]{13}\z/
NAME_PART_RE = /\A[[:word:]]+(-[[:word:]]+)*( [[:word:]]+(-[[:word:]]+)*)*\z/
UNICODE_SUPS = { UNICODE_SUPS = {
'0' => '⁰', '0' => '⁰',
@ -137,13 +137,6 @@ module Repubmark
isbn isbn
end end
def self.validate_name_part!(name_part)
name_part = String(name_part).freeze
raise 'Invalid name part' unless NAME_PART_RE.match? name_part
name_part
end
def self.validate_text!(str) def self.validate_text!(str)
str = String(str).freeze str = String(str).freeze
raise 'Invalid text' if str.empty? || str != str.strip raise 'Invalid text' if str.empty? || str != str.strip

View file

@ -3,28 +3,49 @@
module Repubmark module Repubmark
module References module References
class Author class Author
attr_reader :family, :given ATTRIBUTES = %i[last first prefix suffix].freeze
attr_reader(*ATTRIBUTES)
def initialize(family, given) def initialize(**kwargs)
self.family = family ATTRIBUTES.each { |attr| send :"#{attr}=", kwargs.delete(attr) }
self.given = given raise 'Unknown kwargs' if kwargs.any?
end
def self.from_bibtex(bibtex_name)
unless bibtex_name.instance_of? BibTeX::Name
raise TypeError, "Expected #{BibTeX::Name}, got #{bibtex_name.class}"
end
new(
last: bibtex_name.last,
first: bibtex_name.first,
prefix: bibtex_name.prefix,
suffix: bibtex_name.suffix,
)
end end
def inspect = "#<#{self.class}: #{self}>".freeze def inspect = "#<#{self.class}: #{self}>".freeze
def to_s = "#{family}, #{given.join(' ')}".freeze def to_s = "#{last}, #{first}".freeze
alias to_str to_s alias to_str to_s
private private
def family=(family) def last=(last)
@family = Repubmark.validate_name_part! family @last = Repubmark.validate_text! last
end end
def given=(given) def first=(first)
@given = @first = Repubmark.validate_text! first if first
Array(given).map { |part| Repubmark.validate_name_part! part }.freeze end
def prefix=(prefix)
@prefix = Repubmark.validate_text! prefix if prefix
end
def suffix=(suffix)
@suffix = Repubmark.validate_text! suffix if suffix
end end
end end
end end

View file

@ -3,11 +3,33 @@
module Repubmark module Repubmark
module References module References
class Item class Item
ATTRIBUTES = %i[slug doi isbn title urls authors].freeze ATTRIBUTES = %i[slug doi isbn title year urls authors].freeze
attr_reader(*ATTRIBUTES) attr_reader(*ATTRIBUTES)
def initialize(**kwargs) def initialize(**kwargs)
ATTRIBUTES.each { |attr| send :"#{attr}=", kwargs[attr] } ATTRIBUTES.each { |attr| send :"#{attr}=", kwargs.delete(attr) }
raise 'Unknown kwargs' if kwargs.any?
end
def self.from_bibtex(slug, bibtex_entry)
unless bibtex_entry.instance_of? BibTeX::Entry
raise TypeError,
"Expected #{BibTeX::Entry}, got #{bibtex_entry.class}"
end
authors = bibtex_entry.authors.map do |author|
Author.from_bibtex author
end
new(
slug:,
doi: bibtex_entry[:doi],
isbn: bibtex_entry[:isbn],
title: bibtex_entry[:title],
year: bibtex_entry[:year],
urls: bibtex_entry[:url],
authors:,
)
end end
def inspect = "#<#{self.class}:#{slug}>".freeze def inspect = "#<#{self.class}:#{slug}>".freeze
@ -30,6 +52,10 @@ module Repubmark
@title = Repubmark.validate_text! title @title = Repubmark.validate_text! title
end end
def year=(year)
@year = Integer year if year
end
def urls=(urls) def urls=(urls)
urls = Array urls urls = Array urls
return @urls = [].freeze if urls.empty? return @urls = [].freeze if urls.empty?

View file

@ -47,5 +47,6 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename f } spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename f }
spec.add_dependency 'addressable', '~> 2.8' spec.add_dependency 'addressable', '~> 2.8'
spec.add_dependency 'bibtex-ruby', '~> 6.1'
spec.add_dependency 'i18n', '~> 1.14' spec.add_dependency 'i18n', '~> 1.14'
end end

21
tests/bibtex.rb Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'repubmark'
bib = BibTeX.parse(
File.expand_path('../examples/refs/bibtex.bib', __dir__),
filter: :latex,
)
Repubmark::References::Item
.from_bibtex('citekey-article', bib[:CitekeyArticle])
.tap do |ref|
p ref
raise unless
ref.title == 'The independence of the continuum hypothesis' &&
ref.year == 1963 &&
ref.authors.size == 1 &&
ref.authors[0].last == 'Cohen' &&
ref.authors[0].first == 'P. J.'
end