asciidoctor-foodogsquared-extensions 1.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +21 -0
  3. data/asciidoctor-foodogsquared-extensions.gemspec +1 -1
  4. data/lib/asciidoctor/foodogsquared/converter.rb +31 -0
  5. data/lib/asciidoctor/foodogsquared/extensions/chat-block.rb +26 -0
  6. data/lib/asciidoctor/foodogsquared/extensions/fdroid-inline-macro.rb +28 -0
  7. data/lib/asciidoctor/foodogsquared/extensions/flathub-inline-macro.rb +35 -0
  8. data/lib/asciidoctor/foodogsquared/extensions/git-blob-include-processor.rb +68 -0
  9. data/lib/asciidoctor/foodogsquared/extensions/github-include-processor.rb +70 -0
  10. data/lib/asciidoctor/foodogsquared/extensions/github-inline-macro.rb +38 -0
  11. data/lib/asciidoctor/foodogsquared/extensions/gitlab-include-processor.rb +60 -0
  12. data/lib/asciidoctor/foodogsquared/extensions/gitlab-inline-macro.rb +39 -0
  13. data/lib/asciidoctor/foodogsquared/extensions/ietf-rfc-inline-macro.rb +18 -0
  14. data/lib/asciidoctor/foodogsquared/extensions/man-inline-macro.rb +54 -0
  15. data/lib/asciidoctor/foodogsquared/extensions/musicbrainz-inline-macro.rb +47 -0
  16. data/lib/asciidoctor/foodogsquared/extensions/package-indices-macro.rb +58 -0
  17. data/lib/asciidoctor/foodogsquared/extensions/repology-inline-macro.rb +20 -0
  18. data/lib/asciidoctor/foodogsquared/extensions/swhid-include-processor.rb +55 -0
  19. data/lib/asciidoctor/foodogsquared/extensions/swhid-inline-macro.rb +28 -0
  20. data/lib/asciidoctor/foodogsquared/extensions/wikipedia-inline-macro.rb +23 -0
  21. data/lib/asciidoctor/foodogsquared/extensions.rb +56 -0
  22. data/lib/asciidoctor/foodogsquared/helpers.rb +26 -0
  23. data/lib/asciidoctor-foodogsquared-extensions.rb +2 -1
  24. metadata +21 -36
  25. data/lib/asciidoctor/chat-block-processor/README.adoc +0 -115
  26. data/lib/asciidoctor/chat-block-processor/extension.rb +0 -61
  27. data/lib/asciidoctor/fdroid-link-inline-macro/README.adoc +0 -36
  28. data/lib/asciidoctor/fdroid-link-inline-macro/extension.rb +0 -26
  29. data/lib/asciidoctor/flathub-link-inline-macro/README.adoc +0 -28
  30. data/lib/asciidoctor/flathub-link-inline-macro/extension.rb +0 -33
  31. data/lib/asciidoctor/foodogsquared-extensions.rb +0 -55
  32. data/lib/asciidoctor/git-blob-include-processor/README.adoc +0 -57
  33. data/lib/asciidoctor/git-blob-include-processor/extension.rb +0 -66
  34. data/lib/asciidoctor/github-link-inline-macro/README.adoc +0 -49
  35. data/lib/asciidoctor/github-link-inline-macro/extension.rb +0 -36
  36. data/lib/asciidoctor/github-raw-content-include-processor/README.adoc +0 -40
  37. data/lib/asciidoctor/github-raw-content-include-processor/extension.rb +0 -68
  38. data/lib/asciidoctor/gitlab-link-inline-macro/README.adoc +0 -40
  39. data/lib/asciidoctor/gitlab-link-inline-macro/extension.rb +0 -37
  40. data/lib/asciidoctor/gitlab-raw-content-include-processor/README.adoc +0 -44
  41. data/lib/asciidoctor/gitlab-raw-content-include-processor/extension.rb +0 -66
  42. data/lib/asciidoctor/helpers.rb +0 -20
  43. data/lib/asciidoctor/ietf-rfc-link-inline-macro/README.adoc +0 -27
  44. data/lib/asciidoctor/ietf-rfc-link-inline-macro/extension.rb +0 -16
  45. data/lib/asciidoctor/man-inline-macro/README.adoc +0 -51
  46. data/lib/asciidoctor/man-inline-macro/extension.rb +0 -50
  47. data/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc +0 -45
  48. data/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb +0 -45
  49. data/lib/asciidoctor/package-indices-link-macro/extension.rb +0 -56
  50. data/lib/asciidoctor/repology-link-inline-macro/README.adoc +0 -27
  51. data/lib/asciidoctor/repology-link-inline-macro/extension.rb +0 -18
  52. data/lib/asciidoctor/spdx-link-inline-macro/README.adoc +0 -26
  53. data/lib/asciidoctor/swhid-include-processor/README.adoc +0 -44
  54. data/lib/asciidoctor/swhid-include-processor/extension.rb +0 -53
  55. data/lib/asciidoctor/swhid-inline-macro/README.adoc +0 -54
  56. data/lib/asciidoctor/swhid-inline-macro/extension.rb +0 -26
  57. data/lib/asciidoctor/wikipedia-inline-macro/README.adoc +0 -30
  58. data/lib/asciidoctor/wikipedia-inline-macro/extension.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 903ca29ce450d3aad60571b57c851fbfcf11524f9fcda8ae3ba388e9c619fdf0
