markly 0.15.1 → 0.15.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 712a0a7ad856598eb83b20c370e7613896596af5c76cc2379a368382802f09db
4
- data.tar.gz: f775598d6fc6e4d5e340bf68518816d3bd23bc44facd209fcd59bd4f0d429639
3
+ metadata.gz: 78c9ac76ac7421696ae270097bcf7e960f78b3ae8850232fa9d7c1d6a5e5d893
4
+ data.tar.gz: eb0e5d5ebcfb8cf4f128dc61ac3989eb789a31ae1f9ec7e99ecd6c9482859edc
5
5
  SHA512:
6
- metadata.gz: f13cbaaba186b5716efb05567721ea024633f0c353f7296721406dd7d4f7918625e5518ae4836371a784808ae99de8d4831bf938df6595ed26da462398c6e39f
7
- data.tar.gz: a92d4ee382baaf2bea98defccfd318142f0fdccf42ff5fca5293c17bf611e432d21e178f3d69a272f0c021309d3725454e93ea401d7473495ff4620490071d5d
6
+ metadata.gz: 2c68b3899e33d96fcfeb9ad0c2458f67dffd9b9f8d5a1e2f1b2cd8a158faf74d5b4e1246f59b7257606b8b2218175a3563ad048824878ae6b04f6a1f5b7bfc28
7
+ data.tar.gz: 27d4228f0c7f158d1397117ce744f4c00ed7a59fff8253756281dc3f87d01aa642759a71187e9ee137d051d91a9d059a739addaa8b9f8f3b23b544f7ebb3f18b
checksums.yaml.gz.sig CHANGED
Binary file
@@ -39,7 +39,7 @@ You can use `walk` or `each` to iterate over nodes:
39
39
  <!-- end list -->
40
40
 
41
41
  ``` ruby
42
- require 'markly'
42
+ require "markly"
43
43
 
44
44
  document = Markly.parse("# The site\n\n [GitHub](https://www.github.com)")
45
45
 
@@ -80,11 +80,10 @@ class MyHtmlRenderer < Markly::Renderer::HTML
80
80
  super
81
81
  @header_id = 1
82
82
  end
83
-
83
+
84
84
  def header(node)
85
85
  block do
86
- out("<h", node.header_level, " id=\"", @header_id, "\">",
87
- :children, "</h", node.header_level, ">")
86
+ out("<h", node.header_level, " id=\"", @header_id, "\">", :children, "</h", node.header_level, ">")
88
87
  @header_id += 1
89
88
  end
90
89
  end
data/context/headings.md CHANGED
@@ -38,7 +38,7 @@ document = Markly.parse(markdown)
38
38
  headings = Markly::Renderer::Headings.extract(document, min_level: 2, max_level: 3)
39
39
 
40
40
  headings.each do |heading|
41
- puts "#{heading.level}: #{heading.text} (#{heading.anchor})"
41
+ puts "#{heading.level}: #{heading.text} (#{heading.anchor})"
42
42
  end
43
43
 
44
44
  # Output:
@@ -90,25 +90,24 @@ Subclass `Headings` to implement alternative ID generation strategies:
90
90
 
91
91
  ``` ruby
92
92
  class HierarchicalHeadings < Markly::Renderer::Headings
93
- def initialize
94
- super
95
- @parent_context = []
96
- end
97
-
98
- def anchor_for(node)
99
- base = base_anchor_for(node)
100
-
101
- # Custom logic: could incorporate parent heading context
102
- # to generate IDs like "kubernetes-deployment" instead of "deployment-2"
103
-
104
- if @ids.key?(base)
105
- @ids[base] += 1
106
- "#{base}-#{@ids[base]}"
107
- else
108
- @ids[base] = 1
109
- base
110
- end
111
- end
93
+ def initialize
94
+ super
95
+ @parent_context = []
96
+ end
97
+
98
+ def anchor_for(node)
99
+ base = base_anchor_for(node)
100
+
101
+ # Custom logic: could incorporate parent heading context to generate IDs like "kubernetes-deployment" instead of "deployment-2"
102
+
103
+ if @ids.key?(base)
104
+ @ids[base] += 1
105
+ "#{base}-#{@ids[base]}"
106
+ else
107
+ @ids[base] = 1
108
+ base
109
+ end
110
+ end
112
111
  end
