Skip to content

Commit

Permalink
it can talk!
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian committed Jan 30, 2024
1 parent 5f21436 commit 7ce8b59
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require 'commonmarker'
Commonmarker.to_html('"Hi *there*"', options: {
parse: { smart: true }
})
# <p>“Hi <em>there</em>”</p>\n
# => <p>“Hi <em>there</em>”</p>\n
```

(The second argument is optional--[see below](#options-and-plugins) for more information.)
Expand All @@ -49,10 +49,10 @@ require 'commonmarker'
doc = Commonmarker.parse("*Hello* world", options: {
parse: { smart: true }
})
puts(doc.to_html) # <p><em>Hello</em> world</p>\n
puts(doc.to_html) # => <p><em>Hello</em> world</p>\n

doc.walk do |node|
puts node.type # [:document, :paragraph, :emph, :text, :text]
puts node.type # => [:document, :paragraph, :emph, :text, :text]
end
```

Expand All @@ -66,6 +66,14 @@ When it comes to modifying the document, you can perform the following operation
- `append_child`
- `detach`

You can also get the source position of a node by calling `source_position`:

```ruby
doc = Commonmarker.parse("*Hello* world")
puts doc.first_child.first_child.source_position
# => {:start_line=>1, :start_column=>1, :end_line=>1, :end_column=>7}
```

You can also modify the following attributes:

- `url`
Expand Down
20 changes: 20 additions & 0 deletions ext/commonmarker/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,21 @@ impl CommonmarkerNode {
})
}

fn get_sourcepos(&self) -> Result<RHash, magnus::Error> {
let node = self.inner.borrow();

let result = RHash::new();
result.aset(Symbol::new("start_line"), node.data.sourcepos.start.line)?;
result.aset(
Symbol::new("start_column"),
node.data.sourcepos.start.column,
)?;
result.aset(Symbol::new("end_line"), node.data.sourcepos.end.line)?;
result.aset(Symbol::new("end_column"), node.data.sourcepos.end.column)?;

Ok(result)
}

fn insert_node_before(&self, new_sibling: &CommonmarkerNode) -> Result<bool, magnus::Error> {
let node = new_sibling.inner.clone();
node.detach();
Expand Down Expand Up @@ -546,6 +561,11 @@ pub fn init(m_commonmarker: RModule) -> Result<(), magnus::Error> {

c_node.define_method("detach", method!(CommonmarkerNode::detach_node, 0))?;

c_node.define_method(
"source_position",
method!(CommonmarkerNode::get_sourcepos, 0),
)?;

c_node.define_method("url", method!(CommonmarkerNode::get_url, 0))?;
c_node.define_method("url=", method!(CommonmarkerNode::set_url, 1))?;
c_node.define_method("title", method!(CommonmarkerNode::get_title, 0))?;
Expand Down
55 changes: 55 additions & 0 deletions test/sourcepos_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,59 @@ def test_to_html

assert_equal(expected, Commonmarker.to_html(md, options: { render: { sourcepos: true } }))
end

def test_can_generate_source_positions
md = <<~MARKDOWN
## Try CommonMark
You can try CommonMark here. This dingus is powered by
[commonmark.js](https://github.com/jgm/commonmark.js), the
JavaScript reference implementation.
1. item one
2. item two
- sublist
- sublist
MARKDOWN
doc = Commonmarker.parse(md)

source_positions = []

doc.walk do |node|
source_positions << node.source_position
end

source_positions.delete_if { |h| h.values.all?(&:zero?) }

assert_equal(
[
{ start_line: 1, start_column: 1, end_line: 10, end_column: 12 },
{ start_line: 1, start_column: 1, end_line: 1, end_column: 17 },
{ start_line: 1, start_column: 4, end_line: 1, end_column: 17 },
{ start_line: 3, start_column: 1, end_line: 5, end_column: 36 },
{ start_line: 3, start_column: 1, end_line: 3, end_column: 55 },
{ start_line: 3, start_column: 56, end_line: 3, end_column: 56 },
{ start_line: 4, start_column: 1, end_line: 4, end_column: 53 },
{ start_line: 4, start_column: 2, end_line: 4, end_column: 14 },
{ start_line: 4, start_column: 54, end_line: 4, end_column: 58 },
{ start_line: 4, start_column: 59, end_line: 4, end_column: 59 },
{ start_line: 5, start_column: 1, end_line: 5, end_column: 36 },
{ start_line: 7, start_column: 1, end_line: 10, end_column: 12 },
{ start_line: 7, start_column: 1, end_line: 7, end_column: 11 },
{ start_line: 7, start_column: 4, end_line: 7, end_column: 11 },
{ start_line: 7, start_column: 4, end_line: 7, end_column: 11 },
{ start_line: 8, start_column: 1, end_line: 10, end_column: 12 },
{ start_line: 8, start_column: 4, end_line: 8, end_column: 11 },
{ start_line: 8, start_column: 4, end_line: 8, end_column: 11 },
{ start_line: 9, start_column: 4, end_line: 10, end_column: 12 },
{ start_line: 9, start_column: 4, end_line: 9, end_column: 12 },
{ start_line: 9, start_column: 6, end_line: 9, end_column: 12 },
{ start_line: 9, start_column: 6, end_line: 9, end_column: 12 },
{ start_line: 10, start_column: 4, end_line: 10, end_column: 12 },
{ start_line: 10, start_column: 6, end_line: 10, end_column: 12 },
{ start_line: 10, start_column: 6, end_line: 10, end_column: 12 },
],
source_positions,
)
end
end

0 comments on commit 7ce8b59

Please sign in to comment.