4
- data.tar.gz: 405bfafa852a1bc66ebf46c1242bee986cc949c78289d699c987dacda17feac0
3
+ metadata.gz: 49db0995b8f1dd14e46463b687e10114fd1a86498b47f61bd3c9b6a17cb32651
4
+ data.tar.gz: 286296368f012d16bf94dd66e2f1847866fc2c67d948179eb8e45d550da90e14
5
5
  SHA512:
6
- metadata.gz: 63bc0807247b017729d2b4177796a32ffa34635fb373020552028827ff3b4cfdcea22c958e1abeb084f2c6f6d3e44a5bd154b6e5c479af94425e86c69aeed067
7
- data.tar.gz: bed6effd30c18654a20582ddb383c249ed6f6ddf83ee751c10e4f1f01c98ab0551b7e3fcb095997893a16bf6bfa05e91f28d37986923c59b7fb6190882c5997f
6
+ metadata.gz: b5f9b29ae1e1c10a4642e8470610db3c37bdde4af49a230b0a7a77299c651436ae58c3b70b425f203b080bb9acc17637b1d02e0acab511de0d32f52322030689
7
+ data.tar.gz: 4cdb81ddbb0490e6082257044e64b732b962ca1169bc56f66cccbbbca1cd40b41cb6eaa84a40d95909a6de94b6d6389bcfab9fe1b957f0fb245ed8a043ddd9ad
data/CHANGELOG.adoc CHANGED
@@ -6,6 +6,27 @@
6
6
 
7
7
 
8
8
  The guidelines for writing this changelog is based from link:https://common-changelog.org[Common Changelog].
9
+ Although, this project doesn't follow the Semantic Versioning convention.
10
+ Versioning mostly happens on a whim.
11
+
12
+
13
+ == [1.2.0] - 2023-11-08
14
+
15
+ === Added
16
+
17
+ * Add `subpath` option for man inline macro.
18
+ This enables making links to other versions of the online manpage service such as in Debian (i.e., `man:ls[1, subpath=/bookworm]`) ({commit-url}/69c8015292ceb9fab03250109b2c5009605a9a8f[`69c8015`]) (Gabriel Arazas)
19
+
20
+ * Create an extended converter for HTML5.
21
+ This is to handle new blocks with context such as the revamped chat block. ({commit-url}/6291f3b36d44c271a66a5ad88906cb707e291b3d[`6291f3b`])
22
+
23
+ === Updated
24
+
25
+ * Restructure the modules.
26
+ There should be no difference in using unless you're using the Asciidoctor API which makes it a complete breaking change. footnote:[So far, no one is aware this extension exists so it shouldn't be. If no user uses the project, is it really a breaking change? :)] ({commit-url}/95e7bc12ecd1e573c94b1322ef1b03dec17e8c70[`95e7bc1`]) (Gabriel Arazas)
27
+
28
+ * Update the chat block to have its own context.
29
+ This makes it configurable with a template. ({commit-url}/6291f3b36d44c271a66a5ad88906cb707e291b3d[`6291f3b`]) (Gabriel Arazas)
9
30
 
