From 05c85ff63f01c96dfc5648a1e1ae194654c8eb49 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Sat, 27 May 2023 16:24:10 +0800 Subject: [PATCH] Add MusicBrainz link inline macro --- .../asciidoctor/foodogsquared-extensions.rb | 3 ++ .../musicbrainz-link-inline-macro/README.adoc | 45 +++++++++++++++++ .../extension.rb | 48 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc create mode 100644 gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb diff --git a/gems/lib/asciidoctor/foodogsquared-extensions.rb b/gems/lib/asciidoctor/foodogsquared-extensions.rb index f689658..788339c 100644 --- a/gems/lib/asciidoctor/foodogsquared-extensions.rb +++ b/gems/lib/asciidoctor/foodogsquared-extensions.rb @@ -17,6 +17,7 @@ require_relative 'git-blob-include-processor/extension' require_relative 'wikipedia-inline-macro/extension' require_relative 'package-indices-link-macro/extension' require_relative 'fdroid-link-inline-macro/extension' +require_relative 'musicbrainz-link-inline-macro/extension' Asciidoctor::Extensions.register do inline_macro ManInlineMacro @@ -40,4 +41,6 @@ Asciidoctor::Extensions.register do inline_macro PypiLinkInlineMacro inline_macro CratesIOLinkInlineMacro inline_macro FDroidLinkInlineMacro + + inline_macro MusicBrainzLinkInlineMacro end diff --git a/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc new file mode 100644 index 0000000..266d83d --- /dev/null +++ b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc @@ -0,0 +1,45 @@ += Musicbrainz link inline macro +:toc: + + +An inline macro for easily linking objects from link:https://musicbrainz.org/doc/MusicBrainz_Database[Musicbrainz database]. + + +== Synopsis + +[source, asciidoc] +---- +musicbrainz:$ID[$CAPTION, $TYPE] +---- + +- `$ID` is the database identifier for that object (e.g., `9adcff14-7dba-4ccf-a6a6-298bcde3dd46`). + +- `$CAPTION` is the link text. +By default, it will be the name of the database object (if valid). +Take note it will use the MusicBrainz API to query the title/name of the object. +In other words, it costs an additional network request. + +- `$TYPE` is the database object type. +It defaults to 'Release' object type. + + +== Attributes + +The macro can also accept some attributes. + +- `caption` is the link text to be used. +This can be used instead of the first positional attribute. + +- `type` is the database object type to be queried. +This can be used instead of the second positional attribute. + + +== Example usage + +- `musicbrainz:9adcff14-7dba-4ccf-a6a6-298bcde3dd46[]` should have a link to the link:https://musicbrainz.org/release/9adcff14-7dba-4ccf-a6a6-298bcde3dd46[Musicbrainz page for The Bindings of Isaac Rebirth] with 'The Bindings of Isaac: Rebirth' as the link caption. + +- `musicbrainz:9adcff14-7dba-4ccf-a6a6-298bcde3dd46[Ridiculon's Rebirth soundtrack]` same as above but with the link text replaced with 'Ridiculon's Rebirth Soundtrack'. + +- `musicbrainz:b7c7f603-4c42-45a4-b364-3ddba82da412[type=release-group]` links to the link:https://musicbrainz.org/release-group/b7c7f603-4c42-45a4-b364-3ddba82da412[Musicbrainz page for The Bindings of Isaac Rebirth release group] with 'The Bindings of Isaac: Rebirth' as the link text. + +- `musicbrainz:f07c6afe-ee84-4cd5-9b11-5c541d1dff3b[type=artist]` links to link:https://musicbrainz.org/artist/f07c6afe-ee84-4cd5-9b11-5c541d1dff3b[Musicbrainz page for Ridiculon] with their name as the caption. diff --git a/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb new file mode 100644 index 0000000..5b1ad06 --- /dev/null +++ b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'json' +require 'open-uri' +require 'open-uri/cached' +require 'uri' + +class MusicBrainzLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor + use_dsl + + named :musicbrainz + name_positional_attributes 'caption', 'type' + default_attributes 'type' => 'release' + + def process(parent, target, attrs) + doc = parent.document + root_endpoint = 'https://musicbrainz.org/ws/2' + + begin + headers = { + 'Accept' => 'application/json', + 'User-Agent' => ::Asciidoctor::FoodogsquaredCustomExtensions::USER_AGENT + } + + uri = %(#{root_endpoint}/#{attrs['type']}/#{target}) + + if attrs['caption'].nil? + metadata = OpenURI.open_uri(uri, headers) { |f| JSON.parse(f.read) } + attrs['caption'] ||= case attrs['type'] + when 'artist', 'area', 'events', 'genre', 'instrument', 'label', 'place', 'series' + metadata['name'] + when 'recording', 'release-group', 'release', 'cdstub', 'work' + metadata['title'] + when 'url' + metadata['resource'] + end + end + + target = %(https://musicbrainz.org/#{attrs['type']}/#{target}) + doc.register :links, target + create_anchor parent, attrs['caption'], type: :link, target: target + rescue + warning = %(error while getting Musicbrainz database object '#{target}: #{e}') + warn_or_raise doc, warning + reader.push_include warning, target, target, 1, attrs + end + end +end