Class: CommonMarker::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/commonmarker.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type = nil, pointer = nil) ⇒ Node

Creates a Node. Either type or pointer should be provided; the other should be nil. If type is provided, a new node with that type is created. If pointer is provided, a node is created from the C node at pointer. Params:

type

node_type of the node to be created (nil if pointer is used).

pointer

pointer to C node (nil if type is used).



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/commonmarker.rb', line 35

def initialize(type = nil, pointer = nil)
  if pointer
    @pointer = pointer
  else
    unless NODE_TYPES.include?(type)
      fail NodeError, "node type does not exist #{type}"
    end
    @pointer = CMark.node_new(type)
  end

  fail NodeError, "could not create node of type #{type}" if @pointer.nil?
end

Instance Attribute Details

#pointerObject (readonly)

Returns the value of attribute pointer.



26
27
28
# File 'lib/commonmarker.rb', line 26

def pointer
  @pointer
end

Class Method Details

.parse_file(f) ⇒ Object

Params:

f

File to be parsed (caller must open and close).



64
65
66
67
# File 'lib/commonmarker.rb', line 64

def self.parse_file(f)
  s = f.read()
  self.parse_string(s)
end

.parse_string(s, option = :default) ⇒ Object

Parses a string into a :document Node. The free method should be called to release the node’s memory when it is no longer needed. Params:

s

String to be parsed.



53
54
55
56
# File 'lib/commonmarker.rb', line 53

def self.parse_string(s, option = :default)
  Config.option_exists?(option)
  Node.new(nil, CMark.parse_document(s, s.bytesize, Config.to_h[option]))
end

Instance Method Details

#deleteObject

Deletes the node and unlinks it (fixing pointers in parents and siblings appropriately). Note: this method does not free the node.



102
103
104
# File 'lib/commonmarker.rb', line 102

def delete
  CMark.node_unlink(@pointer)
end

#each_childObject

Iterator over the children (if any) of this Node.



90
91
92
93
94
95
96
97
# File 'lib/commonmarker.rb', line 90

def each_child
  childptr = CMark.node_first_child(@pointer)
  until CMark.node_get_type_string(childptr) == NONE_TYPE
    nextptr = CMark.node_next(childptr)
    yield Node.new(nil, childptr)
    childptr = nextptr
  end
end

#fence_infoObject

Returns fence info of this Node (must be a :code_block).



251
252
253
254
# File 'lib/commonmarker.rb', line 251

def fence_info
  fail NodeError, 'can\'t get fence_info for non code_block' unless type == :code_block
  CMark.node_get_fence_info(@pointer)
end

#fence_info=(info) ⇒ Object

Sets fence_info of this Node (must be a :code_block). Params:

info

New info (String).



259
260
261
262
263
264
265
266
# File 'lib/commonmarker.rb', line 259

def fence_info=(info)
  fail NodeError, 'can\'t set fence_info for non code_block' unless type == :code_block
  fail NodeError, 'info must be a String' unless info.is_a?(String)
  # Make our own copy so ruby won't garbage-collect it:
  c_info = FFI::MemoryPointer.from_string(info)
  res = CMark.node_set_fence_info(@pointer, c_info)
  fail NodeError, 'could not set info' if res == 0
end

#first_childObject



69
70
71
# File 'lib/commonmarker.rb', line 69

def first_child
  Node.new(nil, CMark.node_first_child(@pointer))
end

#freeObject

Unlinks and frees this Node.



293
294
295
296
# File 'lib/commonmarker.rb', line 293

def free
  CMark.node_unlink(@pointer)
  # CMark.node_free(@pointer)
end

#header_levelObject

Returns header level of this Node (must be a :header).



144
145
146
147
# File 'lib/commonmarker.rb', line 144

def header_level
  fail NodeError, 'can\'t get header_level for non-header' unless type == :header
  CMark.node_get_header_level(@pointer)
end

#header_level=(level) ⇒ Object

Sets header level of this Node (must be a :header). Params:

level

New header level (Integer).



152
153
154
155
156
157
158
159
# File 'lib/commonmarker.rb', line 152

def header_level=(level)
  fail NodeError, 'can\'t set header_level for non-header' unless type == :header
  if !level.is_a?(Integer) || level < 0 || level > 6
    fail NodeError, 'level must be between 1-6'
  end
  res = CMark.node_set_header_level(@pointer, level)
  fail NodeError, 'could not set header level' if res == 0
end

#insert_after(sibling) ⇒ Object

Insert a node after this Node. Params:

sibling

Sibling Node to insert.



117
118
119
120
# File 'lib/commonmarker.rb', line 117

def insert_after(sibling)
  res = CMark.node_insert_before(@pointer, sibling.pointer)
  fail NodeError, 'could not insert after' if res == 0
end

#insert_before(sibling) ⇒ Object

Insert a node before this Node. Params:

sibling

Sibling node to insert.



109
110
111
112
# File 'lib/commonmarker.rb', line 109

def insert_before(sibling)
  res = CMark.node_insert_before(@pointer, sibling.pointer)
  fail NodeError, 'could not insert before' if res == 0
end

#last_childObject



73
74
75
# File 'lib/commonmarker.rb', line 73

def last_child
  Node.new(nil, CMark.node_last_child(@pointer))
end

#list_startObject

Returns start number of this Node (must be a :list of list_type :ordered_list).



179
180
181
182
183
184
# File 'lib/commonmarker.rb', line 179

def list_start
  if type != :list || list_type != :ordered_list
    fail NodeError, 'can\'t get list_start for non-ordered list'
  end
  CMark.node_get_list_start(@pointer)
end

#list_start=(start) ⇒ Object

Sets start number of this Node (must be a :list of list_type :ordered_list). Params:

start

New start number (Integer).



190
191
192
193
194
195
196
197
# File 'lib/commonmarker.rb', line 190

def list_start=(start)
  if type != :list || list_type != :ordered_list
    fail NodeError, 'can\'t set list_start for non-ordered list'
  end
  fail NodeError, 'start must be Integer' unless start.is_a?(Integer)
  res = CMark.node_set_list_start(@pointer, start)
  fail NodeError, 'could not set list_start' if res == 0
end

#list_tightObject

Returns tight status of this Node (must be a :list).



200
201
202
203
# File 'lib/commonmarker.rb', line 200

def list_tight
  fail NodeError, 'can\'t get list_tight for non-list' unless type == :list
  CMark.node_get_list_tight(@pointer)
end

#list_tight=(tight) ⇒ Object

Sets tight status of this Node (must be a :list). Params:

tight

New tight status (boolean).



208
209
210
211
212
# File 'lib/commonmarker.rb', line 208

def list_tight=(tight)
  fail NodeError, 'can\'t set list_tight for non-list' unless type == :list
  res = CMark.node_set_list_tight(@pointer, tight)
  fail NodeError, 'could not set list_tight' if res == 0
end

#list_typeObject

Returns list type of this Node (must be a :list).



162
163
164
165
# File 'lib/commonmarker.rb', line 162

def list_type
  fail NodeError, 'can\'t get list_type for non-list' unless type == :list
  LIST_TYPES[CMark.node_get_list_type(@pointer)]
end

#list_type=(list_type) ⇒ Object

Sets list type of this Node (must be a :list). Params:

list_type

New list type (:list_type), either

:ordered_list or :bullet_list.



171
172
173
174
175
# File 'lib/commonmarker.rb', line 171

def list_type=(list_type)
  fail NodeError, 'can\'t set list_type for non-list' unless type == :list
  res = CMark.node_set_list_type(@pointer, list_type)
  fail NodeError, 'could not set list_type' if res == 0
end

#nextObject



85
86
87
# File 'lib/commonmarker.rb', line 85

def next
  Node.new(nil, CMark.node_next(@pointer))
end

#parentObject