10
31
 
11
32
  == [1.1.0] - 2023-11-01
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'asciidoctor-foodogsquared-extensions'
3
- s.version = '1.1.0'
3
+ s.version = '1.2.1'
4
4
  s.licenses = ['MIT']
5
5
  s.summary = "foo-dogsquared's custom Asciidoctor extensions"
6
6
  s.description = <<-DESC
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # foodogsquared's custom converter that is an extended version of the built-in
4
+ # HTML5 converter. It features custom blocks as well as their preferred output
5
+ # for certain blocks.
6
+ module Asciidoctor::Foodogsquared::Converter
7
+ class Html5Custom < (Asciidoctor::Converter.for 'html5')
8
+ register_for 'html5'
9
+
10
+ def convert_chat(node)
11
+ attributes = []
12
+ attributes << %(id="#{node.id}") if node.id
13
+ attributes << %(class="#{node.role}") if node.role
14
+
15
+ avatar_sticker = node.attributes['avatarsticker']
16
+ avatar_uri = node.parent.image_uri avatar_sticker, 'avatarsdir'
17
+
18
+ <<~HTML
19
+ <div role="figure" #{attributes.join ' '}>
20
+ <div class="dialogblock-avatar">
21
+ <img src="#{avatar_uri}" alt="#{node.attributes['name']}">
22
+ </div>
23
+ <div class="dialogblock-text">
24
+ <small>#{node.attributes['name']}</small>
25
+ #{node.content}
26
+ </div>
27
+ </div>
28
+ HTML
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Foodogsquared::Extensions
4
+ class ChatBlock < Asciidoctor::Extensions::BlockProcessor
5
+ use_dsl
6
+
7
+ named :chat
8
+ on_context :example
9
+ name_positional_attributes 'avatar', 'state'
10
+ default_attributes 'state' => 'default'
11
+
12
+ def process(parent, reader, attrs)
13
+ attrs['name'] ||= attrs['avatar']
14
+
15
+ # Configuring the avatar-related attributes.
16
+ attrs['avatarsdir'] ||= File.expand_path('./avatars', attrs['iconsdir'])
17
+ attrs['avatarstype'] ||= parent.attributes['avatarstype'] || 'avif'
18
+ attrs['avatarsticker'] = "#{attrs['avatar'].to_kebab}/#{attrs['state'].to_kebab}.#{attrs['avatarstype']}"
19
+
20
+ block = create_block parent, :chat, nil, attrs, content_model: :compound
21
+ block.add_role 'dialogblock'
22
+
23
+ block
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open-uri'
4
+ require 'yaml'
5
+
6
+ module Asciidoctor::Foodogsquared::Extensions
7
+ class FDroidInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
8
+ use_dsl
9
+
10
+ named :fdroid
11
+ name_positional_attributes 'caption'
12
+ default_attributes 'lang' => 'en'
13
+
14
+ def process(parent, target, attrs)
15
+ doc = parent.document
16
+
17
+ app_id = target
18
+ app_metadata_uri = %(https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/#{app_id}.yml)
19
+
20
+ metadata = OpenURI.open_uri(app_metadata_uri) { |f| YAML.safe_load(f.read) }
21
+ attrs['caption'] ||= metadata['AutoName']
22
+
23
+ url = %(https://f-droid.org/#{attrs['lang']}/packages/#{app_id})
24
+ doc.register :links, url
25
+ create_anchor parent, attrs['caption'], type: :link, target: url
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'open-uri'
5
+
6
+ module Asciidoctor::Foodogsquared::Extensions
7
+ class FlathubInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
8
+ use_dsl
9
+
10
+ named :flathub
11
+ name_positional_attributes 'caption'
12
+
13
+ def process(parent, target, attrs)
14
+ doc = parent.document
15
+
16
+ # FlatHub API seems to have no documentation aside from the source code.
17
+ # You can easily infer the API with its source code at
18
+ # https://github.com/flathub/website.
19
+ app_id = target
20
+ app_metadata_uri = %(https://flathub.org/api/v2/appstream/#{app_id})
21
+
22
+ headers = {
23
+ 'Accept' => 'application/json',
24
+ 'User-Agent' => ::Asciidoctor::Foodogsquared::USER_AGENT
25
+ }
26
+
27
+ metadata = OpenURI.open_uri(app_metadata_uri, headers) { |f| JSON.parse(f.read) }
28
+ attrs['caption'] ||= metadata['name']
29
+
30
+ url = %(https://flathub.org/apps/#{app_id})
31
+ doc.register :links, url
32
+ create_anchor parent, attrs['caption'], type: :link, target: url
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rugged'
4
+
5
+ module Asciidoctor::Foodogsquared::Extensions
6
+ class GitBlobIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
7
+ def handles?(target)
8
+ target.start_with? 'git:'
9
+ end
10
+
11
+ def process(doc, reader, target, attrs)
12
+ attrs['gitrepo'] ||= doc.attributes['gitrepo'] || doc.base_dir
13
+ repo = Rugged::Repository.discover(attrs['gitrepo'])
14
+
15
+ git_object_ref = target.delete_prefix 'git:'
16
+ git_object_ref = doc.attributes['doccontentref'] if git_object_ref.empty?
17
+
18
+ begin
19
+ git_object = repo.rev_parse git_object_ref
20
+
21
+ if attrs.key? 'diff-option'
22
+ options = {}
23
+
24
+ options[:paths] = attrs['path'].split(';') if attrs.key? 'path'
25
+ options[:context_lines] = attrs['context-lines'] if attrs.key? 'context-lines'
26
+ options[:reverse] = true if attrs.key? 'reverse-option'
27
+
28
+ if attrs.key? 'other'
29
+ other = repo.rev_parse attrs['other'] || nil
30
+ reader.push_include git_object.diff(other, **options).patch
31
+ else
32
+ reader.push_include git_object.diff(**options).patch
33
+ end
34
+ else
35
+ inner_entry = case git_object.type
36
+ when :blob
37
+ git_object
38
+ when :commit
39
+ git_object.tree.path attrs['path']
40
+ when :tree
41
+ git_object.path attrs['path']
42
+ when :tag
43
+ git_object.target.tree.path attrs['path']
44
+ end
45
+
46
+ content = repo.lookup(inner_entry[:oid]).content
47
+
48
+ if attrs.key? 'lines'
49
+ content_lines = content.lines
50
+ new_content = +''
51
+ doc.resolve_lines_to_highlight(content, attrs['lines']).each do |line_no|
52
+ new_content << content_lines.at(line_no - 1)
53
+ end
54
+
55
+ content = new_content
56
+ end
57
+
58
+ reader.push_include content
59
+ end
60
+ rescue StandardError => e
61
+ reader.push_include "Unresolved directive for '#{target}' with the following error:\n#{e}"
62
+ warn e
63
+ end
64
+
65
+ reader
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'json'
5
+ require 'open-uri'
6
+ require 'uri'
7
+
8
+ module Asciidoctor::Foodogsquared::Extensions
9
+ class GitHubIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
10
+ def handles?(target)
11
+ target.start_with? 'github:'
12
+ end
13
+
14
+ def warn_or_raise(doc, warning)
15
+ if (doc.safe > Asciidoctor::SafeMode::SERVER) && !(doc.attr? 'allow-uri-read')
16
+ raise warning
17
+ else
18
+ warn warning
19
+ end
20
+ end
21
+
22
+ def process(doc, reader, target, attrs)
23
+ src = target.delete_prefix('github:').split('/', 3)
24
+ owner = src.at 0
25
+ repo = src.at 1
26
+ namespaced_repo = "#{owner}/#{repo}"
27
+
28
+ path = attrs['path'] || ''
29
+
30
+ # For more information, see https://docs.github.com/en/rest/repos/contents.
31
+ uri = URI.parse %(https://api.github.com/repos/#{owner}/#{repo}/contents/#{path})
32
+
33
+ if attrs['rev']
34
+ query = { ref: attrs['rev'] }
35
+ uri.query = URI.encode_www_form query
36
+ end
37
+
38
+ begin
39
+ headers = {
40
+ 'Header' => 'application/vnd.github+json',
41
+ 'X-GitHub-Api-Version' => '2022-11-28'
42
+ }
43
+
44
+ headers['Authorization'] = "Token #{ENV['GITHUB_API_BEARER_TOKEN']}" if ENV['GITHUB_API_BEARER_TOKEN']
45
+
46
+ OpenURI.open_uri(uri, headers) do |f|
47
+ response = JSON.parse(f.read)
48
+
49
+ # If the response is an array, it is likely to be a directory. In this
50
+ # usecase, we'll just list them.
51
+ content = if response.is_a? Array
52
+ warning = %(given path '#{path}' from GitHub repo '#{repo}' is a directory)
53
+ warn_or_raise doc, warning
54
+ warning
55
+ elsif response.is_a? Object
56
+ Base64.decode64 response['content'] if response['content'] && response['encoding'] == 'base64'
57
+ end
58
+
59
+ reader.push_include content, target, target, 1, attrs
60
+ end
61
+ rescue OpenURI::HTTPError => e
62
+ warning = %(error while getting '#{path}' in GitHub repo '#{namespaced_repo}: #{e}')
63
+ warn_or_raise doc, warning
64
+ reader.push_include warning, target, target, 1, attrs
65
+ end
66
+
67
+ reader
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module Asciidoctor::Foodogsquared::Extensions
6
+ class GitHubInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
7
+ use_dsl
8
+
9
+ named :github
10
+ name_positional_attributes 'caption'
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://github.com/#{target})
22
+
23
+ if attrs.key? 'issue'
24
+ uri.path += %(/issues/#{attrs['issue']})
25
+ text << "##{attrs['issue']}" if text == target
26
+ else
27
+ uri.path += %(/tree/#{attrs['rev']}) if attrs.key? 'rev'
28
+ uri.path += %(/#{attrs['path']}) if attrs.key? 'path'
29
+ text << "@#{attrs['rev']}" if attrs.key?('rev') && text == target
30
+ end
31
+
32
+ target = uri.to_s
33
+
34
+ doc.register :links, target
35
+ create_anchor parent, text, type: :link, target: target
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'json'
5
+ require 'open-uri'
6
+ require 'uri'
7
+
8
+ module Asciidoctor::Foodogsquared::Extensions
9
+ class GitLabIncludeProcessor < Asciidoctor::Extensions::IncludeProcessor
10
+ def handles?(target)
11
+ target.start_with? 'gitlab:'
12
+ end
13
+
14
+ def process(doc, reader, target, attrs)
15
+ src = target.delete_prefix('gitlab:').split('/', 2)
16
+ owner = src.at 0
17
+ repo = src.at 1
18
+ namespaced_repo = "#{owner}/#{repo}"
19
+
20
+ raise %(there is no 'path' attribute given for GitLab repo '#{namespaced_repo}') unless attrs.key? 'path'
21
+ raise %(no given ref for getting file in '#{namespaced_repo}') unless attrs.key? 'rev'
22
+
23
+ path = attrs['path']
24
+ rev = attrs['rev']
25
+
26
+ domain = attrs['domain'] || 'gitlab.com'
27
+ version = attrs['version'] || 'v4'
28
+
29
+ uri = URI.parse %(https://#{domain}/api/#{version})
30
+
31
+ # Set the project.
32
+ uri += %(/projects/#{URI.encode_www_form_component namespaced_repo})
33
+
34
+ # Then the filename.
35
+ uri += %(/repository/files/#{URI.encode_www_form_component path})
36
+
37
+ # Then the revision.
38
+ query = { ref: rev }
39
+ uri.query = URI.encode_www_form query
40
+
41
+ content = begin
42
+ headers = { 'Content-Type' => 'application-json' }
43
+ header['PRIVATE-TOKEN'] = ENV['GITLAB_API_PERSONAL_ACCESS_TOKEN'] if ENV['GITLAB_API_PERSONAL_ACCESS_TOKEN']
44
+
45
+ OpenURI.open_uri(uri, headers) do |f|
46
+ response = JSON.parse(f.read)
47
+
48
+ Base64.decode64 response['content'] if response['content'] && response['encoding'] == 'base64'
49
+ end
50
+ rescue OpenURI::HTTPError => e
51
+ warning = %(error while getting '#{path}' in GitLab repo '#{repo}': #{e})
52
+ warn_or_raise doc, warning
53
+ warning
54
+ end
55
+
56
+ reader.push_include content, target, target, 1, attrs
57
+ reader
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module Asciidoctor::Foodogsquared::Extensions
6
+ class GitLabInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
7
+ use_dsl
8
+
9
+ named :gitlab
10
+ name_positional_attributes 'caption'
11
+ default_attributes 'domain' => 'gitlab.com'
12
+
13
+ def process(parent, target, attrs)
14
+ doc = parent.document
15
+
16
+ default_caption = if attrs.key?('repo-option')
17
+ target.split('/').at(1)
18
+ else
19
+ target
20
+ end
21
+ text = attrs['caption'] || default_caption
22
+ uri = URI.parse %(https://#{attrs['domain']}/#{target})
23
+
24
+ if attrs.key? 'issue'
25
+ uri.path += %(/-/issues/#{attrs['issue']})
26
+ text << "##{attrs['issue']}" if text == target
27
+ else
28
+ uri.path += %(/-/tree/#{attrs['rev']}) if attrs.key? 'rev'
29
+ uri.path += %(/#{attrs['path']}) if attrs.key? 'path'
30
+ text << "@#{attrs['rev']}" if attrs.key?('rev') && text == target
31
+ end
32
+
33
+ target = uri.to_s
34
+
35
+ doc.register :links, target
36
+ create_anchor parent, text, type: :link, target: target
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Foodogsquared::Extensions
4
+ class IETFRFCInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
5
+ use_dsl
6
+
7
+ named :rfc
8
+ name_positional_attributes 'caption'
9
+
10
+ def process(parent, target, attrs)
11
+ doc = parent.document
12
+ url = %(https://datatracker.ietf.org/doc/html/#{target})
13
+ attrs['caption'] ||= "RFC#{target}"
14
+ doc.register :links, url
15
+ create_anchor parent, attrs['caption'], type: :link, target: url
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Foodogsquared::Extensions
4
+ class ManInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
5
+ use_dsl
6
+
7
+ named :man
8
+ name_positional_attributes 'volnum'
9
+ default_attributes 'service' => 'debian', 'subpath' => ''
10
+
11
+ def process(parent, target, attrs)
12
+ doc = parent.document
13
+ manname = target
14
+
15
+ text = %(#{manname}(#{attrs['volnum']}))
16
+
17
+ if doc.basebackend? 'html'
18
+ domain = case attrs['service']
19
+ when 'debian'
20
+ 'https://manpages.debian.org'
21
+ when 'ubuntu'
22
+ 'https://manpages.ubuntu.org'
23
+ when 'arch'
24
+ 'https://man.archlinux.org/man'
25
+ when 'opensuse'
26
+ 'https://manpages.opensuse.org'
27
+ when 'voidlinux'
28
+ 'https://man.voidlinux.org'
29
+ when 'openbsd'
30
+ 'https://man.openbsd.org'
31
+ when 'none'
32
+ nil
33
+ else
34
+ raise "no available manpage service #{attrs['service']}"
35
+ end
36
+
37
+ subpath = "#{attrs['subpath'].delete_prefix('/').delete_suffix('/')}/" if !attrs['subpath'].empty?
38
+ if !domain.nil?
39
+ target = %(#{domain}/#{subpath}#{manname}.#{attrs['volnum']})
40
+ doc.register :links, target
41
+ node = create_anchor parent, text, type: :link, target: target
42
+ else
43
+ node = create_inline parent, :quoted, text
44
+ end
45
+ elsif doc.backend == 'manpage'
46
+ node = create_inline parent, :quoted, text, type: :strong
47
+ else
48
+ node = create_inline parent, :quoted, text
49
+ end
50
+
51
+ node
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'open-uri'
5
+ require 'uri'
6
+
7
+ module Asciidoctor::Foodogsquared::Extensions
8
+ class MusicBrainzInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
9
+ use_dsl
10
+
11
+ named :musicbrainz
12
+ name_positional_attributes 'caption', 'type'
13
+ default_attributes 'type' => 'release'
14
+
15
+ def process(parent, target, attrs)
16
+ doc = parent.document
17
+ root_endpoint = 'https://musicbrainz.org/ws/2'
18
+
19
+ begin
20
+ headers = {
21
+ 'Accept' => 'application/json',
22
+ 'User-Agent' => ::Asciidoctor::Foodogsquared::USER_AGENT
23
+ }
24
+
25
+ uri = %(#{root_endpoint}/#{attrs['type']}/#{target})
26
+
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
+
37
+ target = %(https://musicbrainz.org/#{attrs['type']}/#{target})
38
+ doc.register :links, target
39
+ create_anchor parent, attrs['caption'], type: :link, target: target
40
+ rescue StandardError
41
+ warning = %(error while getting Musicbrainz database object '#{target}: #{e}')
42
+ warn_or_raise doc, warning
43
+ reader.push_include warning, target, target, 1, attrs
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,58 @@
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
+ module Asciidoctor::Foodogsquared::Extensions
8
+ class CtanInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
9
+ use_dsl
10
+
11
+ named :ctan
12
+ name_positional_attributes 'caption'
13
+
14
+ def process(parent, target, attrs)
15
+ doc = parent.document
16
+ text = attrs['caption'] || target
17
+ url = %(https://ctan.org/pkg/#{target})
18
+
19
+ doc.register :links, url
20
+
21
+ create_anchor parent, text, type: :link, target: url
22
+ end
23
+ end
24
+
25
+ class PypiInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
26
+ use_dsl
27
+
28
+ named :pypi
29
+ name_positional_attributes 'caption'
30
+
31
+ def process(parent, target, attrs)
32
+ doc = parent.document
33
+ text = attrs['caption'] || target
34
+ url = %(https://pypi.org/project/#{target})
35
+
36
+ doc.register :links, url
37
+
38
+ create_anchor parent, text, type: :link, target: url
39
+ end
40
+ end
41
+
42
+ class CratesIOInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
43
+ use_dsl
44
+
45
+ named :cratesio
46
+ name_positional_attributes 'caption'
47
+
48
+ def process(parent, target, attrs)
49
+ doc = parent.document
50
+ text = attrs['caption'] || target
51
+ url = %(https://crates.io/crates/#{target})
52
+
53
+ doc.register :links, url
54
+
55
+ create_anchor parent, text, type: :link, target: url
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor::Foodogsquared::Extensions
4
+ class RepologyInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
5
+ use_dsl
6
+
7
+ named :repology
8
+ name_positional_attributes 'caption'
9
+
10
+ def process(parent, target, attrs)
11
+ doc = parent.document
12
+ text = attrs['caption'] || target
13
+ url = %(https://repology.org/project/#{target})
14
+
15
+ doc.register :links, url
16
+
17
+ create_anchor parent, text, type: :link, target: url
18
+ end
19
+ end
20
+ end