class Qiita::Markdown::Filters::Truncate

A filter for truncating a document without breaking the document structure.

You can pass ‘:length` and `:omission` option to :truncate context.

@example

Truncate.new(doc, truncate: { length: 50, omission: '... (continued)' })

Constants

DEFAULT_OPTIONS

Public Instance Methods

call() click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 17
def call
  @current_length = 0
  @previous_char_was_blank = false

  traverse(doc) do |node|
    if exceeded?
      node.remove
    elsif node.text?
      process_text_node(node)
    end
  end

  doc
end

Private Instance Methods

exceeded?() click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 46
def exceeded?
  @current_length > max_length
end
max_length() click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 65
def max_length
  options[:length]
end
omission() click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 69
def omission
  options[:omission] || "".freeze
end
options() click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 73
def options
  @options ||= DEFAULT_OPTIONS.merge(context[:truncate] || {})
end
process_text_node(node) click to toggle source
# File lib/qiita/markdown/filters/truncate.rb, line 50
def process_text_node(node)
  node.content.each_char.with_index do |char, index|
    current_char_is_blank = char.strip.empty?

    @current_length += 1 if !@previous_char_was_blank || !current_char_is_blank

    @previous_char_was_blank = current_char_is_blank

    if exceeded?
      node.content = node.content.slice(0...(index - omission.size)) + omission
      break
    end
  end
end
traverse(node) { |node| ... } click to toggle source

Traverse the given node recursively in the depth-first order. Note that we cannot use Nokogiri::XML::Node#traverse since it traverses the node’s descendants before the node itself. github.com/sparklemotion/nokogiri/blob/v1.6.6.2/lib/nokogiri/xml/node.rb#L571-L574

# File lib/qiita/markdown/filters/truncate.rb, line 38
def traverse(node, &block)
  yield(node)

  node.children.each do |child_node|
    traverse(child_node, &block)
  end
end