Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ NORM_RULE_HTML_OUTPUT_FNAME := test-norm-rules.html
# Tag extraction test files
DUPLICATE_TEST_ADOC_INPUT_FNAME := duplicate.adoc
DUPLICATE_NORM_TAGS_OUTPUT_FNAME := duplicate-tags.json
ADMONITION_TEST_ADOC_INPUT_FNAME := admonition.adoc
ADMONITION_NORM_TAGS_OUTPUT_FNAME := admonition-admonition-tags.json
ADMONITION_ERRORS_FNAME := admonition-errors.txt

# Built output files
BUILT_TEST_CH1_HTML_FNAME := $(BUILD_DIR)/$(TEST_CH1_HTML_FNAME)
BUILT_TEST_CH2_HTML_FNAME := $(BUILD_DIR)/$(TEST_CH2_HTML_FNAME)
BUILT_TEST_CH1_NORM_TAGS_FNAME := $(BUILD_DIR)/$(TEST_CH1_NORM_TAGS_OUTPUT_FNAME)
BUILT_TEST_CH2_NORM_TAGS_FNAME := $(BUILD_DIR)/$(TEST_CH2_NORM_TAGS_OUTPUT_FNAME)
BUILT_DUPLICATE_NORM_TAGS_FNAME := $(BUILD_DIR)/$(DUPLICATE_NORM_TAGS_OUTPUT_FNAME)
BUILT_ADMONITION_NORM_TAGS_FNAME := $(BUILD_DIR)/$(ADMONITION_NORM_TAGS_OUTPUT_FNAME)
BUILT_NORM_RULES_JSON := $(BUILD_DIR)/$(NORM_RULE_JSON_OUTPUT_FNAME)
BUILT_NORM_RULES_HTML := $(BUILD_DIR)/$(NORM_RULE_HTML_OUTPUT_FNAME)

Expand Down Expand Up @@ -151,7 +155,7 @@ test: build-tests compare-tests test-adoc2html test-shared-utils test-text-to-ht
# Build tests
.PHONY: build-tests build-test-tags build-test-norm-rules-json build-test-norm-rules-html
build-tests: build-test-tags build-test-norm-rules-json build-test-norm-rules-html
build-test-tags: $(BUILT_TEST_NORM_TAGS_FNAMES) $(BUILT_DUPLICATE_NORM_TAGS_FNAME)
build-test-tags: $(BUILT_TEST_NORM_TAGS_FNAMES) $(BUILT_DUPLICATE_NORM_TAGS_FNAME) $(BUILT_ADMONITION_NORM_TAGS_FNAME)
build-test-norm-rules-json: $(BUILT_NORM_RULES_JSON)
build-test-norm-rules-html: $(BUILT_NORM_RULES_HTML)

