Allow snippet section titles to be customized using document attributes
Closes gh-363
This commit is contained in:
@@ -45,6 +45,58 @@ operation::index[]
|
||||
|
||||
|
||||
|
||||
[[working-with-asciidoctor-including-snippets-operation-titles]]
|
||||
===== Section titles
|
||||
|
||||
For each snippet that's including using `operation` a section with a title will be
|
||||
created. Default titles are provided for the built-in snippets:
|
||||
|
||||
|===
|
||||
| Snippet | Title
|
||||
|
||||
| curl-request
|
||||
| Curl Request
|
||||
|
||||
| http-request
|
||||
| HTTP request
|
||||
|
||||
| http-response
|
||||
| HTTP response
|
||||
|
||||
| httpie-request
|
||||
| HTTPie request
|
||||
|
||||
| links
|
||||
| Links
|
||||
|
||||
| request-body
|
||||
| Request body
|
||||
|
||||
| request-fields
|
||||
| Request fields
|
||||
|
||||
| response-body
|
||||
| Response body
|
||||
|
||||
| response-fields
|
||||
| Response fields
|
||||
|===
|
||||
|
||||
For snippets not listed in the table above, a default title will be generated by replacing
|
||||
`-` characters with spaces and capitalising the first letter. For example, the title for a
|
||||
snippet named `custom-snippet` will be "Custom snippet".
|
||||
|
||||
The default titles can be customized using document attributes. The name of the attribute
|
||||
should be `operation-{snippet}-title`. For example, to customize the title of the
|
||||
`curl-request` snippet to be "Example request", use the following attribute:
|
||||
|
||||
[source,indent=0]
|
||||
----
|
||||
:operation-curl-request-title: Example request
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[working-with-asciidoctor-including-snippets-individual]]
|
||||
==== Including individual snippets
|
||||
|
||||
|
||||
@@ -15,29 +15,32 @@ class OperationBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
||||
def process(parent, operation, attributes)
|
||||
snippets_dir = parent.document.attributes['snippets'].to_s
|
||||
snippet_names = attributes.fetch 'snippets', ''
|
||||
content = read_snippets(snippets_dir, snippet_names, parent, operation)
|
||||
snippet_titles = SnippetTitles.new parent.document.attributes
|
||||
content = read_snippets(snippets_dir, snippet_names, parent, operation,
|
||||
snippet_titles)
|
||||
add_blocks(content, parent.document, parent) unless content.empty?
|
||||
nil
|
||||
end
|
||||
|
||||
def read_snippets(snippets_dir, snippet_names, parent, operation)
|
||||
def read_snippets(snippets_dir, snippet_names, parent, operation,
|
||||
snippet_titles)
|
||||
snippets = snippets_to_include(snippet_names, snippets_dir, operation)
|
||||
if snippets.empty?
|
||||
warn "No snippets were found for operation #{operation} in"\
|
||||
"#{snippets_dir}"
|
||||
"No snippets found for operation::#{operation}"
|
||||
else
|
||||
do_read_snippets(snippets, parent, operation)
|
||||
do_read_snippets(snippets, parent, operation, snippet_titles)
|
||||
end
|
||||
end
|
||||
|
||||
def do_read_snippets(snippets, parent, operation)
|
||||
def do_read_snippets(snippets, parent, operation, snippet_titles)
|
||||
content = StringIO.new
|
||||
section_level = parent.level + 1
|
||||
section_id = parent.id
|
||||
snippets.each do |snippet|
|
||||
append_snippet_block(content, snippet, section_level, section_id,
|
||||
operation)
|
||||
operation, snippet_titles)
|
||||
end
|
||||
content.string
|
||||
end
|
||||
@@ -59,7 +62,7 @@ class OperationBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
||||
else
|
||||
snippet_names.split(',').map do |name|
|
||||
path = File.join snippets_dir, operation, "#{name}.adoc"
|
||||
Snippet.new(path, name)
|
||||
Snippet.new path, name
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -74,8 +77,8 @@ class OperationBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
||||
end
|
||||
|
||||
def append_snippet_block(content, snippet, section_level, section_id,
|
||||
operation)
|
||||
write_title content, snippet, section_level, section_id
|
||||
operation, snippet_titles)
|
||||
write_title content, snippet, section_level, section_id, snippet_titles
|
||||
write_content content, snippet, operation
|
||||
end
|
||||
|
||||
@@ -91,38 +94,49 @@ class OperationBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
||||
end
|
||||
end
|
||||
|
||||
def write_title(content, snippet, level, id)
|
||||
def write_title(content, snippet, level, id, snippet_titles)
|
||||
section_level = '=' * (level + 1)
|
||||
title = snippet_titles.title_for_snippet snippet
|
||||
content.puts "[[#{id}_#{snippet.name.sub '-', '_'}]]"
|
||||
content.puts "#{section_level} #{snippet.title}"
|
||||
content.puts "#{section_level} #{title}"
|
||||
content.puts ''
|
||||
end
|
||||
|
||||
# Details of a snippet to be rendered
|
||||
class Snippet
|
||||
@titles = { 'http-request' => 'HTTP request',
|
||||
'curl-request' => 'Curl request',
|
||||
'httpie-request' => 'HTTPie request',
|
||||
'request-body' => 'Request body',
|
||||
'request-fields' => 'Request fields',
|
||||
'http-response' => 'HTTP response',
|
||||
'response-body' => 'Response body',
|
||||
'response-fields' => 'Response fields',
|
||||
'links' => 'Links' }
|
||||
|
||||
class << self
|
||||
attr_reader :titles
|
||||
end
|
||||
|
||||
attr_reader :name, :path
|
||||
|
||||
def initialize(path, name)
|
||||
@path = path
|
||||
@name = name
|
||||
@snippet_titles
|
||||
end
|
||||
end
|
||||
|
||||
class SnippetTitles
|
||||
@defaults = { 'http-request' => 'HTTP request',
|
||||
'curl-request' => 'Curl request',
|
||||
'httpie-request' => 'HTTPie request',
|
||||
'request-body' => 'Request body',
|
||||
'request-fields' => 'Request fields',
|
||||
'http-response' => 'HTTP response',
|
||||
'response-body' => 'Response body',
|
||||
'response-fields' => 'Response fields',
|
||||
'links' => 'Links' }
|
||||
|
||||
class << self
|
||||
attr_reader :defaults
|
||||
end
|
||||
|
||||
def title
|
||||
Snippet.titles.fetch @name, name.sub('-', ' ').capitalize
|
||||
def initialize(document_attributes)
|
||||
@document_attributes = document_attributes
|
||||
end
|
||||
|
||||
def title_for_snippet(snippet)
|
||||
attribute_name = "operation-#{snippet.name}-title"
|
||||
@document_attributes.fetch attribute_name do
|
||||
SnippetTitles.defaults.fetch snippet.name, snippet.name.sub('-', ' ').capitalize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -62,12 +61,6 @@ public class OperationBlockMacroTests {
|
||||
this.options.setAttributes(getAttributes());
|
||||
}
|
||||
|
||||
private Attributes getAttributes() {
|
||||
Attributes attributes = new Attributes();
|
||||
attributes.setAttribute("projectdir", new File(".").getAbsolutePath());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleSnippetInclude() throws Exception {
|
||||
String result = this.asciidoctor.convert(
|
||||
@@ -106,27 +99,49 @@ public class OperationBlockMacroTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void includingUnknownSnippetAddsWarning() throws Exception {
|
||||
public void includingMissingSnippetAddsWarning() throws Exception {
|
||||
String result = this.asciidoctor.convert(
|
||||
"operation::some-operation[snippets='unknown-snippet']", this.options);
|
||||
"operation::some-operation[snippets='missing-snippet']", this.options);
|
||||
assertThat(result, startsWith(getExpectedContentFromFile("missing-snippet")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void includingCustomSnippetCreatesCustomTitle() throws Exception {
|
||||
public void defaultTitleIsProvidedForCustomSnippet() throws Exception {
|
||||
String result = this.asciidoctor.convert(
|
||||
"operation::some-operation[snippets='custom-snippet']", this.options);
|
||||
assertThat(result,
|
||||
containsString(getExpectedContentFromFile("snippet-custom-title")));
|
||||
equalTo(getExpectedContentFromFile("custom-snippet-default-title")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonExistentOperationIsHandledGracefully() throws Exception {
|
||||
String result = this.asciidoctor.convert("operation::non-existent-operation[]",
|
||||
public void missingOperationIsHandledGracefully() throws Exception {
|
||||
String result = this.asciidoctor.convert("operation::missing-operation[]",
|
||||
this.options);
|
||||
assertThat(result, startsWith(getExpectedContentFromFile("missing-operation")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void titleOfBuiltInSnippetCanBeCustomizedUsingDocumentAttribute()
|
||||
throws URISyntaxException, IOException {
|
||||
String result = this.asciidoctor.convert(
|
||||
":operation-curl-request-title: Example request\n"
|
||||
+ "operation::some-operation[snippets='curl-request']",
|
||||
this.options);
|
||||
assertThat(result,
|
||||
equalTo(getExpectedContentFromFile("built-in-snippet-custom-title")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void titleOfCustomSnippetCanBeCustomizedUsingDocumentAttribute()
|
||||
throws Exception {
|
||||
String result = this.asciidoctor.convert(
|
||||
":operation-custom-snippet-title: Customized title\n"
|
||||
+ "operation::some-operation[snippets='custom-snippet']",
|
||||
this.options);
|
||||
assertThat(result,
|
||||
equalTo(getExpectedContentFromFile("custom-snippet-custom-title")));
|
||||
}
|
||||
|
||||
private String getExpectedContentFromFile(String fileName)
|
||||
throws URISyntaxException, IOException {
|
||||
Path filePath = Paths.get(
|
||||
@@ -142,4 +157,10 @@ public class OperationBlockMacroTests {
|
||||
return File.separatorChar == '\\';
|
||||
}
|
||||
|
||||
private Attributes getAttributes() {
|
||||
Attributes attributes = new Attributes();
|
||||
attributes.setAttribute("projectdir", new File(".").getAbsolutePath());
|
||||
return attributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="sect1">
|
||||
<h2 id="_curl_request">Example request</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/' -i</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="sect1">
|
||||
<h2 id="_custom_snippet">Customized title</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight nowrap"><code class="language-http" data-lang="http">mycustomsnippet</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="sect1">
|
||||
<h2 id="_custom_snippet">Custom snippet</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight nowrap"><code class="language-http" data-lang="http">mycustomsnippet</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="paragraph">
|
||||
<p>No snippets found for operation::non-existent-operation</p>
|
||||
<p>No snippets found for operation::missing-operation</p>
|
||||
</div>
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="sect1">
|
||||
<h2 id="_unknown_snippet">Unknown snippet</h2>
|
||||
<h2 id="_missing_snippet">Missing snippet</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Snippet unknown-snippet not found for operation::some-operation</p>
|
||||
<p>Snippet missing-snippet not found for operation::some-operation</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
<h2 id="_custom_snippet">Custom snippet</h2>
|
||||
Reference in New Issue
Block a user