Module: Sourcerer::AsciiDoc
- Defined in:
- lib/sourcerer/asciidoc.rb
Overview
AsciiDoc-focused primitives for attribute loading, region extraction, includes, and converter-oriented utilities. AsciiDoc processing module for document conversion and content extraction.
This module provides utilities for working with AsciiDoc files, including:
-
Loading document attributes and snippets via include directives
-
Extracting tagged content from files
-
Converting AsciiDoc to HTML, manpage, and Markdown formats
-
Managing YAML front matter in AsciiDoc documents
-
Extracting commands from code blocks with specific roles
Defined Under Namespace
Modules: AttributesFilter
Constant Summary collapse
- YAML_FRONTMATTER_REGEXP =
Sourcerer::YamlFrontmatter::REGEXP
- YAML_FRONT_MATTER_REGEXP =
YAML_FRONTMATTER_REGEXP- PAGE_ATTRIBUTE_PREFIX =
'page-'
Class Method Summary collapse
-
.compose_front_matter_block(frontmatter) ⇒ Object
Compatibility alias.
-
.compose_frontmatter_block(frontmatter) ⇒ String?
Build YAML front matter block content from a hash.
-
.extract_commands(file_path, role: 'testable') ⇒ Array<String>
Extracts commands from listing and literal blocks with a specific role.
-
.extract_frontmatter(source_text, document_attributes) ⇒ Hash
Extract front matter from AsciiDoc text using YAML fences and page-* attributes.
-
.extract_page_attributes(document_attributes) ⇒ Hash
Parse page-* attributes using Asciidoctor-resolved document attributes.
-
.extract_tagged_content(path_to_tagged_adoc, **options) ⇒ String
Extracts tagged content from a file.
-
.extract_yaml_front_matter(source_text) ⇒ Object
Compatibility alias.
-
.extract_yaml_frontmatter(source_text) ⇒ Hash
Parse optional YAML front matter fenced with — at the top of source content.
-
.generate_html(source_adoc, target_html, backend: 'asciidoctor-html5s', header_footer: false) ⇒ String
Generates HTML from an AsciiDoc source file.
-
.generate_manpage(source_adoc, target_manpage) ⇒ Object
Generates a manpage from an AsciiDoc source file.
-
.load_attributes(path) ⇒ Hash
Loads AsciiDoc attributes from a document header as a Hash.
-
.load_include(path_to_main_adoc, tag: nil, tags: [], leveloffset: nil) ⇒ String
Loads a snippet from an AsciiDoc file using an ‘include::` directive.
-
.mark_down_grade(source_path, markdown_output_path = nil, markdown_converter:, **options) ⇒ Hash
Convert AsciiDoc source to Markdown through an interim HTML conversion.
-
.prepend_front_matter(content, frontmatter) ⇒ Object
Compatibility alias.
-
.prepend_frontmatter(content, frontmatter) ⇒ String
Prepend front matter block to content.
-
.split_front_matter(content) ⇒ Object
Compatibility alias.
-
.split_frontmatter_block(content) ⇒ Array<(String, String)>
Split front matter block from content if present.
-
.strip_yaml_front_matter(source_text) ⇒ Object
Compatibility alias.
-
.strip_yaml_frontmatter(source_text) ⇒ String
Remove leading YAML front matter fence block from AsciiDoc source.
Class Method Details
.compose_front_matter_block(frontmatter) ⇒ Object
Compatibility alias.
377 378 379 |
# File 'lib/sourcerer/asciidoc.rb', line 377 def self.compose_front_matter_block frontmatter compose_frontmatter_block(frontmatter) end |
.compose_frontmatter_block(frontmatter) ⇒ String?
Build YAML front matter block content from a hash.
286 287 288 289 290 291 292 293 294 |
# File 'lib/sourcerer/asciidoc.rb', line 286 def self.compose_frontmatter_block frontmatter return nil if frontmatter.nil? || frontmatter.empty? yaml_payload = Psych.dump(frontmatter, nil, { line_width: -1 }) yaml_payload = yaml_payload.sub(/\A---\s*\n/, '') yaml_payload = yaml_payload.sub(/\n\.\.\.\s*\z/, "\n") "---\n#{yaml_payload}---" end |
.extract_commands(file_path, role: 'testable') ⇒ Array<String>
Extracts commands from listing and literal blocks with a specific role.
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
# File 'lib/sourcerer/asciidoc.rb', line 432 def self.extract_commands file_path, role: 'testable' doc = Asciidoctor.load_file(file_path, safe: :unsafe) command_groups = [] current_group = [] blocks = doc.find_by(context: :listing) + doc.find_by(context: :literal) blocks.each do |block| next unless block.has_role?(role) commands = process_block_content(block.content) if block.has_role?('testable-newshell') command_groups << current_group.join("\n") unless current_group.empty? command_groups << commands.join("\n") unless commands.empty? current_group = [] else current_group.concat(commands) end end command_groups << current_group.join("\n") unless current_group.empty? command_groups end |
.extract_frontmatter(source_text, document_attributes) ⇒ Hash
Extract front matter from AsciiDoc text using YAML fences and page-* attributes.
276 277 278 279 280 |
# File 'lib/sourcerer/asciidoc.rb', line 276 def self.extract_frontmatter source_text, document_attributes page_attrs = extract_page_attributes(document_attributes) yaml_frontmatter = extract_yaml_frontmatter(source_text) page_attrs.merge(yaml_frontmatter) end |
.extract_page_attributes(document_attributes) ⇒ Hash
Parse page-* attributes using Asciidoctor-resolved document attributes.
325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/sourcerer/asciidoc.rb', line 325 def self.extract_page_attributes document_attributes attributes = {} prefix = PAGE_ATTRIBUTE_PREFIX document_attributes.each do |key, value| next unless key.start_with?(prefix) normalized_key = key.sub(/\A#{Regexp.escape(prefix)}/, '') attributes[normalized_key] = coerce_page_attribute_value(value) end attributes end |
.extract_tagged_content(path_to_tagged_adoc, **options) ⇒ String
Extracts tagged content from a file.
88 89 90 91 92 93 94 95 96 |
# File 'lib/sourcerer/asciidoc.rb', line 88 def self.extract_tagged_content path_to_tagged_adoc, ** = () = ([:tag], [:tags]) collect_tagged_content( path_to_tagged_adoc, tags: , comment_prefix: [:comment_prefix], skip_comments: [:skip_comments]) end |
.extract_yaml_front_matter(source_text) ⇒ Object
Compatibility alias.
392 393 394 |
# File 'lib/sourcerer/asciidoc.rb', line 392 def self.extract_yaml_front_matter source_text extract_yaml_frontmatter(source_text) end |
.extract_yaml_frontmatter(source_text) ⇒ Hash
Parse optional YAML front matter fenced with — at the top of source content.
364 365 366 |
# File 'lib/sourcerer/asciidoc.rb', line 364 def self.extract_yaml_frontmatter source_text Sourcerer::YamlFrontmatter.extract(source_text) end |
.generate_html(source_adoc, target_html, backend: 'asciidoctor-html5s', header_footer: false) ⇒ String
Generates HTML from an AsciiDoc source file.
177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/sourcerer/asciidoc.rb', line 177 def self.generate_html source_adoc, target_html, backend: 'asciidoctor-html5s', header_footer: false FileUtils.mkdir_p(File.dirname(target_html)) selected_backend = resolve_html_backend(backend) Asciidoctor.convert_file( source_adoc, backend: selected_backend, safe: :unsafe, header_footer: , to_file: target_html) selected_backend end |
.generate_manpage(source_adoc, target_manpage) ⇒ Object
Generates a manpage from an AsciiDoc source file.
160 161 162 163 164 165 166 167 168 |
# File 'lib/sourcerer/asciidoc.rb', line 160 def self.generate_manpage source_adoc, target_manpage FileUtils.mkdir_p(File.dirname(target_manpage)) Asciidoctor.convert_file( source_adoc, backend: 'manpage', safe: :unsafe, standalone: true, to_file: target_manpage) end |
.load_attributes(path) ⇒ Hash
Loads AsciiDoc attributes from a document header as a Hash.
47 48 49 50 |
# File 'lib/sourcerer/asciidoc.rb', line 47 def self.load_attributes path doc = Asciidoctor.load_file(path, safe: :unsafe) doc.attributes end |
.load_include(path_to_main_adoc, tag: nil, tags: [], leveloffset: nil) ⇒ String
Loads a snippet from an AsciiDoc file using an ‘include::` directive.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/sourcerer/asciidoc.rb', line 59 def self.load_include path_to_main_adoc, tag: nil, tags: [], leveloffset: nil opts = [] opts << "tag=#{tag}" if tag opts << "tags=#{.join(',')}" if .any? opts << "leveloffset=#{leveloffset}" if leveloffset snippet_doc = <<~ADOC include::#{path_to_main_adoc}[#{opts.join(', ')}] ADOC doc = Asciidoctor.load( snippet_doc, safe: :unsafe, base_dir: File.('.'), header_footer: false, attributes: { 'source-highlighter' => nil }) doc.blocks.map(&:content).join("\n") end |
.mark_down_grade(source_path, markdown_output_path = nil, markdown_converter:, **options) ⇒ Hash
Convert AsciiDoc source to Markdown through an interim HTML conversion.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/sourcerer/asciidoc.rb', line 203 def self.mark_down_grade source_path, markdown_output_path=nil, markdown_converter:, ** = () source_text = File.read(source_path) conversion_source_text = strip_yaml_frontmatter(source_text) selected_backend = resolve_html_backend([:backend]) document = load_document_for_markdown_grade( source_path, conversion_source_text, backend: selected_backend, header_footer: [:header_footer], attributes: [:attributes]) frontmatter = [:include_frontmatter] ? extract_frontmatter(source_text, document.attributes) : {} html_body = document.convert html_body = ensure_document_title(html_body, document.doctitle) html_with_frontmatter = [:include_frontmatter] ? prepend_frontmatter(html_body, frontmatter) : html_body if [:html_output_path] FileUtils.mkdir_p(File.dirname([:html_output_path])) File.write([:html_output_path], html_with_frontmatter) end frontmatter_block, html_for_markdown = split_frontmatter_block(html_with_frontmatter) # Build options for markdown converter, including table conversion mode = [:markdown_options].dup # Pass frontmatter table conversion setting through converter_options if .key?(:convert_tables_to_markdown) [:convert_tables_to_markdown] = [:convert_tables_to_markdown] end if [:convert_tables_to_markdown].nil? && frontmatter.key?('tables-to-markdown') [:convert_tables_to_markdown] = frontmatter['tables-to-markdown'] end markdown_body = markdown_converter.call(html_for_markdown, ) markdown = frontmatter_block ? "#{frontmatter_block}\n\n#{markdown_body}" : markdown_body if markdown_output_path FileUtils.mkdir_p(File.dirname(markdown_output_path)) File.write(markdown_output_path, markdown) end { markdown: markdown, frontmatter: frontmatter, requested_backend: [:backend], used_backend: selected_backend } end |
.prepend_front_matter(content, frontmatter) ⇒ Object
Compatibility alias.
382 383 384 |
# File 'lib/sourcerer/asciidoc.rb', line 382 def self.prepend_front_matter content, frontmatter prepend_frontmatter(content, frontmatter) end |
.prepend_frontmatter(content, frontmatter) ⇒ String
Prepend front matter block to content.
301 302 303 304 305 306 |
# File 'lib/sourcerer/asciidoc.rb', line 301 def self.prepend_frontmatter content, frontmatter block = compose_frontmatter_block(frontmatter) return content unless block "#{block}\n\n#{content}" end |
.split_front_matter(content) ⇒ Object
Compatibility alias.
387 388 389 |
# File 'lib/sourcerer/asciidoc.rb', line 387 def self.split_front_matter content split_frontmatter_block(content) end |
.split_frontmatter_block(content) ⇒ Array<(String, String)>
Split front matter block from content if present.
312 313 314 315 316 317 318 319 |
# File 'lib/sourcerer/asciidoc.rb', line 312 def self.split_frontmatter_block content match = content.match(YAML_FRONTMATTER_REGEXP) return [nil, content] unless match full_block = "#{match[1]}#{match[2]}".strip remainder = content.sub(YAML_FRONTMATTER_REGEXP, '').sub(/\A\n+/, '') [full_block, remainder] end |
.strip_yaml_front_matter(source_text) ⇒ Object
Compatibility alias.
397 398 399 |
# File 'lib/sourcerer/asciidoc.rb', line 397 def self.strip_yaml_front_matter source_text strip_yaml_frontmatter(source_text) end |
.strip_yaml_frontmatter(source_text) ⇒ String
Remove leading YAML front matter fence block from AsciiDoc source.
372 373 374 |
# File 'lib/sourcerer/asciidoc.rb', line 372 def self.strip_yaml_frontmatter source_text Sourcerer::YamlFrontmatter.strip(source_text) end |