113
112
 
114
113
  renderer = Markly::Renderer::HTML.new(headings: HierarchicalHeadings.new)
data/ext/markly/blocks.c CHANGED
@@ -72,6 +72,20 @@ static CMARK_INLINE bool S_is_space_or_tab(char c) {
72
72
  return (c == ' ' || c == '\t');
73
73
  }
74
74
 
75
+ // Returns true if block is being finalized on the same line it ends.
76
+ // This happens for:
77
+ // - Document node (special case)
78
+ // - Fenced code blocks (end on the closing fence line)
79
+ // - Setext headings (end on the underline)
80
+ // - Any block finalized on the same line it started (e.g., single-line HTML blocks)
81
+ static CMARK_INLINE bool S_ends_on_current_line(cmark_parser *parser, cmark_node *b) {
82
+ return S_type(b) == CMARK_NODE_DOCUMENT ||
83
+ (S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) ||
84
+ (S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext) ||
85
+ // Single-line blocks: finalized on same line they started
86
+ b->start_line == parser->line_number;
87
+ }
88
+
75
89
  static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
76
90
  size_t len, bool eof);
77
91
 
@@ -288,17 +302,15 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
288
302
  bool has_content;
289
303
 
290
304
  parent = b->parent;
291
- assert(b->flags &
292
- CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks
305
+ assert(b->flags & CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks
293
306
  b->flags &= ~CMARK_NODE__OPEN;
294
307
 
295
308
  if (parser->curline.size == 0) {
296
- // end of input - line number has not been incremented
309
+ // end of input - line number has not been incremented:
297
310
  b->end_line = parser->line_number;
298
311
  b->end_column = parser->last_line_length;
299
- } else if (S_type(b) == CMARK_NODE_DOCUMENT ||
300
- (S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) ||
301
- (S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext)) {
312
+ } else if (S_ends_on_current_line(parser, b)) {
313
+ // Block ends on current line (line_number already incremented):
302
314
  b->end_line = parser->line_number;
303
315
  b->end_column = parser->curline.size;
304
316
  if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\n')
@@ -306,6 +318,7 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
306
318
  if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\r')
307
319
  b->end_column -= 1;
308
320
  } else {
321
+ // Block ended on a previous line:
309
322
  b->end_line = parser->line_number - 1;
310
323
  b->end_column = parser->last_line_length;
311
324
  }
data/lib/markly/node.rb CHANGED
@@ -6,6 +6,7 @@
6
6
  # Copyright, 2017, by Goro Fuji.
7
7
  # Copyright, 2018, by Jerry van Leeuwen.
8
8
  # Copyright, 2020-2025, by Samuel Williams.
9
+ # Copyright, 2025, by Olle Jonsson.
9
10
 
10
11
  require_relative "node/inspect"
11
12
 
@@ -26,9 +26,9 @@ module Markly
26
26
  def out(*args)
27
27
  args.each do |arg|
28
28
  if arg == :children
29
- @node.each {|child| out(child)}
29
+ @node.each{|child| out(child)}
30
30
  elsif arg.is_a?(Array)
31
- arg.each {|x| render(x)}
31
+ arg.each{|x| render(x)}
32
32
  elsif arg.is_a?(Node)
33
33
  render(arg)
34
34
  else
@@ -43,7 +43,7 @@ module Markly
43
43
  document(node)
44
44
  @stream.string
45
45
  elsif @in_plain && node.type != :text && node.type != :softbreak
46
- node.each {|child| render(child)}
46
+ node.each{|child| render(child)}
47
47
  else
48
48
  send(node.type, node)
49
49
  end
@@ -10,7 +10,13 @@
10
10
 
11
11
  require_relative "generic"
12
12
  require_relative "headings"
13
- require "cgi"
13
+
14
+ require "cgi/escape"
15
+
16
+ # Compatibility for older Ruby versions where escape_html alias doesn't exist:
17
+ unless CGI.respond_to?(:escape_html)
18
+ require "cgi"
19
+ end
14
20
 
15
21
  module Markly
16
22
  module Renderer
@@ -256,10 +262,10 @@ module Markly
256
262
  end
257
263
 
258
264
  TABLE_CELL_ALIGNMENT = {
259
- left: ' align="left"',
260
- right: ' align="right"',
261
- center: ' align="center"'
262
- }.freeze
265
+ left: ' align="left"',
266
+ right: ' align="right"',
267
+ center: ' align="center"'
268
+ }.freeze
263
269
 
264
270
  def table_cell(node)
265
271
  align = TABLE_CELL_ALIGNMENT.fetch(@alignments[@column_index], "")
@@ -7,5 +7,5 @@
7
7
  # Copyright, 2020-2025, by Samuel Williams.
8
8
 
9
9
  module Markly
10
- VERSION = "0.15.1"
10
+ VERSION = "0.15.2"
11
11
  end
data/license.md CHANGED
@@ -17,9 +17,11 @@ Copyright, 2018, by Akira Matsuda.
17
17
  Copyright, 2018, by Danny Iachini.
18
18
  Copyright, 2019-2020, by Tomoya Chiba.
19
19
  Copyright, 2019, by Brett Walker.
20
- Copyright, 2020, by Olle Jonsson.
20
+ Copyright, 2020-2025, by Olle Jonsson.
21
21
  Copyright, 2020-2025, by Samuel Williams.
22
22
  Copyright, 2024, by Ross Kaffenberger.
23
+ Copyright, 2025, by Henrik Nyh.
24
+ Copyright, 2025, by Peter H. Boling.
23
25
 
24
26
  Permission is hereby granted, free of charge, to any person obtaining a copy
25
27
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -1,18 +1,14 @@
1
1
  # Markly
2
2
 
3
- A parser and abstract syntax tree for Markdown documents (CommonMark compatible) in Ruby. Originally forked from
4
- [CommonMarker](https://github.com/gjtorikian/commonmarker). It also includes extensions to the CommonMark spec as
5
- documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables,
6
- strikethroughs, and autolinking.
3
+ A parser and abstract syntax tree for Markdown documents (CommonMark compatible) in Ruby. Originally forked from [CommonMarker](https://github.com/gjtorikian/commonmarker). It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
7
4
 
8
5
  [![Development Status](https://github.com/ioquatix/markly/workflows/Test/badge.svg)](https://github.com/ioquatix/markly/actions?workflow=Test)
9
6
 
10
7
  ## Motivation
11
8
 
12
- This code base was originally forked from [Commonmarker](https://github.com/gjtorikian/commonmarker) before they
13
- switched from `cmark-gfm` (C) to `comrak` (Rust). The original implementation provided access to the abstract syntax
14
- tree (AST), which is useful for building tools on top of Markdown. The Rust implementation does not provide this
15
- functionality, and so this fork was created to continue to provide these (and more) features.
9
+ This code base was originally forked from [Commonmarker](https://github.com/gjtorikian/commonmarker) before theyswitched from `cmark-gfm` (C) to `comrak` (Rust). The original implementation provided access to the abstract syntaxtree (AST), which is useful for building tools on top of Markdown. The Rust implementation did not provide thisfunctionality, and so this fork was created to continue to provide these (and more) features.
10
+
11
+ It should be noted that `commonmarker` re-introduced AST access, but the original C implementation in this fork is [3-4x faster at processing Markdown into HTML](https://github.com/gjtorikian/commonmarker?tab=readme-ov-file#benchmarks) and has a more advanced HTML generation and AST processing features.
16
12
 
17
13
  ## Usage
18
14
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
@@ -14,13 +14,15 @@ authors:
14
14
  - Andrew Anderson
15
15
  - Ben Woosley
16
16
  - Goro Fuji
17
+ - Olle Jonsson
17
18
  - Tomoya Chiba
18
19
  - Akira Matsuda
19
20
  - Danny Iachini
21
+ - Henrik Nyh
20
22
  - Jerry van Leeuwen
21
23
  - Michael Camilleri
22
24
  - Mu-An Chiou
23
- - Olle Jonsson
25
+ - Peter H. Boling
24
26
  - Roberto Hidalgo
25
27
  - Ross Kaffenberger
26
28
  - Vitaliy Klachkov
metadata.gz.sig CHANGED
Binary file