class RubyMatter::Parser

Parses the supplied original on demand, when the relevant methods are called.

Constants

COMMENT
NEWLINE

Attributes

original[R]

Public Class Methods

new( source, delimiters:, language: nil, aliases: {}, engines: {}, excerpt: nil, excerpt_separator: nil ) click to toggle source

Instantiate the parser. This should not need to be called directly, as the RubyMatter module methods will handle this. For more information, see the following methods that instantiate a parser:

Returns

(RubyMatter::Parser)

An instance of the parser.

# File lib/ruby_matter/parser.rb, line 28
def initialize(
  source,
  delimiters:,
  language: nil,
  aliases: {},
  engines: {},
  excerpt: nil,
  excerpt_separator: nil
)
  @original = source
  @delimiters = delimiters
  @language_default = language
  @aliases = aliases
  @engines = engines
  @excerpt = excerpt
  @excerpt_separator = excerpt_separator
end

Public Instance Methods

content() click to toggle source

Extracts the content from the front matter.

Returns

(String)

The content found in the source.

# File lib/ruby_matter/parser.rb, line 83
def content
  return @original unless matter?

  finish == size ? '' : @original[after..].sub(/^#{NEWLINE}/, '')
end
data() click to toggle source

Extracts the data from the front matter.

Returns

(Hash)

The data found in the front matter.

# File lib/ruby_matter/parser.rb, line 52
def data
  return {} unless block?

  engine[:parse].call(matter).then do |value|
    value.is_a?(Hash) ? value : {}
  end
end
directive() click to toggle source

The language extracted from the front matter.

Returns

(String)

The raw directive string within the front matter.

# File lib/ruby_matter/parser.rb, line 138
def directive
  @directive ||= extract_directive.then do |raw|
    (raw && raw.strip).then do |name|
      { raw: raw, name: name.empty? ? nil : name }
    end
  end
end
empty() click to toggle source

When the front matter is empty (either all whitespace, nothing at all, or just comments and no data), the original string is set on this property.

Returns

(String|nil)

If the front matter was empty, this is the raw front matter, otherwise nil.

# File lib/ruby_matter/parser.rb, line 118
def empty
  @empty ||= block.empty? ? @original : nil
end
empty?() click to toggle source

Whether the front matter is empty.

Returns

(Boolean)

Evaluates to true if front matter is empty.

# File lib/ruby_matter/parser.rb, line 128
def empty?
  empty != nil
end
excerpt() click to toggle source

If enabled, extracts the excerpt after front matter.

Returns

(String|nil)

The excerpt, or nil.

# File lib/ruby_matter/parser.rb, line 66
def excerpt
  return unless @excerpt || @excerpt_separator
  return @excerpt.call(self) if @excerpt.respond_to?(:call)

  content.index(
    @excerpt.is_a?(String) ? @excerpt : @excerpt_separator || opening
  ).then do |index|
    index && content[0...index]
  end
end
matter() click to toggle source

Extracts the raw front matter block.

Returns

(String)

The raw front matter found in the source.

# File lib/ruby_matter/parser.rb, line 95
def matter
  @matter ||= matter? && @original[start...finish] || ''
end
matter?() click to toggle source

Whether the source has front matter.

Returns

(Boolean)

Evaluates to true if front matter is present.

# File lib/ruby_matter/parser.rb, line 105
def matter?
  @original.start_with?(opening) && @original[opening.size] != opening[-1]
end
stringify() click to toggle source

Stringifies using the supplied delimiters, language, engines and optional excerpt. By default, only YAML and JSON can be stringified. See the engines argument for to go about stringifying other languages.

Returns

(String)

The stringified data, excerpt, and content.

# File lib/ruby_matter/parser.rb, line 156
def stringify
  RubyMatter::Stringifier.new(
    content,
    data: data,
    delimiters: @delimiters,
    language: language,
    engines: @engines,
    excerpt: excerpt,
    excerpt_separator: @excerpt_separator
  ).stringify
end

Private Instance Methods

after() click to toggle source

Index after closing delimiter.

# File lib/ruby_matter/parser.rb, line 226
def after
  @after ||= finish + closing.size
end
block() click to toggle source

Raw matter block without comments.

# File lib/ruby_matter/parser.rb, line 194
def block
  matter? ? matter.gsub(/#{COMMENT}/m, '').strip : ''
end
block?() click to toggle source

Is there any matter to parse.

# File lib/ruby_matter/parser.rb, line 199
def block?
  !block.empty?
end
closing() click to toggle source

Closing delimiter, with leading newline.

# File lib/ruby_matter/parser.rb, line 209
def closing
  @closing ||= "\n#{@delimiters.last}"
end
engine() click to toggle source

Engine for language.

# File lib/ruby_matter/parser.rb, line 187
def engine
  @engine ||= @engines[language] || raise(
    EngineError.new(language: language)
  )
end
extract_directive() click to toggle source

Language defined after first delimiter.

# File lib/ruby_matter/parser.rb, line 178
def extract_directive
  return nil unless matter?

  @original[opening.size..].then do |matter|
    matter && matter[0...matter.index(/#{NEWLINE}/)]
  end
end
finish() click to toggle source

Index of closing delimiter.

# File lib/ruby_matter/parser.rb, line 221
def finish
  @finish ||= @original.index(closing, start) || size
end
language() click to toggle source

Language from directive or fallback to supplied string.

# File lib/ruby_matter/parser.rb, line 171
def language
  @language ||= (directive[:name] || @language_default).then do |handle|
    @aliases[handle.downcase] || handle
  end
end
opening() click to toggle source

Opening delimiter.

# File lib/ruby_matter/parser.rb, line 204
def opening
  @opening ||= @delimiters.first
end
size() click to toggle source

Size on the original content.

# File lib/ruby_matter/parser.rb, line 231
def size
  @size ||= @original.size
end
start() click to toggle source

Length of the opening delimiter and language.

# File lib/ruby_matter/parser.rb, line 214
def start
  @start ||= directive[:raw].then do |raw|
    raw ? opening.size + raw.size : opening.size
  end
end