Skip to content

Commit c1bc6a1

Browse files
authored
Merge pull request #600 from gmlueck/gmlueck/api-xrefs-attribute
Enable additional API cross-references
2 parents 398180c + 582e560 commit c1bc6a1

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

adoc/config/api_xrefs/extension.rb

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,47 @@
3737
# Note that an "API" can be anything. This extension only cares that the text
3838
# in the "[apidef]" role matches the text in the "[api]" role.
3939
#
40+
# Sometimes you want an API name to link to something that is not an [apidef]
41+
# title. In this case, you can define the Asciidoc attribute "api-xrefs", which
42+
# has a syntax like:
43+
#
44+
# :api-xrefs: API1=ID1 API2=ID2 ...
45+
#
46+
# The IDs (ID1, ID2, etc.) must be defined someplace in the Asciidoc document.
47+
# Each of these IDs is used as the target for the associated API (API1, API2,
48+
# etc.)
49+
#
4050
# Typically, projects using this extension also provide some custom CSS styling
4151
# for the "apidef" and "api" HTML classes.
4252

4353
class AddApiXrefs < Extensions::Postprocessor
4454
include Asciidoctor::Logging
4555

56+
Id = /<\w+ id="([\w:-]*)"/
4657
ApiSpan = /<span class="api">([\w:]*)<\/span>/
4758
ApiDefSpan = /<span class="apidef">([\w:]*)<\/span>/
4859
ApiIdDiv = /<div id="([\w:-]*)"/
4960

5061
def process document, output
5162

5263
if document.basebackend? 'html'
64+
# Get all of the IDs in the HTML document, so we can do error checking
65+
# below.
66+
all_ids = output.scan(Id).to_h{|m| [m.first, true]}
67+
68+
# Parse the api-xrefs attribute. Make sure each ID is defined someplace
69+
# in the document. Populate "api_id_array" with this information.
70+
api_id_array = []
71+
if document.attr? 'api-xrefs'
72+
(document.attr 'api-xrefs').scan(/([\w:-]*)=([\w:-]*)/) do |api, id|
73+
if not all_ids.key?(id)
74+
logger.error "Id '#{id}' from api-xrefs is not defined"
75+
else
76+
api_id_array.push([api, id])
77+
end
78+
end
79+
end
80+
5381
# Scan through all the HTML lines looking for the "[apidef]" definitions.
5482
# A typical definition looks like this:
5583
#
@@ -58,16 +86,19 @@ def process document, output
5886
# <div class="title"><span class="apidef">NAME</span></div>
5987
#
6088
# where the <a> element above may or may not be present, depending on
61-
# whether the listing block also uses the "synopsis" extension.
89+
# whether the listing block also uses the "synopsis" extension. Add
90+
# these also to "api_id_array".
6291
#
63-
api_id_array = output.lines.each_cons(3).filter_map do |prev2, prev1, cur|
92+
output.lines.each_cons(3) do |prev2, prev1, cur|
6493
api = cur.scan(ApiDefSpan).first
6594
api_id = prev1.scan(ApiIdDiv).first || prev2.scan(ApiIdDiv).first
66-
[api.first, api_id.first] if api && api_id
95+
if api && api_id
96+
api_id_array.push([api.first, api_id.first])
97+
end
6798
end
6899

69-
# Diagnose duplicate id definitions, and create a hash mapping each API
70-
# name to its ID.
100+
# Diagnose duplicate apidef definitions, and create a hash mapping each
101+
# API name to its ID.
71102
api_to_id = {}
72103
api_id_array.map do |api, api_id|
73104
if api_to_id.key?(api)

0 commit comments

Comments
 (0)