asciisourcerer 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +22 -21
- data/lib/sourcerer/asciidoc.rb +42 -7
- data/lib/sourcerer/jekyll/bootstrapper.rb +1 -1
- data/lib/sourcerer/mark_down_grade.rb +147 -12
- data/lib/sourcerer/rendering.rb +1 -1
- data/lib/sourcerer/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e85e0efc612880e0a0e62bef37b836015007d18074a74f890edc9db56791772c
|
|
4
|
+
data.tar.gz: 3fc912495515ae3b1a42016e3b5de6fd2a136533e53f981d42a14b5860a5038f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2f3ed3a3b52950034965fa3edde7bf7159c7a907885e90b74e1a1e623b7996b9d7e4f03b72bf9f4cc7bfd8dc8cb7179deed2f38e8cf3adca04b5e34f0753bde
|
|
7
|
+
data.tar.gz: b859463483fb45eb5d84d326301b4c44adf2716f719cfdb77ecd4293d92dc23b3e9c8dc4128129ec84287d08d94761a250d9b629d451ac7b9fb77eddbbcbb08b
|
data/README.adoc
CHANGED
|
@@ -37,12 +37,13 @@ endif::[]
|
|
|
37
37
|
:this_prod_name: {this_proj_name}
|
|
38
38
|
// end::universal-settings[]
|
|
39
39
|
:this_prod_vrsn_major: 0
|
|
40
|
-
:this_prod_vrsn_minor:
|
|
40
|
+
:this_prod_vrsn_minor: 4
|
|
41
41
|
:this_prod_vrsn_majmin: {this_prod_vrsn_major}.{this_prod_vrsn_minor}
|
|
42
|
-
:this_prod_vrsn_patch:
|
|
42
|
+
:this_prod_vrsn_patch: 0
|
|
43
43
|
:this_prod_vrsn: {this_prod_vrsn_majmin}.{this_prod_vrsn_patch}
|
|
44
|
-
:next_prod_vrsn: 0.
|
|
44
|
+
:next_prod_vrsn: 0.5.0
|
|
45
45
|
// end::global-settings[]
|
|
46
|
+
// end::ai-prompt[]
|
|
46
47
|
:toc: macro
|
|
47
48
|
:toclevels: 4
|
|
48
49
|
:this_prod_repo_files_path: {this_proj_src_www_url}/tree/main
|
|
@@ -89,7 +90,7 @@ Initialize a Jekyll-routed Liquid runtime with DocOps Lab filters and tags, so J
|
|
|
89
90
|
See <<templating-liquid-runtime>>.
|
|
90
91
|
|
|
91
92
|
Build-time generation::
|
|
92
|
-
Generate
|
|
93
|
+
Generate pre-build artifacts (attributes, snippets, regions) for downstream builds and runtime access.
|
|
93
94
|
See <<pipelines>>.
|
|
94
95
|
|
|
95
96
|
AsciiDoc-to-manpage conversion::
|
|
@@ -144,7 +145,7 @@ The most common workflows are summarized below.
|
|
|
144
145
|
Basic render flow::
|
|
145
146
|
Load YAML data, optionally enrich it with AsciiDoc attributes, render a template, and write output to a file.
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
Pre-build flow::
|
|
148
149
|
Extract attributes and tagged content from AsciiDoc into artifacts that are loaded at runtime.
|
|
149
150
|
|
|
150
151
|
Converter flow::
|
|
@@ -329,7 +330,7 @@ NOTE: Only blocks marked `_skip` are not carried over.
|
|
|
329
330
|
sync::
|
|
330
331
|
Ongoing operation that scans for canonical blocks, replaces their content with the prime version (after optional Liquid rendering), and leaves everything else verbatim.
|
|
331
332
|
|
|
332
|
-
dry_run: true
|
|
333
|
+
`dry_run: true`::
|
|
333
334
|
Pass `dry_run: true` to either operation to compute the result without writing any file.
|
|
334
335
|
The `result.diff` file contains the rendered content (`init`) or a unified diff (`sync`).
|
|
335
336
|
|
|
@@ -394,10 +395,10 @@ If you are building a Jekyll-compatible templating pipeline, prefer Liquid.
|
|
|
394
395
|
If you want a low-friction Ruby template for internal tooling, ERB is available.
|
|
395
396
|
|
|
396
397
|
[[pipelines]]
|
|
397
|
-
===
|
|
398
|
+
=== Pre-build and Rendering Pipelines
|
|
398
399
|
|
|
399
|
-
Sourcerer's rendering pipeline is optimized for build tooling and
|
|
400
|
-
A typical
|
|
400
|
+
Sourcerer's rendering pipeline is optimized for build tooling and pre-build steps.
|
|
401
|
+
A typical pre-build might load attributes from `README.adoc`, extract tagged snippets into `build/snippets/`, and render YAML plus Liquid templates into `build/docs/`.
|
|
401
402
|
|
|
402
403
|
The API is intentionally small.
|
|
403
404
|
Sourcerer focuses on producing artifacts, not managing a broader build lifecycle.
|
|
@@ -518,18 +519,18 @@ Sourcerer::Util::ListAmend.apply(default_list, custom_list, normalize: nil) -> A
|
|
|
518
519
|
----
|
|
519
520
|
|
|
520
521
|
Behavior::
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
522
|
+
`nil` / empty custom:::
|
|
523
|
+
Returns `default_list` (stringified) unchanged.
|
|
524
|
+
Fixed-list mode:::
|
|
525
|
+
If `custom_list` contains *no* tokens starting with `+` or `-`, it fully replaces `default_list`.
|
|
526
|
+
Amendment mode:::
|
|
527
|
+
If `custom_list` contains *any* `+`/`-` token:
|
|
528
|
+
`-slug` removes `slug` from the working set (or no-op if absent). +
|
|
529
|
+
`+slug` adds `slug` if not already present. +
|
|
530
|
+
bare `slug` is treated as `+slug`.
|
|
530
531
|
|
|
531
532
|
`normalize` (optional)::
|
|
532
|
-
|
|
533
|
+
A callable used to compare items during de-duplication and removal, for example `->(s) { s.downcase }`.
|
|
533
534
|
|
|
534
535
|
.Examples
|
|
535
536
|
[source,ruby]
|
|
@@ -573,7 +574,7 @@ result = Sourcerer::Util::Pathifier.match(input, recursive: true, include_dirs:
|
|
|
573
574
|
Classification rules::
|
|
574
575
|
`:file`::: `File.file?(input)` is true.
|
|
575
576
|
`:dir`::: `File.directory?(input)` is true.
|
|
576
|
-
`:glob`::: Input contains glob
|
|
577
|
+
`:glob`::: Input contains glob meta-characters (`* ? [ ] { }`).
|
|
577
578
|
`:missing`::: None of the above.
|
|
578
579
|
|
|
579
580
|
Options::
|
|
@@ -621,7 +622,7 @@ Sourcerer provides it with primitives such as YAML loading, templating, and Liqu
|
|
|
621
622
|
SchemaGraphy depends on AsciiSourcerer for these primitives, not the other way around.
|
|
622
623
|
|
|
623
624
|
https://github.com/DocOps/releasehx[ReleaseHx]::
|
|
624
|
-
The ReleaseHx API and `rhx` CLI uses Sourcerer for generating source files during a
|
|
625
|
+
The ReleaseHx API and `rhx` CLI uses Sourcerer for generating source files during a pre-build stage, and at runtime for YAML ingest and template rendering.
|
|
625
626
|
|
|
626
627
|
LiquiDoc::
|
|
627
628
|
Secondary to SchemaGraphy, the scriptable template-rendering build utility LiquiDoc will use SchemaGraphy and AsciiSourcerer at runtime.
|
data/lib/sourcerer/asciidoc.rb
CHANGED
|
@@ -115,7 +115,7 @@ module Sourcerer
|
|
|
115
115
|
|
|
116
116
|
tags = [tag] if tag
|
|
117
117
|
raise ArgumentError, 'at least one tag must be specified' if tags.empty?
|
|
118
|
-
raise ArgumentError, 'tags must all be strings' unless tags.all?
|
|
118
|
+
raise ArgumentError, 'tags must all be strings' unless tags.all?(String)
|
|
119
119
|
|
|
120
120
|
tags
|
|
121
121
|
end
|
|
@@ -198,6 +198,7 @@ module Sourcerer
|
|
|
198
198
|
# @param include_frontmatter [Boolean] Whether to prepend markdown YAML front matter.
|
|
199
199
|
# @param markdown_options [Hash] Options passed to markdown converter.
|
|
200
200
|
# @param markdown_converter [#call] Callable that accepts `(html, markdown_options)`.
|
|
201
|
+
# @param convert_tables_to_markdown [Boolean] Convert all tables to markdown UNLESS they have .no-markdown class.
|
|
201
202
|
# @return [Hash] Conversion result containing markdown, frontmatter, and backend info.
|
|
202
203
|
def self.mark_down_grade source_path, markdown_output_path=nil, markdown_converter:, **options
|
|
203
204
|
options = normalize_mark_down_grade_options(options)
|
|
@@ -223,7 +224,17 @@ module Sourcerer
|
|
|
223
224
|
end
|
|
224
225
|
|
|
225
226
|
frontmatter_block, html_for_markdown = split_frontmatter_block(html_with_frontmatter)
|
|
226
|
-
|
|
227
|
+
# Build options for markdown converter, including table conversion mode
|
|
228
|
+
converter_options = options[:markdown_options].dup
|
|
229
|
+
# Pass frontmatter table conversion setting through converter_options
|
|
230
|
+
if options.key?(:convert_tables_to_markdown)
|
|
231
|
+
converter_options[:convert_tables_to_markdown] =
|
|
232
|
+
options[:convert_tables_to_markdown]
|
|
233
|
+
end
|
|
234
|
+
if converter_options[:convert_tables_to_markdown].nil? && frontmatter.key?('tables-to-markdown')
|
|
235
|
+
converter_options[:convert_tables_to_markdown] = frontmatter['tables-to-markdown']
|
|
236
|
+
end
|
|
237
|
+
markdown_body = markdown_converter.call(html_for_markdown, converter_options)
|
|
227
238
|
markdown = frontmatter_block ? "#{frontmatter_block}\n\n#{markdown_body}" : markdown_body
|
|
228
239
|
|
|
229
240
|
if markdown_output_path
|
|
@@ -241,7 +252,8 @@ module Sourcerer
|
|
|
241
252
|
|
|
242
253
|
# @api private
|
|
243
254
|
def self.normalize_mark_down_grade_options options
|
|
244
|
-
supported_option_keys = %i[html_output_path backend header_footer include_frontmatter markdown_options attributes
|
|
255
|
+
supported_option_keys = %i[html_output_path backend header_footer include_frontmatter markdown_options attributes
|
|
256
|
+
convert_tables_to_markdown]
|
|
245
257
|
unknown_option_keys = options.keys - supported_option_keys
|
|
246
258
|
raise ArgumentError, "unknown option(s): #{unknown_option_keys.join(', ')}" unless unknown_option_keys.empty?
|
|
247
259
|
|
|
@@ -251,7 +263,8 @@ module Sourcerer
|
|
|
251
263
|
header_footer: options.fetch(:header_footer, false),
|
|
252
264
|
include_frontmatter: options.fetch(:include_frontmatter, true),
|
|
253
265
|
markdown_options: options.fetch(:markdown_options, { github_flavored: true }),
|
|
254
|
-
attributes: options.fetch(:attributes, {})
|
|
266
|
+
attributes: options.fetch(:attributes, {}),
|
|
267
|
+
convert_tables_to_markdown: options[:convert_tables_to_markdown]
|
|
255
268
|
}
|
|
256
269
|
end
|
|
257
270
|
|
|
@@ -273,7 +286,7 @@ module Sourcerer
|
|
|
273
286
|
def self.compose_frontmatter_block frontmatter
|
|
274
287
|
return nil if frontmatter.nil? || frontmatter.empty?
|
|
275
288
|
|
|
276
|
-
yaml_payload =
|
|
289
|
+
yaml_payload = Psych.dump(frontmatter, nil, { line_width: -1 })
|
|
277
290
|
yaml_payload = yaml_payload.sub(/\A---\s*\n/, '')
|
|
278
291
|
yaml_payload = yaml_payload.sub(/\n\.\.\.\s*\z/, "\n")
|
|
279
292
|
|
|
@@ -317,12 +330,33 @@ module Sourcerer
|
|
|
317
330
|
next unless key.start_with?(prefix)
|
|
318
331
|
|
|
319
332
|
normalized_key = key.sub(/\A#{Regexp.escape(prefix)}/, '')
|
|
320
|
-
attributes[normalized_key] = value
|
|
333
|
+
attributes[normalized_key] = coerce_page_attribute_value(value)
|
|
321
334
|
end
|
|
322
335
|
|
|
323
336
|
attributes
|
|
324
337
|
end
|
|
325
338
|
|
|
339
|
+
# Coerce page attribute values to appropriate types (boolean, string, etc).
|
|
340
|
+
# Preserves boolean values and converts string representations to boolean where appropriate.
|
|
341
|
+
#
|
|
342
|
+
# @param value [Object] The attribute value from document.attributes.
|
|
343
|
+
# @return [Object] The coerced value.
|
|
344
|
+
def self.coerce_page_attribute_value value
|
|
345
|
+
# Preserve actual booleans
|
|
346
|
+
return value if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
347
|
+
|
|
348
|
+
# Convert string representations of booleans
|
|
349
|
+
string_val = value.to_s.downcase.strip
|
|
350
|
+
case string_val
|
|
351
|
+
when 'true', '1', 'yes', 'on'
|
|
352
|
+
true
|
|
353
|
+
when 'false', '0', 'no', 'off'
|
|
354
|
+
false
|
|
355
|
+
else
|
|
356
|
+
value.to_s
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
326
360
|
# Parse optional YAML front matter fenced with --- at the top of source content.
|
|
327
361
|
#
|
|
328
362
|
# @param source_text [String]
|
|
@@ -476,7 +510,8 @@ module Sourcerer
|
|
|
476
510
|
:normalize_extract_tagged_content_options,
|
|
477
511
|
:normalize_extract_tags,
|
|
478
512
|
:collect_tagged_content,
|
|
479
|
-
:normalize_mark_down_grade_options
|
|
513
|
+
:normalize_mark_down_grade_options,
|
|
514
|
+
:coerce_page_attribute_value
|
|
480
515
|
|
|
481
516
|
# Utilities for filtering and partitioning Asciidoctor document attributes.
|
|
482
517
|
#
|
|
@@ -21,7 +21,8 @@ module Sourcerer
|
|
|
21
21
|
|
|
22
22
|
@config = {
|
|
23
23
|
preserve_heading_ids: true,
|
|
24
|
-
strip_internal_links: false
|
|
24
|
+
strip_internal_links: false,
|
|
25
|
+
convert_tables_to_markdown: false
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
class << self
|
|
@@ -32,6 +33,7 @@ module Sourcerer
|
|
|
32
33
|
# Options:
|
|
33
34
|
# preserve_heading_ids: (default: true) Include <a id="..."> anchors before headings
|
|
34
35
|
# strip_internal_links: (default: false) Remove href from internal anchor links, keeping only text
|
|
36
|
+
# convert_tables_to_markdown: (default: false) Convert all tables to markdown UNLESS they have .no-markdown class
|
|
35
37
|
def self.bootstrap! options={}
|
|
36
38
|
@config.merge!(options)
|
|
37
39
|
|
|
@@ -421,9 +423,49 @@ module Sourcerer
|
|
|
421
423
|
end
|
|
422
424
|
|
|
423
425
|
# Passthrough Tables: preserve HTML tables as-is (except admonition internals handled elsewhere).
|
|
426
|
+
# Tables with "to-markdown" class are converted via ReverseMarkdown instead.
|
|
427
|
+
# Supports both html5 (class on <table>) and html5s (class on parent <div class="table-block">).
|
|
428
|
+
# Per-table classes (.to-markdown, .no-markdown) override the global conversion mode.
|
|
424
429
|
class TablePassthrough < ReverseMarkdown::Converters::Base
|
|
425
|
-
def
|
|
426
|
-
|
|
430
|
+
def initialize
|
|
431
|
+
super
|
|
432
|
+
@markdown_converter = ReverseMarkdown::Converters::Table.new
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def convert node, state={}
|
|
436
|
+
global_mode = Thread.current[:sourcerer_table_conversion_mode] || false
|
|
437
|
+
|
|
438
|
+
# Check for per-table classes (on table or parent wrapper)
|
|
439
|
+
has_to_markdown = check_class_on_node(node, 'to-markdown')
|
|
440
|
+
has_no_markdown = check_class_on_node(node, 'no-markdown')
|
|
441
|
+
|
|
442
|
+
# Also check parent <div class="table-block"> wrapper (html5s backend)
|
|
443
|
+
parent_div = node.parent
|
|
444
|
+
if parent_div && parent_div.name == 'div'
|
|
445
|
+
has_to_markdown ||= check_class_on_node(parent_div, 'to-markdown')
|
|
446
|
+
has_no_markdown ||= check_class_on_node(parent_div, 'no-markdown')
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Determine whether to convert (per-table classes override global mode)
|
|
450
|
+
should_convert = if has_no_markdown
|
|
451
|
+
false # .no-markdown always prevents conversion
|
|
452
|
+
elsif has_to_markdown
|
|
453
|
+
true # .to-markdown always forces conversion
|
|
454
|
+
else
|
|
455
|
+
global_mode # Use global table conversion mode
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
if should_convert
|
|
459
|
+
@markdown_converter.convert(node, state)
|
|
460
|
+
else
|
|
461
|
+
"#{node.to_html}\n"
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
private
|
|
466
|
+
|
|
467
|
+
def check_class_on_node node, class_name
|
|
468
|
+
node['class'].to_s.split.include?(class_name)
|
|
427
469
|
end
|
|
428
470
|
end
|
|
429
471
|
|
|
@@ -606,18 +648,28 @@ module Sourcerer
|
|
|
606
648
|
end
|
|
607
649
|
|
|
608
650
|
# Convert HTML into Markdown with MarkDownGrade converters.
|
|
651
|
+
# Options include:
|
|
652
|
+
# convert_tables_to_markdown: Override global config for table conversion (true/false)
|
|
609
653
|
def self.convert_html html, options={}
|
|
610
654
|
bootstrap! unless @setup_complete
|
|
611
655
|
@setup_complete = true
|
|
612
656
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
657
|
+
# Determine effective table conversion mode
|
|
658
|
+
effective_mode = determine_table_conversion_mode(html.to_s, options)
|
|
659
|
+
Thread.current[:sourcerer_table_conversion_mode] = effective_mode
|
|
660
|
+
|
|
661
|
+
begin
|
|
662
|
+
normalized_html = normalize_html_for_markdown(html.to_s)
|
|
663
|
+
markdown = ReverseMarkdown.convert(normalized_html, options)
|
|
664
|
+
markdown = markdown.gsub(/(\*\*[^\n]+\*\* \n)\n+(?=\S)/, '\\1')
|
|
665
|
+
markdown = markdown.gsub(/<figcaption>\s+/, '<figcaption>')
|
|
666
|
+
markdown = markdown.gsub(%r{\s+</figcaption>}, '</figcaption>')
|
|
667
|
+
|
|
668
|
+
markdown.gsub('<!--CHECKBOX_CHECKED-->', '- [x]')
|
|
669
|
+
.gsub('<!--CHECKBOX_UNCHECKED-->', '- [ ]')
|
|
670
|
+
ensure
|
|
671
|
+
Thread.current[:sourcerer_table_conversion_mode] = nil
|
|
672
|
+
end
|
|
621
673
|
end
|
|
622
674
|
|
|
623
675
|
def self.convert html, options={}
|
|
@@ -629,6 +681,7 @@ module Sourcerer
|
|
|
629
681
|
fragment = Nokogiri::HTML::DocumentFragment.parse(html_body)
|
|
630
682
|
normalize_abstract_nodes!(fragment)
|
|
631
683
|
normalize_footnote_nodes!(fragment)
|
|
684
|
+
clean_html5s_tables!(fragment)
|
|
632
685
|
fragment.to_html
|
|
633
686
|
end
|
|
634
687
|
|
|
@@ -682,10 +735,92 @@ module Sourcerer
|
|
|
682
735
|
raw_id.empty? ? nil : raw_id
|
|
683
736
|
end
|
|
684
737
|
|
|
738
|
+
# Clean HTML5s table artifacts: remove colgroup elements and class/style attributes from cells.
|
|
739
|
+
# This normalizes tables generated by the asciidoctor-html5s backend for safer Markdown conversion.
|
|
740
|
+
#
|
|
741
|
+
# @param fragment [Nokogiri::HTML::DocumentFragment] The HTML fragment to clean.
|
|
742
|
+
# @return [void] Modifies fragment in place.
|
|
743
|
+
def self.clean_html5s_tables! fragment
|
|
744
|
+
# Remove all colgroup elements
|
|
745
|
+
fragment.css('colgroup').each(&:remove)
|
|
746
|
+
|
|
747
|
+
# Remove class and style attributes from table cells and rows
|
|
748
|
+
fragment.css('td, th, tr').each do |cell|
|
|
749
|
+
cell.delete('class')
|
|
750
|
+
cell.delete('style')
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
# Determine the effective table conversion mode from options, frontmatter, or global config.
|
|
755
|
+
#
|
|
756
|
+
# Precedence:
|
|
757
|
+
# 1. Explicit convert_tables_to_markdown option in parameters
|
|
758
|
+
# 2. Document-level setting from frontmatter (YAML) or page attributes (AsciiDoc)
|
|
759
|
+
# 3. Global config setting
|
|
760
|
+
#
|
|
761
|
+
# @param html_body [String] The HTML document body.
|
|
762
|
+
# @param options [Hash] Optional override.
|
|
763
|
+
# @return [Boolean] Whether tables should be converted to markdown by default.
|
|
764
|
+
def self.determine_table_conversion_mode html_body, options
|
|
765
|
+
# Explicit option takes precedence
|
|
766
|
+
return options[:convert_tables_to_markdown] if options.key?(:convert_tables_to_markdown)
|
|
767
|
+
|
|
768
|
+
# Extract from document metadata
|
|
769
|
+
document_mode = extract_table_conversion_mode_from_html(html_body)
|
|
770
|
+
return document_mode unless document_mode.nil?
|
|
771
|
+
|
|
772
|
+
# Fall back to global config
|
|
773
|
+
@config[:convert_tables_to_markdown]
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
# Extract table conversion mode from document frontmatter or page attributes.
|
|
777
|
+
#
|
|
778
|
+
# Checks for:
|
|
779
|
+
# - YAML frontmatter key: tables-to-markdown
|
|
780
|
+
# - AsciiDoc page attribute: page-tables-to-markdown
|
|
781
|
+
#
|
|
782
|
+
# @param html_body [String] The HTML document body.
|
|
783
|
+
# @return [Boolean, nil] The setting if found, nil otherwise.
|
|
784
|
+
def self.extract_table_conversion_mode_from_html html_body
|
|
785
|
+
# Try to extract YAML frontmatter
|
|
786
|
+
frontmatter = Sourcerer::YamlFrontmatter.extract(html_body)
|
|
787
|
+
return string_to_boolean(frontmatter['tables-to-markdown']) if frontmatter.key?('tables-to-markdown')
|
|
788
|
+
|
|
789
|
+
# Try to find page-tables-to-markdown in HTML comments or metadata
|
|
790
|
+
# (This would be set by AsciiDoc's page attributes)
|
|
791
|
+
if html_body.include?('page-tables-to-markdown')
|
|
792
|
+
# Look for data attributes or comments that might encode this
|
|
793
|
+
if html_body.match?(/page-tables-to-markdown['"]?\s*[:=]\s*['"]*true/i)
|
|
794
|
+
return true
|
|
795
|
+
elsif html_body.match?(/page-tables-to-markdown['"]?\s*[:=]\s*['"]*false/i)
|
|
796
|
+
return false
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
nil
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
# Convert a string representation to a boolean value.
|
|
804
|
+
#
|
|
805
|
+
# @param value [String, Boolean, nil] The value to convert.
|
|
806
|
+
# @return [Boolean, nil] Boolean if value is truthy string, nil if unclear.
|
|
807
|
+
def self.string_to_boolean value
|
|
808
|
+
case value.to_s.downcase.strip
|
|
809
|
+
when 'true', '1', 'yes', 'on'
|
|
810
|
+
true
|
|
811
|
+
when 'false', '0', 'no', 'off', ''
|
|
812
|
+
false
|
|
813
|
+
end
|
|
814
|
+
end
|
|
815
|
+
|
|
685
816
|
private_class_method :normalize_html_for_markdown,
|
|
686
817
|
:normalize_abstract_nodes!,
|
|
687
818
|
:normalize_footnote_nodes!,
|
|
688
|
-
:canonical_footnote_anchor_id
|
|
819
|
+
:canonical_footnote_anchor_id,
|
|
820
|
+
:clean_html5s_tables!,
|
|
821
|
+
:determine_table_conversion_mode,
|
|
822
|
+
:extract_table_conversion_mode_from_html,
|
|
823
|
+
:string_to_boolean
|
|
689
824
|
end # module MarkDownGrade
|
|
690
825
|
end # module Sourcerer
|
|
691
826
|
|
data/lib/sourcerer/rendering.rb
CHANGED
|
@@ -86,7 +86,7 @@ module Sourcerer
|
|
|
86
86
|
# @return [void]
|
|
87
87
|
def self.render_with_converter render_entry
|
|
88
88
|
data_file = render_entry[:data]
|
|
89
|
-
out_file
|
|
89
|
+
out_file = render_entry[:out]
|
|
90
90
|
raise ArgumentError, 'render entry missing :data' unless data_file
|
|
91
91
|
raise ArgumentError, 'render entry missing :out' unless out_file
|
|
92
92
|
|
data/lib/sourcerer/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciisourcerer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- DocOps Lab
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: asciidoctor
|
|
@@ -153,7 +152,6 @@ licenses:
|
|
|
153
152
|
metadata:
|
|
154
153
|
allowed_push_host: https://rubygems.org
|
|
155
154
|
rubygems_mfa_required: 'true'
|
|
156
|
-
post_install_message:
|
|
157
155
|
rdoc_options: []
|
|
158
156
|
require_paths:
|
|
159
157
|
- lib
|
|
@@ -168,8 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
168
166
|
- !ruby/object:Gem::Version
|
|
169
167
|
version: '0'
|
|
170
168
|
requirements: []
|
|
171
|
-
rubygems_version: 3.
|
|
172
|
-
signing_key:
|
|
169
|
+
rubygems_version: 3.7.2
|
|
173
170
|
specification_version: 4
|
|
174
171
|
summary: APIs for specialized handling of AsciiDoc, YAML, and Liquid documents.
|
|
175
172
|
test_files: []
|