Expose Section's sectnum property
MODIFY
CHANGELOG.adoc
CHANGELOG.adoc
@@ -22,6 +22,7 @@ Improvement::
* Upgrade to JRuby 9.3.8.0 (#1116)
* Upgrade to tilt 2.0.11 (#1109)
* Upgrade to asciimath 2.0.4 (#1109)
+* Expose `sectnum` property in Section interface (#1121)
Bug Fixes::

MODIFY
asciidoctorj-api/src/main/java/org/asciidoctor/ast/Section.java
asciidoctorj-api/src/main/java/org/asciidoctor/ast/Section.java
@@ -74,4 +74,24 @@ public interface Section extends StructuralNode {
*/
boolean isNumbered();
+
+ /**
+ * Get the section number for the current Section.
+ * <p>
+ * The section number is a dot-separated String that uniquely describes the position of this
+ * Section in the document. Each entry represents a level of nesting. The value of each entry is
+ * the 1-based outline number of the Section amongst its numbered sibling Sections.
+ */
+ String getSectnum();
+
+ /**
+ * Get the section number for the current Section.
+ * <p>
+ * The section number is a dot-separated String that uniquely describes the position of this
+ * Section in the document. Each entry represents a level of nesting. The value of each entry is
+ * the 1-based outline number of the Section amongst its numbered sibling Sections.
+ *
+ * @param delimiter the delimiter to separate the number for each level
+ */
+ String getSectnum(String delimiter);
}

MODIFY
asciidoctorj-core/src/main/java/org/asciidoctor/jruby/ast/impl/SectionImpl.java
asciidoctorj-core/src/main/java/org/asciidoctor/jruby/ast/impl/SectionImpl.java
@@ -70,4 +70,14 @@ public class SectionImpl extends StructuralNodeImpl implements Section {
return getBoolean("numbered");
}
+ @Override
+ public String getSectnum() {
+ return getString("sectnum");
+ }
+
+ @Override
+ public String getSectnum(String delimiter) {
+ return getString("sectnum", new Object[]{delimiter});
+ }
+
}

ADD
asciidoctorj-core/src/test/java/org/asciidoctor/jruby/ast/impl/SectionImplTest.java
+package org.asciidoctor.jruby.ast.impl;
+
+import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.Attributes;
+import org.asciidoctor.Options;
+import org.asciidoctor.ast.Document;
+import org.asciidoctor.ast.Section;
+import org.junit.Test;
+
+import java.util.Collections;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SectionImplTest {
+
+ private Asciidoctor asciidoctor = Asciidoctor.Factory.create();
+
+
+ @Test
+ public void should_return_valid_sectnum_when_sectionNumbers_are_enabled() {
+ final String source = sectionsSample();
+
+ Document document = loadDocument(source, true);
+
+ Section node1 = findSectionNode(document, 1);
+ assertThat(node1.getSectnum()).isEqualTo("1.");
+ assertThat(node1.isNumbered()).isTrue();
+
+ Section node2 = findSectionNode(document, 2);
+ assertThat(node2.getSectnum()).isEqualTo("1.1.");
+ assertThat(node2.isNumbered()).isTrue();
+ }
+
+ @Test
+ public void should_return_invalid_sectnum_when_sectionNumbers_are_not_enabled() {
+ final String source = sectionsSample();
+
+ Document document = loadDocument(source, false);
+
+ Section node1 = findSectionNode(document, 1);
+ assertThat(node1.getSectnum()).isEqualTo(".");
+ assertThat(node1.isNumbered()).isFalse();
+
+ Section node2 = findSectionNode(document, 2);
+ assertThat(node2.getSectnum()).isEqualTo("..");
+ assertThat(node2.isNumbered()).isFalse();
+ }
+
+ @Test
+ public void should_return_sectnum_with_custom_delimiter_when_sectionNumbers_are_enabled() {
+ final String source = sectionsSample();
+
+ Document document = loadDocument(source, true);
+
+ Section node1 = findSectionNode(document, 1);
+ assertThat(node1.getSectnum("_")).isEqualTo("1_");
+
+ Section node2 = findSectionNode(document, 2);
+ assertThat(node2.getSectnum("*")).isEqualTo("1*1*");
+ }
+
+ @Test
+ public void should_return_sectnum_with_custom_delimiter_when_sectionNumbers_are_not_enabled() {
+ final String source = sectionsSample();
+
+ Document document = loadDocument(source, false);
+
+ Section node1 = findSectionNode(document, 1);
+ assertThat(node1.getSectnum("_")).isEqualTo("_");
+
+ Section node2 = findSectionNode(document, 2);
+ assertThat(node2.getSectnum("*")).isEqualTo("**");
+ }
+
+ private Document loadDocument(String source, boolean sectionNumbers) {
+ Attributes attributes = Attributes.builder().sectionNumbers(sectionNumbers).build();
+ Options options = Options.builder().attributes(attributes).build();
+ Document document = asciidoctor.load(source, options);
+ return document;
+ }
+
+ private Section findSectionNode(Document document, int level) {
+ return (Section) document.findBy(Collections.singletonMap("context", ":section"))
+ .stream()
+ .filter(n -> n.getLevel() == level)
+ .findFirst()
+ .get();
+ }
+
+ static String sectionsSample() {
+ return "= Document Title\n\n" +
+ "== Section A\n\n" +
+ "Section A paragraph.\n\n" +
+ "=== Section A Subsection\n\n" +
+ "Section A 'subsection' paragraph.\n\n";
+ }
+}

Expose Section's sectnum property