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, user_only: false) ⇒ 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: nil, **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.
384 385 386 |
# File 'lib/sourcerer/asciidoc.rb', line 384 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.
293 294 295 296 297 298 299 300 301 |
# File 'lib/sourcerer/asciidoc.rb', line 293 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.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
# File 'lib/sourcerer/asciidoc.rb', line 439 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.
283 284 285 286 287 |
# File 'lib/sourcerer/asciidoc.rb', line 283 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.
332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/sourcerer/asciidoc.rb', line 332 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.
92 93 94 95 96 97 98 99 100 |
# File 'lib/sourcerer/asciidoc.rb', line 92 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.
399 400 401 |
# File 'lib/sourcerer/asciidoc.rb', line 399 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.
371 372 373 |
# File 'lib/sourcerer/asciidoc.rb', line 371 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.
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/sourcerer/asciidoc.rb', line 181 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.
164 165 166 167 168 169 170 171 172 |
# File 'lib/sourcerer/asciidoc.rb', line 164 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, user_only: false) ⇒ Hash
Loads AsciiDoc attributes from a document header as a Hash.
49 50 51 52 53 54 |
# File 'lib/sourcerer/asciidoc.rb', line 49 def self.load_attributes path, user_only: false doc = Asciidoctor.load_file(path, safe: :unsafe) return AttributesFilter.user_attributes(doc) if user_only 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.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sourcerer/asciidoc.rb', line 63 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: nil, **options) ⇒ Hash
Convert AsciiDoc source to Markdown through an interim HTML conversion.
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 252 253 254 255 256 257 258 |
# File 'lib/sourcerer/asciidoc.rb', line 208 def self.mark_down_grade source_path, markdown_output_path=nil, markdown_converter: nil, ** = () markdown_converter ||= ->(html, opts) { Sourcerer::MarkDownGrade.convert_html(html, opts || {}) } 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.
389 390 391 |
# File 'lib/sourcerer/asciidoc.rb', line 389 def self.prepend_front_matter content, frontmatter prepend_frontmatter(content, frontmatter) end |
.prepend_frontmatter(content, frontmatter) ⇒ String
Prepend front matter block to content.
308 309 310 311 312 313 |
# File 'lib/sourcerer/asciidoc.rb', line 308 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.
394 395 396 |
# File 'lib/sourcerer/asciidoc.rb', line 394 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.
319 320 321 322 323 324 325 326 |
# File 'lib/sourcerer/asciidoc.rb', line 319 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.
404 405 406 |
# File 'lib/sourcerer/asciidoc.rb', line 404 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.
379 380 381 |
# File 'lib/sourcerer/asciidoc.rb', line 379 def self.strip_yaml_frontmatter source_text Sourcerer::YamlFrontmatter.strip(source_text) end |