Expand Down Expand Up @@ -258,6 +262,15 @@ $(BUILT_DUPLICATE_NORM_TAGS_FNAME): $(TAGS_TESTS_DIR)/$(DUPLICATE_TEST_ADOC_INPU
$(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='duplicate:' -a tags-output-suffix='-duplicate-tags.json' $< || touch $(BUILT_DUPLICATE_NORM_TAGS_FNAME) $(DOCKER_QUOTE)
$(WORKDIR_TEARDOWN)

# Build tags with admonition adoc input.
# Tags in or on an admonition are errors, so Asciidoctor must fail and report each "bad" tag.
$(BUILT_ADMONITION_NORM_TAGS_FNAME): $(TAGS_TESTS_DIR)/$(ADMONITION_TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND)
$(WORKDIR_SETUP)
$(DOCKER_CMD) $(DOCKER_QUOTE) ! $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='admonition:' -a tags-output-suffix='-admonition-tags.json' $< 2> $(ADMONITION_ERRORS_FNAME) $(DOCKER_QUOTE)
test "$$(grep -c "^asciidoctor: ERROR: Tag 'admonition:bad-.*' is in an admonition" $@.workdir/$(ADMONITION_ERRORS_FNAME))" -eq 5
! grep -q "admonition:ok-" $@.workdir/$(ADMONITION_ERRORS_FNAME)
$(WORKDIR_TEARDOWN)

# Build normative rules with JSON output format
$(BUILT_NORM_RULES_JSON): $(BUILT_TEST_NORM_TAGS_FNAMES) $(CREATE_NORM_RULE_TOOL)
$(WORKDIR_SETUP)
Expand Down
14 changes: 14 additions & 0 deletions converters/tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def convert(node, transform = node.node_name, opts = nil)
if node.id.start_with?(@prefix)
node.document.logger.error "Duplicate tag name '#{node.id}'" unless @tag_map[node.id].nil?
node.document.logger.error "Tag '#{node.id}' content should be a String but it is #{content.class}" unless content.is_a?(String)
node.document.logger.error "Tag '#{node.id}' is in an admonition, which is non-normative" if in_admonition?(node)

@tag_map[node.id] = content.strip()
@section_stack.last["tags"] << node.id
Expand All @@ -108,6 +109,19 @@ def convert(node, transform = node.node_name, opts = nil)

private

# Return true if the node is an admonition (e.g. a tag on the line above
# `[NOTE]`) or is inside one. Inline nodes reach their block via `parent`.
#
# node: AbstractNode
# returns: Boolean
def in_admonition?(node)
until node.nil? || node.context == :document
return true if node.context == :admonition
node = node.parent
end
false
end

# Return the text content of a node. Adapted from `text-converter.rb`
# in the docs: https://docs.asciidoctor.org/asciidoctor/latest/convert/custom/
#
Expand Down
9 changes: 4 additions & 5 deletions normative-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ If you'd like to see detailed AsciiDoc examples of tagging cases, see https://gi
This also includes text followed by a list (ordered, unordered, description) since there has to be
a blank line between the text the list.
> * Must have text next to the 2nd hash symbol (i.e., can't have newline after `[#<anchor-name]#`).
> * Can't put inside admonitions such as [NOTE] (see #4 below for solution).
> * Can't put inside admonitions such as [NOTE] (see #4 below).
> * Can't have `.` in anchor-name (replace with hyphen)

3. Tagging description lists
Expand All @@ -146,7 +146,6 @@ If you'd like to see detailed AsciiDoc examples of tagging cases, see https://gi
> `Bananas::`<br>
> `Generally yellow in color`

4. Tagging admonitions (e.g. `[NOTE]`):
* Can tag entire admonition by putting ``[[anchor-name]]`` before `[NOTE]`
* Can also tag individual paragraphs in admonition using `[[<anchor-name]]` before each paragraph
* Only use `NOTE: [#<anchor-name]#Here's some note text.#` for this style of admonition
4. Admonitions (e.g. `[NOTE]`, `NOTE:`, `[WARNING]`) are non-normative, so they can't contain normative rules:
* The tags backend reports an error for a tag inside an admonition, or on the line just above one (which tags the admonition itself).
* If the admonition is the only place a requirement is stated, move that text out of the admonition and tag it there. Otherwise, remove the tag.
30 changes: 4 additions & 26 deletions tests/norm-rule/expected/test-ch2-norm-tags.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
{
"tags": {
"norm:admonition:single-paragraph-note": "Single paragraph note\nthat spans lines.",
"norm:admonition:no-anchors-in-notes:entire-note": "Paragraph A\n\nParagraph B\n\nParagraph C",
"norm:admonition:anchors-in-notes:note1": "Paragraph 0",
"norm:admonition:anchors-in-notes:note3": "Paragraph 2",
"norm:admonition:anchors-in-notes:entire-note": "Paragraph 0\n\nParagraph 1\n\nParagraph 2",
"norm:admonition:only-anchors-in-notes:note1": "Paragraph X",
"norm:admonition:only-anchors-in-notes:note3": "Paragraph Z",
"norm:ROSE_COLORS": "You can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see ^superscript^ as long as I use the inline anchor and not the paragraph anchor.",
"norm:XLEN": "We use the term XLEN to refer to the width of an integer register in bits (either 32 or 64). No superscript in paragraph anchors for some reason.",
"norm:ASIDLEN": "The number of ASID bits is UNSPECIFIED and may be zero. The number of implemented ASID bits, termed ASIDLEN, may be determined by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one.",
Expand All @@ -32,23 +25,8 @@
"level": 1,
"children": [
{
"title": "Chapter 2.1 - Tagging Admonitions",
"id": "_chapter_2_1_tagging_admonitions",
"level": 2,
"children": [],
"tags": [
"norm:admonition:single-paragraph-note",
"norm:admonition:no-anchors-in-notes:entire-note",
"norm:admonition:anchors-in-notes:note1",
"norm:admonition:anchors-in-notes:note3",
"norm:admonition:anchors-in-notes:entire-note",
"norm:admonition:only-anchors-in-notes:note1",
"norm:admonition:only-anchors-in-notes:note3"
]
},
{
"title": "Chapter 2.2 - Implementation-Defined Behaviors",
"id": "_chapter_2_2_implementation_defined_behaviors",
"title": "Chapter 2.1 - Implementation-Defined Behaviors",
"id": "_chapter_2_1_implementation_defined_behaviors",
"level": 2,
"children": [],
"tags": [
Expand All @@ -65,8 +43,8 @@
]
},
{
"title": "Chapter 2.3 - CSR Field Types",
"id": "_chapter_2_3_csr_field_types",
"title": "Chapter 2.2 - CSR Field Types",
"id": "_chapter_2_2_csr_field_types",
"level": 2,
"children": [],
"tags": [
Expand Down
39 changes: 2 additions & 37 deletions tests/norm-rule/expected/test-norm-rules.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ <h2>All Normative Rules</h2>
</aside>
<main>
<style>.grand-total-heading { font-size: 24px; font-weight: bold; }</style>
<h1 class="grand-total-heading">94 Normative Rules</h1>
<h1 class="grand-total-heading">87 Normative Rules</h1>

<section id="table-norm-rules-ch-1" class="section">
<table>
<caption class="sticky-caption">Chapter Chapter 2: 21 Normative Rules</caption>
<caption class="sticky-caption">Chapter Chapter 2: 14 Normative Rules</caption>
<colgroup>
<col class="col-name">
<col class="col-description">
Expand All @@ -158,41 +158,6 @@ <h1 class="grand-total-heading">94 Normative Rules</h1>
<tr><th>Name</th><th>Text</th><th>Location</th></tr>
</thead>
<tbody>
<tr>
<td id="admonition:single-paragraph-note">admonition:single-paragraph-note</td>
<td>Single paragraph note<br>that spans lines.</td>
<td><a href="test-ch2.html#norm:admonition:single-paragraph-note">norm:admonition:single-paragraph-note</a></td>
</tr>
<tr>
<td id="admonition:no-anchors-in-notes:entire-note">admonition:no-anchors-in-notes:entire-note</td>
<td>Paragraph A<br><br>Paragraph B<br><br>Paragraph C</td>
<td><a href="test-ch2.html#norm:admonition:no-anchors-in-notes:entire-note">norm:admonition:no-anchors-in-notes:entire-note</a></td>
</tr>
<tr>
<td id="admonition:anchors-in-notes:note1">admonition:anchors-in-notes:note1</td>
<td>Paragraph 0</td>
<td><a href="test-ch2.html#norm:admonition:anchors-in-notes:note1">norm:admonition:anchors-in-notes:note1</a></td>
</tr>
<tr>
<td id="admonition:anchors-in-notes:note3">admonition:anchors-in-notes:note3</td>
<td>Paragraph 2</td>
<td><a href="test-ch2.html#norm:admonition:anchors-in-notes:note3">norm:admonition:anchors-in-notes:note3</a></td>
</tr>
<tr>
<td id="admonition:anchors-in-notes:entire-note">admonition:anchors-in-notes:entire-note</td>
<td>Paragraph 0<br><br>Paragraph 1<br><br>Paragraph 2</td>
<td><a href="test-ch2.html#norm:admonition:anchors-in-notes:entire-note">norm:admonition:anchors-in-notes:entire-note</a></td>
</tr>
<tr>
<td id="admonition:only-anchors-in-notes:note1">admonition:only-anchors-in-notes:note1</td>
<td>Paragraph X</td>
<td><a href="test-ch2.html#norm:admonition:only-anchors-in-notes:note1">norm:admonition:only-anchors-in-notes:note1</a></td>
</tr>
<tr>
<td id="admonition:only-anchors-in-notes:note3">admonition:only-anchors-in-notes:note3</td>
<td>Paragraph Z</td>
<td><a href="test-ch2.html#norm:admonition:only-anchors-in-notes:note3">norm:admonition:only-anchors-in-notes:note3</a></td>
</tr>
<tr>
<td id="ROSE_COLORS">ROSE_COLORS</td>
<td>You can use red or yellow roses. The tags backend removes some adoc formating so I don't see bold text but I can see <sup>superscript</sup> as long as I use the inline anchor and not the paragraph anchor.</td>
Expand Down
49 changes: 0 additions & 49 deletions tests/norm-rule/expected/test-norm-rules.json
Original file line number Diff line number Diff line change
@@ -1,54 +1,5 @@
{
"normative_rules": [
{
"name": "admonition:single-paragraph-note",
"chapter_name": "Chapter 2",
"text": "Single paragraph note\nthat spans lines.",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:no-anchors-in-notes:entire-note",
"chapter_name": "Chapter 2",
"text": "Paragraph A\n\nParagraph B\n\nParagraph C",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:anchors-in-notes:note1",
"chapter_name": "Chapter 2",
"text": "Paragraph 0",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:anchors-in-notes:note3",
"chapter_name": "Chapter 2",
"text": "Paragraph 2",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:anchors-in-notes:entire-note",
"chapter_name": "Chapter 2",
"text": "Paragraph 0\n\nParagraph 1\n\nParagraph 2",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:only-anchors-in-notes:note1",
"chapter_name": "Chapter 2",
"text": "Paragraph X",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "admonition:only-anchors-in-notes:note3",
"chapter_name": "Chapter 2",
"text": "Paragraph Z",
"tag_filename": "/build/test-ch2-norm-tags.json",
"stds_doc_url": "test-ch2.html"
},
{
"name": "ROSE_COLORS",
"chapter_name": "Chapter 2",
Expand Down
49 changes: 2 additions & 47 deletions tests/norm-rule/test-ch2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,7 @@

== Chapter 2

=== Chapter 2.1 - Tagging Admonitions

// PASSES
NOTE: [#norm:admonition:single-paragraph-note]#Single paragraph note
that spans lines.#

// PASSES - Tag contains entire list
[[norm:admonition:no-anchors-in-notes:entire-note]]
[NOTE]
====
Paragraph A

Paragraph B

Paragraph C
====

// PASSES - Tag contains entire list
[[norm:admonition:anchors-in-notes:entire-note]]
[NOTE]
====
// PASSES - Tag contains paragraph
[[norm:admonition:anchors-in-notes:note1]]
Paragraph 0

Paragraph 1

// PASSES - Tag contains paragraph
[[norm:admonition:anchors-in-notes:note3]]
Paragraph 2
====

[NOTE]
====
// PASSES - Tag contains paragraph
[[norm:admonition:only-anchors-in-notes:note1]]
Paragraph X

Paragraph Y

// PASSES - Tag contains paragraph
[[norm:admonition:only-anchors-in-notes:note3]]
Paragraph Z
====

=== Chapter 2.2 - Implementation-Defined Behaviors
=== Chapter 2.1 - Implementation-Defined Behaviors

[#norm:ROSE_COLORS]#You can use red or yellow roses. The tags backend removes some adoc formating so I don't see *bold* text but I can see ^superscript^ as long as I use the inline anchor and not the paragraph anchor.#

Expand Down Expand Up @@ -80,7 +35,7 @@ Here's a normative rule for mock CSR field "Y".
[[norm:mock-ext-dep-A-on-B]]
Here's a normative rule for mock extension dependency of extension A on extension B.

=== Chapter 2.3 - CSR Field Types
=== Chapter 2.2 - CSR Field Types

[#norm:foo_abc_warl_enum]#An implementation may support any or all of the following values for the 4-bit `foo.ABC` field: When `foo.GHI` is 0, legal values are 0, 4, 15. When `foo.GHI` is non-zero, legal values are 1, 2, 3.#

Expand Down
27 changes: 27 additions & 0 deletions tests/tags/admonition.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Used to test that the tags backend reports an error for every tag in or on an admonition,
// since admonitions are non-normative. Each tag below must be reported.

== Chapter 1

[#admonition:ok-inline]#Normative text outside any admonition.#

NOTE: [#admonition:bad-paragraph-note]#Inline tag in a paragraph admonition.#

[[admonition:bad-entire-note]]
[NOTE]
====
An anchor on the line above an admonition tags the admonition itself.
====

[WARNING]
====
[[admonition:bad-paragraph-in-block]]
A tagged paragraph in a delimited admonition of another type.

* [#admonition:bad-list-item-in-block]#A tagged list item in an admonition.#
====

TIP: An inline anchor [[admonition:bad-inline-anchor]] in a paragraph admonition.

[[admonition:ok-paragraph]]
A tagged paragraph outside any admonition.
Loading