77
78
79
# File 'lib/commonmarker.rb', line 77

def parent
  Node.new(nil, CMark.node_parent(@pointer))
end

#prepend_child(child) ⇒ Object

Prepend a child to this Node. Params:

child

Child Node to prepend.



125
126
127
128
# File 'lib/commonmarker.rb', line 125

def prepend_child(child)
  res = CMark.node_prepend_child(@pointer, child.pointer)
  fail NodeError, 'could not prepend child' if res == 0
end

#previousObject



81
82
83
# File 'lib/commonmarker.rb', line 81

def previous
  Node.new(nil, CMark.node_previous(@pointer))
end

#string_contentObject

Returns string content of this Node.



131
132
133
# File 'lib/commonmarker.rb', line 131

def string_content
  CMark.node_get_string_content(@pointer)
end

#string_content=(s) ⇒ Object

Sets string content of this Node. Params:

s

String containing new content.



138
139
140
141
# File 'lib/commonmarker.rb', line 138

def string_content=(s)
  res = CMark.node_set_string_content(@pointer, s)
  fail NodeError, 'could not set string content' if res == 0
end

#titleObject

Returns title of this Node (must be a :link or :image).



233
234
235
236
# File 'lib/commonmarker.rb', line 233

def title
  fail NodeError, 'can\'t get title for non-link or image' if !(type == :link || type == :image)
  CMark.node_get_title(@pointer)
end

#title=(title) ⇒ Object

Sets title of this Node (must be a :link or :image). Params:

title

New title (String).



241
242
243
244
245
246
247
248
# File 'lib/commonmarker.rb', line 241

def title=(title)
  fail NodeError, 'can\'t set title for non-link or image' if !(type == :link || type == :image)
  fail NodeError, 'title must be a String' unless title.is_a?(String)
  # Make our own copy so ruby won't garbage-collect it:
  c_title = FFI::MemoryPointer.from_string(title)
  res = CMark.node_set_title(@pointer, c_title)
  fail NodeError, 'could not set header level' if res == 0
end

#to_html(option = :default) ⇒ Object

Convert to HTML using libcmark’s fast (but uncustomizable) renderer.



287
288
289
290
# File 'lib/commonmarker.rb', line 287

def to_html(option = :default)
  Config.option_exists?(option)
  CMark.render_html(@pointer, Config.to_h[option]).force_encoding('utf-8')
end

#typeObject

Returns the type of this Node.



278
279
280
# File 'lib/commonmarker.rb', line 278

def type
  NODE_TYPES[CMark.node_get_type(@pointer)]
end

#type_stringObject



282
283
284
# File 'lib/commonmarker.rb', line 282

def type_string
  CMark.node_get_type_string(@pointer)
end

#urlObject

Returns URL of this Node (must be a :link or :image).



215
216
217
218
# File 'lib/commonmarker.rb', line 215

def url
  fail NodeError, 'can\'t get URL for non-link or image' if !(type == :link || type == :image)
  CMark.node_get_url(@pointer)
end

#url=(url) ⇒ Object

Sets URL of this Node (must be a :link or :image). Params:

URL

New URL (String).



223
224
225
226
227
228
229
230
# File 'lib/commonmarker.rb', line 223

def url=(url)
  fail NodeError, 'can\'t set URL for non-link or image' if !(type == :link || type == :image)
  fail NodeError, 'url must be a String' unless url.is_a?(String)
  # Make our own copy so ruby won't garbage-collect it:
  c_url = FFI::MemoryPointer.from_string(url)
  res = CMark.node_set_url(@pointer, c_url)
  fail NodeError, 'could not set header level' if res == 0
end

#walk {|_self| ... } ⇒ Object

An iterator that “walks the tree,” descending into children recursively.

Yields:

  • (_self)

Yield Parameters:



270
271
272
273
274
275
# File 'lib/commonmarker.rb', line 270

def walk(&blk)
  yield self
  each_child do |child|
    child.walk(&blk)
  end
end