asciidoctor-foodogsquared-extensions 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/asciidoctor-foodogsquared-extensions.gemspec +22 -0
- data/lib/asciidoctor/chat-block-processor/README.adoc +115 -0
- data/lib/asciidoctor/chat-block-processor/extension.rb +56 -0
- data/lib/asciidoctor/fdroid-link-inline-macro/README.adoc +36 -0
- data/lib/asciidoctor/fdroid-link-inline-macro/extension.rb +28 -0
- data/lib/asciidoctor/flathub-link-inline-macro/README.adoc +28 -0
- data/lib/asciidoctor/flathub-link-inline-macro/extension.rb +35 -0
- data/lib/asciidoctor/foodogsquared-extensions.rb +56 -0
- data/lib/asciidoctor/git-blob-include-processor/README.adoc +68 -0
- data/lib/asciidoctor/git-blob-include-processor/extension.rb +79 -0
- data/lib/asciidoctor/github-link-inline-macro/README.adoc +49 -0
- data/lib/asciidoctor/github-link-inline-macro/extension.rb +36 -0
- data/lib/asciidoctor/github-raw-content-include-processor/README.adoc +40 -0
- data/lib/asciidoctor/github-raw-content-include-processor/extension.rb +68 -0
- data/lib/asciidoctor/gitlab-link-inline-macro/README.adoc +37 -0
- data/lib/asciidoctor/gitlab-link-inline-macro/extension.rb +31 -0
- data/lib/asciidoctor/gitlab-raw-content-include-processor/README.adoc +44 -0
- data/lib/asciidoctor/gitlab-raw-content-include-processor/extension.rb +66 -0
- data/lib/asciidoctor/helpers.rb +20 -0
- data/lib/asciidoctor/ietf-rfc-link-inline-macro/README.adoc +27 -0
- data/lib/asciidoctor/ietf-rfc-link-inline-macro/extension.rb +16 -0
- data/lib/asciidoctor/man-inline-macro/README.adoc +51 -0
- data/lib/asciidoctor/man-inline-macro/extension.rb +45 -0
- data/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc +45 -0
- data/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb +47 -0
- data/lib/asciidoctor/package-indices-link-macro/extension.rb +56 -0
- data/lib/asciidoctor/repology-link-inline-macro/README.adoc +27 -0
- data/lib/asciidoctor/repology-link-inline-macro/extension.rb +18 -0
- data/lib/asciidoctor/swhid-include-processor/README.adoc +44 -0
- data/lib/asciidoctor/swhid-include-processor/extension.rb +53 -0
- data/lib/asciidoctor/swhid-inline-macro/README.adoc +54 -0
- data/lib/asciidoctor/swhid-inline-macro/extension.rb +26 -0
- data/lib/asciidoctor/wikipedia-inline-macro/README.adoc +30 -0
- data/lib/asciidoctor/wikipedia-inline-macro/extension.rb +21 -0
- data/lib/asciidoctor-foodogsquared-extensions.rb +3 -0
- metadata +109 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
class GitHubRawIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
|
9
|
+
def handles?(target)
|
10
|
+
target.start_with? 'github:'
|
11
|
+
end
|
12
|
+
|
13
|
+
def warn_or_raise(doc, warning)
|
14
|
+
if (doc.safe > Asciidoctor::SafeMode::SERVER) && !(doc.attr? 'allow-uri-read')
|
15
|
+
raise warning
|
16
|
+
else
|
17
|
+
warn warning
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def process(doc, reader, target, attrs)
|
22
|
+
src = target.delete_prefix('github:').split('/', 3)
|
23
|
+
owner = src.at 0
|
24
|
+
repo = src.at 1
|
25
|
+
namespaced_repo = "#{owner}/#{repo}"
|
26
|
+
|
27
|
+
path = attrs['path'] || ''
|
28
|
+
|
29
|
+
# For more information, see https://docs.github.com/en/rest/repos/contents.
|
30
|
+
uri = URI.parse %(https://api.github.com/repos/#{owner}/#{repo}/contents/#{path})
|
31
|
+
|
32
|
+
if attrs['rev']
|
33
|
+
query = { ref: attrs['rev'] }
|
34
|
+
uri.query = URI.encode_www_form query
|
35
|
+
end
|
36
|
+
|
37
|
+
begin
|
38
|
+
headers = {
|
39
|
+
'Header' => 'application/vnd.github+json',
|
40
|
+
'X-GitHub-Api-Version' => '2022-11-28'
|
41
|
+
}
|
42
|
+
|
43
|
+
headers['Authorization'] = "Token #{ENV['GITHUB_API_BEARER_TOKEN']}" if ENV['GITHUB_API_BEARER_TOKEN']
|
44
|
+
|
45
|
+
OpenURI.open_uri(uri, headers) do |f|
|
46
|
+
response = JSON.parse(f.read)
|
47
|
+
|
48
|
+
# If the response is an array, it is likely to be a directory. In this
|
49
|
+
# usecase, we'll just list them.
|
50
|
+
content = if response.is_a? Array
|
51
|
+
warning = %(given path '#{path}' from GitHub repo '#{repo}' is a directory)
|
52
|
+
warn_or_raise doc, warning
|
53
|
+
warning
|
54
|
+
elsif response.is_a? Object
|
55
|
+
Base64.decode64 response['content'] if response['content'] && response['encoding'] == 'base64'
|
56
|
+
end
|
57
|
+
|
58
|
+
reader.push_include content, target, target, 1, attrs
|
59
|
+
end
|
60
|
+
rescue OpenURI::HTTPError => e
|
61
|
+
warning = %(error while getting '#{path}' in GitHub repo '#{namespaced_repo}: #{e}')
|
62
|
+
warn_or_raise doc, warning
|
63
|
+
reader.push_include warning, target, target, 1, attrs
|
64
|
+
end
|
65
|
+
|
66
|
+
reader
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
= GitLab link inline macro
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
An inline macro for easily linking objects from GitLab instances.
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
gitlab:$OWNER/$REPO[$CAPTION]
|
13
|
+
----
|
14
|
+
|
15
|
+
|
16
|
+
== Attributes
|
17
|
+
|
18
|
+
- `domain` is the base domain of the GitLab instance.
|
19
|
+
By default, it points to the official instance of `gitlab.com`.
|
20
|
+
|
21
|
+
- `rev` is the commit of the repo.
|
22
|
+
By default. it doesn't point to anything which should be in the default branch of the repository.
|
23
|
+
|
24
|
+
- `path` is the filepath to be linked.
|
25
|
+
|
26
|
+
There are settings that is enabled with the link:https://docs.asciidoctor.org/asciidoc/latest/attributes/options/[options attribute].
|
27
|
+
|
28
|
+
- `repo` sets the default caption to be the repo part.
|
29
|
+
|
30
|
+
|
31
|
+
== Example usage
|
32
|
+
|
33
|
+
- `gitlab:gitlab-org/gitlab[]` will link to link:https://gitlab.com/gitlab-org/gitlab[the GitLab's source code with the default domain].
|
34
|
+
|
35
|
+
- `gitlab:gitlab-org/gitlab[rev=0c9f77389424b6c5fd8e96b227e9125a13a07cb3, path=README.md]` should link to the link:https://gitlab.com/gitlab-org/gitlab/-/blob/0c9f77389424b6c5fd8e96b227e9125a13a07cb3/README.md[GitLab's README from 3 years ago].
|
36
|
+
|
37
|
+
- `gitlab:GNOME/mutter[domain=gitlab.gnome.org, rev=df653b95adf6462fc731998eb53b0860baa7253c, path=meson.build]` should link to link:https://gitlab.gnome.org/GNOME/mutter/-/blob/df653b95adf6462fc731998eb53b0860baa7253c/meson.build[Mutter v44.beta `meson.build` from GNOME GitLab instance].
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
class GitLabLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
6
|
+
use_dsl
|
7
|
+
|
8
|
+
named :gitlab
|
9
|
+
name_positional_attributes 'caption'
|
10
|
+
default_attributes 'domain' => 'gitlab.com'
|
11
|
+
|
12
|
+
def process(parent, target, attrs)
|
13
|
+
doc = parent.document
|
14
|
+
|
15
|
+
default_caption = if attrs.key?('repo-option')
|
16
|
+
target.split('/').at(1)
|
17
|
+
else
|
18
|
+
target
|
19
|
+
end
|
20
|
+
text = attrs['caption'] || default_caption
|
21
|
+
uri = URI.parse %(https://#{attrs['domain']}/#{target})
|
22
|
+
|
23
|
+
uri.path += %(/-/tree/#{attrs['rev']}) if attrs['rev']
|
24
|
+
uri.path += %(/#{attrs['path']}) if attrs['path']
|
25
|
+
|
26
|
+
target = uri.to_s
|
27
|
+
|
28
|
+
doc.register :links, target
|
29
|
+
create_anchor parent, text, type: :link, target: target
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
= GitLab raw content include processor
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
It's a link:https://docs.asciidoctor.org/asciidoctor/latest/extensions/include-processor/[include processor] for easily including raw content from GitLab repositories.
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
include::gitlab/$OWNER/$REPO[rev=$COMMIT, path=$FILEPATH]
|
13
|
+
----
|
14
|
+
|
15
|
+
|
16
|
+
== Extra notes
|
17
|
+
|
18
|
+
A link:https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-tokens[personal access token] is most likely required.
|
19
|
+
Get one and place the value in an environment variable `GITLAB_API_PERSONAL_ACCESS_TOKEN`.
|
20
|
+
|
21
|
+
|
22
|
+
== Attributes
|
23
|
+
|
24
|
+
There are some attributes required to be passed.
|
25
|
+
|
26
|
+
- `rev` is the commit to be checked out.
|
27
|
+
- `path` is the file path to be included.
|
28
|
+
|
29
|
+
Aside from the required attributes, there are optional attributes to configured further.
|
30
|
+
|
31
|
+
- `domain` is the domain of the GitLab instance.
|
32
|
+
By default, it points to the `gitlab.com` official instance.
|
33
|
+
|
34
|
+
- `version` is the version string of the API to be used.
|
35
|
+
By default, it uses version `v4`.
|
36
|
+
|
37
|
+
|
38
|
+
== Example usage
|
39
|
+
|
40
|
+
- `include::gitlab:gitlab-org/gitlab[rev=master, path=README.md]` should include the README content from the master branch of link:https://gitlab.com/gitlab-org/gitlab/[GitLab source code].
|
41
|
+
|
42
|
+
- `include::freedesktop-sdk/freedesktop-sdk[rev=bcb3e0de957519e87a4c7b8c0e40af9876e531e7, path=.gitlab-ci.yml]` should transclude the GitLab CI configuration from link:https://gitlab.com/freedesktop-sdk/freedesktop-sdk[Freedesktop SDK].
|
43
|
+
|
44
|
+
- `include::World/warp[domain=gitlab.gnome.org, rev=v0.5.2, path=meson_options.txt]` includes `meson_options.txt` from link:https://gitlab.gnome.org/World/warp/[Warp source code] at v0.5.2.
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
class GitLabRawIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
|
9
|
+
def handles?(target)
|
10
|
+
target.start_with? 'gitlab:'
|
11
|
+
end
|
12
|
+
|
13
|
+
def warn_or_raise(doc, warning)
|
14
|
+
if (doc.safe > Asciidoctor::SafeMode::SERVER) && !(doc.attr? 'allow-uri-read')
|
15
|
+
raise warning
|
16
|
+
else
|
17
|
+
warn warning
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def process(doc, reader, target, attrs)
|
22
|
+
src = target.delete_prefix('gitlab:').split('/', 2)
|
23
|
+
owner = src.at 0
|
24
|
+
repo = src.at 1
|
25
|
+
namespaced_repo = "#{owner}/#{repo}"
|
26
|
+
|
27
|
+
raise %(there is no 'path' attribute given for GitLab repo '#{namespaced_repo}') unless attrs.key? 'path'
|
28
|
+
raise %(no given ref for getting file in '#{namespaced_repo}') unless attrs.key? 'rev'
|
29
|
+
|
30
|
+
path = attrs['path']
|
31
|
+
rev = attrs['rev']
|
32
|
+
|
33
|
+
domain = attrs['domain'] || 'gitlab.com'
|
34
|
+
version = attrs['version'] || 'v4'
|
35
|
+
|
36
|
+
uri = URI.parse %(https://#{domain}/api/#{version})
|
37
|
+
|
38
|
+
# Set the project.
|
39
|
+
uri += %(/projects/#{URI.encode_www_form_component namespaced_repo})
|
40
|
+
|
41
|
+
# Then the filename.
|
42
|
+
uri += %(/repository/files/#{URI.encode_www_form_component path})
|
43
|
+
|
44
|
+
# Then the revision.
|
45
|
+
query = { ref: rev }
|
46
|
+
uri.query = URI.encode_www_form query
|
47
|
+
|
48
|
+
content = begin
|
49
|
+
headers = { 'Content-Type' => 'application-json' }
|
50
|
+
header['PRIVATE-TOKEN'] = ENV['GITLAB_API_PERSONAL_ACCESS_TOKEN'] if ENV['GITLAB_API_PERSONAL_ACCESS_TOKEN']
|
51
|
+
|
52
|
+
OpenURI.open_uri(uri, headers) do |f|
|
53
|
+
response = JSON.parse(f.read)
|
54
|
+
|
55
|
+
Base64.decode64 response['content'] if response['content'] && response['encoding'] == 'base64'
|
56
|
+
end
|
57
|
+
rescue OpenURI::HTTPError => e
|
58
|
+
warning = %(error while getting '#{path}' in GitLab repo '#{repo}': #{e})
|
59
|
+
warn_or_raise doc, warning
|
60
|
+
warning
|
61
|
+
end
|
62
|
+
|
63
|
+
reader.push_include content, target, target, 1, attrs
|
64
|
+
reader
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class String
|
4
|
+
def to_kebab
|
5
|
+
self.gsub(/\s+/, '-') # Replace all spaces with dashes.
|
6
|
+
.gsub(/[^a-zA-Z0-9-]/, '') # Remove all non-alphanumerical (and dashes) characters.
|
7
|
+
.gsub(/-+/, '-') # Reduce all dashes into only one.
|
8
|
+
.gsub(/^-|-+$/, '') # Remove all leading and trailing dashes.
|
9
|
+
.downcase
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Asciidoctor
|
14
|
+
module FoodogsquaredCustomExtensions
|
15
|
+
NAME = 'asciidoctor-foodogsquared-custom-extensions'
|
16
|
+
VERSION = '1.0.0'
|
17
|
+
CONTACT_EMAIL = 'foodogsquared@foodogsquared.one'
|
18
|
+
USER_AGENT = "#{NAME}/#{VERSION} ( #{CONTACT_EMAIL} )"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
= Flathub link inline macro
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
A shorthand for linking link:https://datatracker.ietf.org/[IETF RFCs].
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
rfc:$RFC[$CAPTION]
|
13
|
+
----
|
14
|
+
|
15
|
+
Where...
|
16
|
+
|
17
|
+
- `$RFC` is the RFC number.
|
18
|
+
|
19
|
+
- `$CAPTION` is the link text to be used.
|
20
|
+
By default, it will be `RFC$RFC`.
|
21
|
+
|
22
|
+
|
23
|
+
== Example usage
|
24
|
+
|
25
|
+
- `rfc:2136[]` links to the link:https://datatracker.ietf.org/doc/html/rfc2136[RFC2136 (dynamic update)] with the caption `RFC2136`.
|
26
|
+
|
27
|
+
- `rfc:2136[Dynamic DNS updates]` is the same as the previous list item but with the caption text `Dynamic DNS updates`.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class IETFRFCLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
4
|
+
use_dsl
|
5
|
+
|
6
|
+
named :rfc
|
7
|
+
name_positional_attributes 'caption'
|
8
|
+
|
9
|
+
def process(parent, target, attrs)
|
10
|
+
doc = parent.document
|
11
|
+
url = %(https://datatracker.ietf.org/doc/html/#{target})
|
12
|
+
attrs['caption'] ||= "RFC#{target}"
|
13
|
+
doc.register :links, url
|
14
|
+
create_anchor parent, attrs['caption'], type: :link, target: url
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
= Man inline macro
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
It's a link:https://docs.asciidoctor.org/asciidoctorj/latest/extensions/inline-macro-processor/[inline macro] that easily links manual pages from an online manpage service like link:https://manpages.debian.org/[Debian Manpages].
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
man:$MANPAGE[$VOLNUM]
|
13
|
+
----
|
14
|
+
|
15
|
+
|
16
|
+
== Attributes
|
17
|
+
|
18
|
+
There are optional attributes that can be passed.
|
19
|
+
|
20
|
+
- `volnum` expects the section number where the manual page belongs to.
|
21
|
+
This attribute is another way to indicate the section in case you start to use more attributes.
|
22
|
+
The value from `volnum` attribute has higher precedence.
|
23
|
+
When both the positional argument and `volnum` attribute is passed, the `volnum` attribute will be used.
|
24
|
+
|
25
|
+
- `service` is the domain of the online manpage service.
|
26
|
+
Take note this attribute is only used in `html` backend.
|
27
|
+
+
|
28
|
+
--
|
29
|
+
This is an attribute that expects certain values:
|
30
|
+
|
31
|
+
- `debian` uses https://manpages.debian.org.
|
32
|
+
This is also the default service when no value is given.
|
33
|
+
|
34
|
+
- `archlinux` uses https://man.archlinux.org.
|
35
|
+
|
36
|
+
- `opensuse` uses https://manpages.opensuse.org.
|
37
|
+
|
38
|
+
- `voidlinux` use https://man.voidlinux.org.
|
39
|
+
|
40
|
+
- `none` uses none at all. :)
|
41
|
+
This is useful if the reference is not found anywhere.
|
42
|
+
|
43
|
+
Any invalid value raises an error.
|
44
|
+
--
|
45
|
+
|
46
|
+
|
47
|
+
== Example usage
|
48
|
+
|
49
|
+
- `man:crontab[5]` will link to the default manpage service with `crontab(5)` manual page.
|
50
|
+
|
51
|
+
- `man:man[volnum=1, service=archlinux]` will link to the link:https://man.archlinux.org/man/man.1[man manpage] from link:https://man.archlinux.org/[man.archlinux.org].
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ManInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
4
|
+
use_dsl
|
5
|
+
|
6
|
+
named :man
|
7
|
+
name_positional_attributes 'volnum'
|
8
|
+
default_attributes 'service' => 'debian'
|
9
|
+
|
10
|
+
def process(parent, target, attrs)
|
11
|
+
doc = parent.document
|
12
|
+
text = manname = target
|
13
|
+
suffix = (volnum = attrs['volnum']) ? %((#{volnum})) : ''
|
14
|
+
|
15
|
+
if doc.basebackend? 'html'
|
16
|
+
domain = case attrs['service']
|
17
|
+
when 'debian'
|
18
|
+
'https://manpages.debian.org'
|
19
|
+
when 'arch'
|
20
|
+
'https://man.archlinux.org/man'
|
21
|
+
when 'opensuse'
|
22
|
+
'https://manpages.opensuse.org'
|
23
|
+
when 'voidlinux'
|
24
|
+
'https://man.voidlinux.org'
|
25
|
+
when 'none'
|
26
|
+
nil
|
27
|
+
else
|
28
|
+
raise "no available manpage service #{attrs['service']}"
|
29
|
+
end
|
30
|
+
|
31
|
+
if !domain.nil?
|
32
|
+
target = %(#{domain}/#{manname}.#{volnum})
|
33
|
+
doc.register :links, target
|
34
|
+
node = create_anchor parent, text, type: :link, target: target
|
35
|
+
else
|
36
|
+
node = create_inline parent, :quoted, manname
|
37
|
+
end
|
38
|
+
elsif doc.backend == 'manpage'
|
39
|
+
node = create_inline parent, :quoted, manname, type: :strong
|
40
|
+
else
|
41
|
+
node = create_inline parent, :quoted, manname
|
42
|
+
end
|
43
|
+
create_inline parent, :quoted, %(#{node.convert}#{suffix})
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
= Musicbrainz link inline macro
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
An inline macro for easily linking objects from link:https://musicbrainz.org/doc/MusicBrainz_Database[Musicbrainz database].
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
musicbrainz:$ID[$CAPTION, $TYPE]
|
13
|
+
----
|
14
|
+
|
15
|
+
- `$ID` is the database identifier for that object (e.g., `9adcff14-7dba-4ccf-a6a6-298bcde3dd46`).
|
16
|
+
|
17
|
+
- `$CAPTION` is the link text.
|
18
|
+
By default, it will be the name of the database object (if valid).
|
19
|
+
Take note it will use the MusicBrainz API to query the title/name of the object.
|
20
|
+
In other words, it costs an additional network request.
|
21
|
+
|
22
|
+
- `$TYPE` is the database object type.
|
23
|
+
It defaults to 'Release' object type.
|
24
|
+
|
25
|
+
|
26
|
+
== Attributes
|
27
|
+
|
28
|
+
The macro can also accept some attributes.
|
29
|
+
|
30
|
+
- `caption` is the link text to be used.
|
31
|
+
This can be used instead of the first positional attribute.
|
32
|
+
|
33
|
+
- `type` is the database object type to be queried.
|
34
|
+
This can be used instead of the second positional attribute.
|
35
|
+
|
36
|
+
|
37
|
+
== Example usage
|
38
|
+
|
39
|
+
- `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.
|
40
|
+
|
41
|
+
- `musicbrainz:9adcff14-7dba-4ccf-a6a6-298bcde3dd46[Ridiculon's Rebirth soundtrack]` same as above but with the link text replaced with 'Ridiculon's Rebirth Soundtrack'.
|
42
|
+
|
43
|
+
- `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.
|
44
|
+
|
45
|
+
- `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.
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
class MusicBrainzLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
8
|
+
use_dsl
|
9
|
+
|
10
|
+
named :musicbrainz
|
11
|
+
name_positional_attributes 'caption', 'type'
|
12
|
+
default_attributes 'type' => 'release'
|
13
|
+
|
14
|
+
def process(parent, target, attrs)
|
15
|
+
doc = parent.document
|
16
|
+
root_endpoint = 'https://musicbrainz.org/ws/2'
|
17
|
+
|
18
|
+
begin
|
19
|
+
headers = {
|
20
|
+
'Accept' => 'application/json',
|
21
|
+
'User-Agent' => ::Asciidoctor::FoodogsquaredCustomExtensions::USER_AGENT
|
22
|
+
}
|
23
|
+
|
24
|
+
uri = %(#{root_endpoint}/#{attrs['type']}/#{target})
|
25
|
+
|
26
|
+
if attrs['caption'].nil?
|
27
|
+
metadata = OpenURI.open_uri(uri, headers) { |f| JSON.parse(f.read) }
|
28
|
+
attrs['caption'] ||= case attrs['type']
|
29
|
+
when 'artist', 'area', 'events', 'genre', 'instrument', 'label', 'place', 'series'
|
30
|
+
metadata['name']
|
31
|
+
when 'recording', 'release-group', 'release', 'cdstub', 'work'
|
32
|
+
metadata['title']
|
33
|
+
when 'url'
|
34
|
+
metadata['resource']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
target = %(https://musicbrainz.org/#{attrs['type']}/#{target})
|
39
|
+
doc.register :links, target
|
40
|
+
create_anchor parent, attrs['caption'], type: :link, target: target
|
41
|
+
rescue
|
42
|
+
warning = %(error while getting Musicbrainz database object '#{target}: #{e}')
|
43
|
+
warn_or_raise doc, warning
|
44
|
+
reader.push_include warning, target, target, 1, attrs
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# I'm fairly sure this could be programmed since Ruby has nice metaprogramming
|
4
|
+
# capabilities. Though, we'll be keeping it manually defining classes for now
|
5
|
+
# for initial versions since there could be additional features for each macro.
|
6
|
+
|
7
|
+
class CtanLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
8
|
+
use_dsl
|
9
|
+
|
10
|
+
named :ctan
|
11
|
+
name_positional_attributes 'caption'
|
12
|
+
|
13
|
+
def process(parent, target, attrs)
|
14
|
+
doc = parent.document
|
15
|
+
text = attrs['caption'] || target
|
16
|
+
url = %(https://ctan.org/pkg/#{target})
|
17
|
+
|
18
|
+
doc.register :links, url
|
19
|
+
|
20
|
+
create_anchor parent, text, type: :link, target: url
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class PypiLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
25
|
+
use_dsl
|
26
|
+
|
27
|
+
named :pypi
|
28
|
+
name_positional_attributes 'caption'
|
29
|
+
|
30
|
+
def process(parent, target, attrs)
|
31
|
+
doc = parent.document
|
32
|
+
text = attrs['caption'] || target
|
33
|
+
url = %(https://pypi.org/project/#{target})
|
34
|
+
|
35
|
+
doc.register :links, url
|
36
|
+
|
37
|
+
create_anchor parent, text, type: :link, target: url
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class CratesIOLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
42
|
+
use_dsl
|
43
|
+
|
44
|
+
named :cratesio
|
45
|
+
name_positional_attributes 'caption'
|
46
|
+
|
47
|
+
def process(parent, target, attrs)
|
48
|
+
doc = parent.document
|
49
|
+
text = attrs['caption'] || target
|
50
|
+
url = %(https://crates.io/crates/#{target})
|
51
|
+
|
52
|
+
doc.register :links, url
|
53
|
+
|
54
|
+
create_anchor parent, text, type: :link, target: url
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
= Repology link inline macro
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
An inline macro for shorthands Repology links.
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
repology:$PROJECT[$CAPTION]
|
13
|
+
----
|
14
|
+
|
15
|
+
Where...
|
16
|
+
|
17
|
+
- `$PROJECT` is the project name listed in link:https://repology.org/projects/[Repology's project list].
|
18
|
+
|
19
|
+
- `$CAPTION` is the link text to be used.
|
20
|
+
By default, it will use the project name.
|
21
|
+
|
22
|
+
|
23
|
+
== Example usage
|
24
|
+
|
25
|
+
- `repology:beets[]` should link to the link:https://repology.org/project/beets/[Beets project page in Repology] with `beets` as the link text.
|
26
|
+
|
27
|
+
- `repology:beets[widely available in Linux distributions]` is the same as the previous item but with the link text replaced to `widely available in Linux distributions`.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RepologyLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
4
|
+
use_dsl
|
5
|
+
|
6
|
+
named :repology
|
7
|
+
name_positional_attributes 'caption'
|
8
|
+
|
9
|
+
def process(parent, target, attrs)
|
10
|
+
doc = parent.document
|
11
|
+
text = attrs['caption'] || target
|
12
|
+
url = %(https://repology.org/project/#{target})
|
13
|
+
|
14
|
+
doc.register :links, url
|
15
|
+
|
16
|
+
create_anchor parent, text, type: :link, target: url
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
= SWHID include processor
|
2
|
+
:toc:
|
3
|
+
|
4
|
+
|
5
|
+
This is an include processor extension for easily fetching SWHIDs, only with the `cnt` schema type.
|
6
|
+
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
|
10
|
+
[source, asciidoc]
|
11
|
+
----
|
12
|
+
\include::$SWHID[]
|
13
|
+
----
|
14
|
+
|
15
|
+
Where `$SWHID` is a link:https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html[SWHID].
|
16
|
+
This could accept SWHIDs with qualifiers.
|
17
|
+
|
18
|
+
Take note this include processor will only give the raw content with the `cnt` schema type.
|
19
|
+
Anything else will be skipped and log a warning instead.
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
== Extra notes
|
24
|
+
|
25
|
+
[source, asciidoc]
|
26
|
+
----
|
27
|
+
= doctitle
|
28
|
+
:swhid-gpl3: swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2
|
29
|
+
|
30
|
+
\include::{swhid-nixpkgs}[]
|
31
|
+
----
|
32
|
+
|
33
|
+
This include processor also respects the safe mode setting.
|
34
|
+
This means in order to permit including by SWHID, you have to permit link:https://docs.asciidoctor.org/asciidoc/latest/directives/include-uri/[includes by URIs].
|
35
|
+
|
36
|
+
Lastly, this include processor uses the Software Heritage API which includes a limitation.
|
37
|
+
You could create authorized requests by setting `SWH_API_BEARER_TOKEN` environment variable with a token.
|
38
|
+
|
39
|
+
|
40
|
+
== Example usage
|
41
|
+
|
42
|
+
- SWHID with a bare core identifier: `include::swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2[]`.
|
43
|
+
|
44
|
+
- SWHID with full contextual information: `include::swh:1:cnt:4c6ad635164b25b9bc2ebe17d2c3b7c0835f6035;origin=https://github.com/NixOS/nixpkgs;visit=swh:1:snp:6ea7d28dfd4789609e0be2b64179fc9c12931beb;anchor=swh:1:rev:7f5639fa3b68054ca0b062866dc62b22c3f11505;path=/README.md`.
|