coradoc-markdown 1.0.2 → 1.0.3

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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/markdown/model/admonition.rb +35 -0
  3. data/lib/coradoc/markdown/model/comment.rb +14 -0
  4. data/lib/coradoc/markdown/model/definition_term.rb +16 -6
  5. data/lib/coradoc/markdown/model/document.rb +9 -0
  6. data/lib/coradoc/markdown/model/example_block.rb +26 -0
  7. data/lib/coradoc/markdown/model/hard_line_break.rb +21 -0
  8. data/lib/coradoc/markdown/model/horizontal_rule.rb +1 -6
  9. data/lib/coradoc/markdown/model/list_item.rb +1 -1
  10. data/lib/coradoc/markdown/model/literal.rb +21 -0
  11. data/lib/coradoc/markdown/model/open_block.rb +22 -0
  12. data/lib/coradoc/markdown/model/paragraph.rb +2 -2
  13. data/lib/coradoc/markdown/model/pass.rb +21 -0
  14. data/lib/coradoc/markdown/model/sidebar.rb +22 -0
  15. data/lib/coradoc/markdown/model/verse.rb +27 -0
  16. data/lib/coradoc/markdown/parser/block_parser.rb +1 -1
  17. data/lib/coradoc/markdown/parser/frontmatter_parser.rb +23 -0
  18. data/lib/coradoc/markdown/serializer/builder.rb +57 -0
  19. data/lib/coradoc/markdown/serializer/config.rb +77 -0
  20. data/lib/coradoc/markdown/serializer/context.rb +66 -0
  21. data/lib/coradoc/markdown/serializer/element_serializer.rb +46 -0
  22. data/lib/coradoc/markdown/serializer/flavor.rb +82 -0
  23. data/lib/coradoc/markdown/serializer/registrations.rb +111 -0
  24. data/lib/coradoc/markdown/serializer/registry.rb +62 -0
  25. data/lib/coradoc/markdown/serializer/runner.rb +84 -0
  26. data/lib/coradoc/markdown/serializer/serializers/abbreviation.rb +19 -0
  27. data/lib/coradoc/markdown/serializer/serializers/admonition.rb +20 -0
  28. data/lib/coradoc/markdown/serializer/serializers/attribute_list.rb +25 -0
  29. data/lib/coradoc/markdown/serializer/serializers/blockquote.rb +19 -0
  30. data/lib/coradoc/markdown/serializer/serializers/code.rb +19 -0
  31. data/lib/coradoc/markdown/serializer/serializers/code_block.rb +19 -0
  32. data/lib/coradoc/markdown/serializer/serializers/comment.rb +31 -0
  33. data/lib/coradoc/markdown/serializer/serializers/cross_reference.rb +19 -0
  34. data/lib/coradoc/markdown/serializer/serializers/definition_list.rb +20 -0
  35. data/lib/coradoc/markdown/serializer/serializers/document.rb +22 -0
  36. data/lib/coradoc/markdown/serializer/serializers/emphasis.rb +19 -0
  37. data/lib/coradoc/markdown/serializer/serializers/example_block.rb +40 -0
  38. data/lib/coradoc/markdown/serializer/serializers/extension.rb +30 -0
  39. data/lib/coradoc/markdown/serializer/serializers/footnote.rb +20 -0
  40. data/lib/coradoc/markdown/serializer/serializers/footnote_reference.rb +19 -0
  41. data/lib/coradoc/markdown/serializer/serializers/hard_line_break.rb +22 -0
  42. data/lib/coradoc/markdown/serializer/serializers/heading.rb +19 -0
  43. data/lib/coradoc/markdown/serializer/serializers/highlight.rb +19 -0
  44. data/lib/coradoc/markdown/serializer/serializers/horizontal_rule.rb +19 -0
  45. data/lib/coradoc/markdown/serializer/serializers/image.rb +19 -0
  46. data/lib/coradoc/markdown/serializer/serializers/link.rb +29 -0
  47. data/lib/coradoc/markdown/serializer/serializers/list.rb +45 -0
  48. data/lib/coradoc/markdown/serializer/serializers/literal.rb +21 -0
  49. data/lib/coradoc/markdown/serializer/serializers/math.rb +23 -0
  50. data/lib/coradoc/markdown/serializer/serializers/open_block.rb +38 -0
  51. data/lib/coradoc/markdown/serializer/serializers/paragraph.rb +23 -0
  52. data/lib/coradoc/markdown/serializer/serializers/pass.rb +21 -0
  53. data/lib/coradoc/markdown/serializer/serializers/sidebar.rb +20 -0
  54. data/lib/coradoc/markdown/serializer/serializers/strikethrough.rb +19 -0
  55. data/lib/coradoc/markdown/serializer/serializers/strong.rb +19 -0
  56. data/lib/coradoc/markdown/serializer/serializers/subscript.rb +19 -0
  57. data/lib/coradoc/markdown/serializer/serializers/superscript.rb +19 -0
  58. data/lib/coradoc/markdown/serializer/serializers/table.rb +37 -0
  59. data/lib/coradoc/markdown/serializer/serializers/underline.rb +19 -0
  60. data/lib/coradoc/markdown/serializer/serializers/verse.rb +31 -0
  61. data/lib/coradoc/markdown/serializer/strategies/admonition/base.rb +30 -0
  62. data/lib/coradoc/markdown/serializer/strategies/admonition/container.rb +34 -0
  63. data/lib/coradoc/markdown/serializer/strategies/admonition/gfm_alert.rb +28 -0
  64. data/lib/coradoc/markdown/serializer/strategies/admonition/github.rb +29 -0
  65. data/lib/coradoc/markdown/serializer/strategies/admonition/html.rb +25 -0
  66. data/lib/coradoc/markdown/serializer/strategies/admonition/registry.rb +50 -0
  67. data/lib/coradoc/markdown/serializer/strategies/autolink/angle.rb +35 -0
  68. data/lib/coradoc/markdown/serializer/strategies/autolink/bare.rb +23 -0
  69. data/lib/coradoc/markdown/serializer/strategies/autolink/base.rb +33 -0
  70. data/lib/coradoc/markdown/serializer/strategies/autolink/none.rb +27 -0
  71. data/lib/coradoc/markdown/serializer/strategies/autolink/registry.rb +58 -0
  72. data/lib/coradoc/markdown/serializer/strategies/definition_list/base.rb +37 -0
  73. data/lib/coradoc/markdown/serializer/strategies/definition_list/flat.rb +48 -0
  74. data/lib/coradoc/markdown/serializer/strategies/definition_list/nested_html.rb +54 -0
  75. data/lib/coradoc/markdown/serializer/strategies/definition_list/registry.rb +37 -0
  76. data/lib/coradoc/markdown/serializer.rb +29 -243
  77. data/lib/coradoc/markdown/toc_generator.rb +2 -2
  78. data/lib/coradoc/markdown/transform/block_transformer.rb +163 -0
  79. data/lib/coradoc/markdown/transform/from_core_model.rb +187 -28
  80. data/lib/coradoc/markdown/transform/image_transformer.rb +20 -0
  81. data/lib/coradoc/markdown/transform/inline_transformer.rb +74 -0
  82. data/lib/coradoc/markdown/transform/list_transformer.rb +52 -0
  83. data/lib/coradoc/markdown/transform/structural_transformer.rb +94 -0
  84. data/lib/coradoc/markdown/transform/table_transformer.rb +40 -0
  85. data/lib/coradoc/markdown/transform/to_core_model.rb +24 -3
  86. data/lib/coradoc/markdown/transformer.rb +87 -2
  87. data/lib/coradoc/markdown/version.rb +1 -1
  88. data/lib/coradoc/markdown.rb +16 -2
  89. metadata +75 -1
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class FootnoteReference < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::FootnoteReference
11
+
12
+ def call(element, _ctx)
13
+ "[^#{element.id}]"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ # Hard line break. Output depends on `config.hard_break` (not
10
+ # part of the 5 spec options yet — defaults to CommonMark
11
+ # two-trailing-spaces).
12
+ class HardLineBreak < ElementSerializer
13
+ handles_type ::Coradoc::Markdown::HardLineBreak
14
+
15
+ def call(_element, _ctx)
16
+ " \n"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Heading < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Heading
11
+
12
+ def call(element, _ctx)
13
+ "#{'#' * element.level} #{element.text}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Highlight < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Highlight
11
+
12
+ def call(element, _ctx)
13
+ "==#{element.text}=="
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class HorizontalRule < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::HorizontalRule
11
+
12
+ def call(element, _ctx)
13
+ element.style || '---'
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Image < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Image
11
+
12
+ def call(element, _ctx)
13
+ "![#{element.alt}](#{element.src}#{element.title ? " \"#{element.title}\"" : ''})"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+ require_relative '../strategies/autolink/registry'
5
+
6
+ module Coradoc
7
+ module Markdown
8
+ class Serializer
9
+ module Serializers
10
+ class Link < ElementSerializer
11
+ handles_type ::Coradoc::Markdown::Link
12
+
13
+ def call(element, ctx)
14
+ url = element.url.to_s
15
+ text = element.text.to_s
16
+ title_suffix = element.title ? " \"#{element.title}\"" : ''
17
+
18
+ Strategies::Autolink::Registry.render_or_default(
19
+ url: url,
20
+ text: text,
21
+ ctx: ctx,
22
+ default: "[#{text}](#{url}#{title_suffix})"
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class List < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::List
11
+
12
+ def call(element, _ctx)
13
+ marker = element.ordered ? '1.' : '-'
14
+ element.items.flat_map do |item|
15
+ lines = [render_item(item, marker, _ctx)]
16
+ if item.sublist
17
+ lines += call(item.sublist, _ctx).split("\n").map { |l| " #{l}" }
18
+ end
19
+ lines
20
+ end.join("\n")
21
+ end
22
+
23
+ private
24
+
25
+ def render_item(item, marker, ctx)
26
+ text = serialize_item_text(item, ctx)
27
+ if item.checked == true
28
+ "- [x] #{text.sub(/^- \[[ x]\] /, '')}"
29
+ elsif item.checked == false
30
+ "- [ ] #{text.sub(/^- \[[ x]\] /, '')}"
31
+ else
32
+ "#{marker} #{text}"
33
+ end
34
+ end
35
+
36
+ def serialize_item_text(item, ctx)
37
+ return item.text.to_s unless item.children.any?
38
+
39
+ ctx.serialize_inline_join(item.children)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ # Literal block: indented code block (4 leading spaces per line).
10
+ # Distinct from a code block (which carries a language hint).
11
+ class Literal < ElementSerializer
12
+ handles_type ::Coradoc::Markdown::Literal
13
+
14
+ def call(element, _ctx)
15
+ element.content.to_s.lines.map { |line| " #{line}" }.join
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Math < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Math
11
+
12
+ def call(element, _ctx)
13
+ if element.inline?
14
+ "$$#{element.content}$$"
15
+ else
16
+ "$$\n#{element.content}\n$$"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ # Open block: emits children inline unless id/classes are present,
10
+ # in which case it wraps them in an HTML `<div>`.
11
+ class OpenBlock < ElementSerializer
12
+ handles_type ::Coradoc::Markdown::OpenBlock
13
+
14
+ def call(element, ctx)
15
+ children_md = element.children.map { |c| ctx.serialize(c) }.join("\n\n")
16
+ return children_md unless needs_wrapper?(element)
17
+
18
+ attrs = wrapper_attrs(element)
19
+ %(<div#{attrs}>\n#{children_md}\n</div>)
20
+ end
21
+
22
+ private
23
+
24
+ def needs_wrapper?(element)
25
+ element.id || (element.classes && element.classes.any?)
26
+ end
27
+
28
+ def wrapper_attrs(element)
29
+ parts = []
30
+ parts << %(id="#{element.id}") if element.id
31
+ element.classes&.each { |c| parts << %(class="#{c}") }
32
+ parts.empty? ? '' : " #{parts.join(' ')}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Paragraph < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Paragraph
11
+
12
+ def call(element, ctx)
13
+ if element.children.any?
14
+ ctx.serialize_inline_join(element.children)
15
+ else
16
+ element.text.to_s
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ # Pass block: emit content inside kramdown's nomarkdown extension
10
+ # so it bypasses Markdown rendering.
11
+ class Pass < ElementSerializer
12
+ handles_type ::Coradoc::Markdown::Pass
13
+
14
+ def call(element, _ctx)
15
+ "{::nomarkdown}#{element.content.to_s}{:/}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Sidebar < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Sidebar
11
+
12
+ def call(element, _ctx)
13
+ title_html = element.title ? %(<div class="title">#{element.title}</div>\n) : ''
14
+ %(<div class="sidebar">\n#{title_html}#{element.content.to_s}\n</div>)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Strikethrough < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Strikethrough
11
+
12
+ def call(element, _ctx)
13
+ "~~#{element.text}~~"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Strong < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Strong
11
+
12
+ def call(element, _ctx)
13
+ "**#{element.text}**"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Subscript < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Subscript
11
+
12
+ def call(element, _ctx)
13
+ "<sub>#{element.text}</sub>"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Superscript < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Superscript
11
+
12
+ def call(element, _ctx)
13
+ "<sup>#{element.text}</sup>"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Table < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Table
11
+
12
+ def call(element, _ctx)
13
+ cols = [element.headers.size, *element.rows.map { |r| row_cells(r).size }].max
14
+ return '' if cols.zero?
15
+
16
+ headers = element.headers.empty? ? Array.new(cols, '') : element.headers
17
+ header_row = "| #{headers.join(' | ')} |"
18
+ separator = "| #{headers.map { '---' }.join(' | ')} |"
19
+ rows = element.rows.map do |row|
20
+ cells = row_cells(row).fill('', row_cells(row).size...cols)
21
+ "| #{cells.join(' | ')} |"
22
+ end
23
+
24
+ [header_row, separator, *rows].join("\n")
25
+ end
26
+
27
+ private
28
+
29
+ # Rows are stored as either Array<String> (cells) or pipe-joined String
30
+ def row_cells(row)
31
+ row.is_a?(Array) ? row : row.to_s.split(' | ')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ class Underline < ElementSerializer
10
+ handles_type ::Coradoc::Markdown::Underline
11
+
12
+ def call(element, _ctx)
13
+ "<u>#{element.text}</u>"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../element_serializer'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Serializers
9
+ # Verse: blockquote with hard line breaks preserved. The verse
10
+ # semantic is lost but line breaks survive.
11
+ class Verse < ElementSerializer
12
+ handles_type ::Coradoc::Markdown::Verse
13
+
14
+ def call(element, _ctx)
15
+ body = element.content.to_s
16
+ attribution = element.attribution
17
+ citetitle = element.citetitle
18
+ attribution_line = if attribution && citetitle
19
+ "\n>\n> — #{attribution}, <cite>#{citetitle}</cite>"
20
+ elsif attribution
21
+ "\n>\n> — #{attribution}"
22
+ else
23
+ ''
24
+ end
25
+ body.lines.map { |line| "> #{line}".rstrip }.join("\n").concat(attribution_line)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Markdown
5
+ class Serializer
6
+ module Strategies
7
+ module Admonition
8
+ # Each strategy renders an admonition (type, content, optional
9
+ # title) for a specific output form. The active strategy is
10
+ # chosen by `config.admonition_style`.
11
+ #
12
+ # Strategies are stateless; all state flows through arguments.
13
+ # Adding a new admonition form = adding one file + one entry
14
+ # in Registry::MODES.
15
+ class Base
16
+ class << self
17
+ def render(_admonition, _ctx)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def mode_name
22
+ name.split('::').last.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Strategies
9
+ module Admonition
10
+ # Container syntax (VitePress, markdown-it-container):
11
+ #
12
+ # :::note
13
+ # content
14
+ # :::
15
+ #
16
+ # Custom title:
17
+ #
18
+ # :::note[Custom Title]
19
+ # content
20
+ # :::
21
+ class Container < Base
22
+ class << self
23
+ def render(admonition, _ctx)
24
+ type = admonition.admonition_type.to_s
25
+ title_suffix = admonition.title ? "[#{admonition.title}]" : ''
26
+ ":::#{type}#{title_suffix}\n#{admonition.content.to_s}\n:::"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Strategies
9
+ module Admonition
10
+ # GFM Alerts (native since Dec 2023): `> [!TYPE]\n> content`.
11
+ # Recognized types: NOTE, TIP, IMPORTANT, WARNING, CAUTION.
12
+ # Source: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
13
+ class GfmAlert < Base
14
+ class << self
15
+ def render(admonition, _ctx)
16
+ type = admonition.admonition_type.to_s.capitalize
17
+ body = admonition.content.to_s
18
+ body = body.lines.map { |line| "> #{line}".rstrip }.join("\n")
19
+ title_suffix = admonition.title ? " \"#{admonition.title}\"" : ''
20
+ "> [!#{type}]#{title_suffix}\n#{body}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Strategies
9
+ module Admonition
10
+ # GitHub-style: a styled blockquote with `**TYPE:**` prefix.
11
+ # Renders correctly in GitHub, GitLab, and most renderers that
12
+ # recognize the bold-prefix pattern.
13
+ class Github < Base
14
+ class << self
15
+ def render(admonition, _ctx)
16
+ type = admonition.admonition_type.to_s.upcase
17
+ body = admonition.content.to_s
18
+ if admonition.title
19
+ body = "**#{admonition.title}**\n\n#{body}" unless admonition.title.to_s.strip.empty?
20
+ end
21
+ "> **#{type}:** #{body}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base'
4
+
5
+ module Coradoc
6
+ module Markdown
7
+ class Serializer
8
+ module Strategies
9
+ module Admonition
10
+ # HTML fallback: a div with `class="<type>"` and optional
11
+ # `<div class="title">` for the title.
12
+ class Html < Base
13
+ class << self
14
+ def render(admonition, _ctx)
15
+ type = admonition.admonition_type.to_s
16
+ title_html = admonition.title ? %(<div class="title">#{admonition.title}</div>\n) : ''
17
+ %(<div class="#{type}">\n#{title_html}#{admonition.content.to_s}\n</div>)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end