class Glyph::Macro

A Macro object is instantiated by a Glyph::Interpreter whenever a macro is found in the parsed text. The Macro class contains shortcut methods to access the current node and document, as well as other useful methods to be used in macro definitions.

Attributes

name[R]
node[R]
source_file[R]
source_name[R]
source_topic[R]

Public Class Methods

new(node) click to toggle source

Creates a new macro instance from a Node @param [Node] node a node populated with macro data

# File lib/glyph/macro.rb, line 17
def initialize(node)
        @data = {}
        @node = node
        @name = @node[:name]
        @updated_source = nil
        @source_name = @node[:source][:name] || nil rescue "--"
        @source_topic = @node[:source][:topic] || nil rescue "--"
        @source_file = @node[:source][:file] rescue nil
end

Public Instance Methods

apply(text) click to toggle source

Performs parameter/attribute substitution and interprets text @since 0.5.0 @param [String] text the text to interpret @return [String] the interpreted output

# File lib/glyph/macro.rb, line 284
def apply(text)
        body = text.dup
        # Parameters
        body.gsub!(/\{\{(\d+)\}\}/) do
                raw_param($1.to_i).to_s.strip
        end
        # Attributes
        body.gsub!(/\{\{([^\[\]\|\\\s]+)\}\}/) do
                raw_attr($1.to_sym).to_s.strip
        end
        interpret body
end
attr(name, options={:strip => true, :null_if_blank => true})
Alias for: attribute
attribute(name, options={:strip => true, :null_if_blank => true}) click to toggle source

Returns an evaluated macro attribute by name @param [String, Symbol] name the name of the attribute @param [Hash] options a hash of options @option options [Boolean] :strip whether the value is stripped or not @return [String, nil] the value of the attribute @since 0.3.0

# File lib/glyph/macro.rb, line 60
def attribute(name, options={:strip => true, :null_if_blank => true})
        return @attributes[name.to_sym] if @attributes && @attributes[name.to_sym]
        return nil unless @node.attribute(name)
        @attributes = {} unless @attributes
        @attributes[name] = @node.attribute(name).evaluate(@node, :attrs => true).to_s
        @attributes[name].strip! if options[:strip]
        @attributes[name] = nil if @attributes[name].blank? && options[:null_if_blank]
        @attributes[name]
end
Also aliased as: attr
attributes(options={:strip => true, :null_if_blank => true}) click to toggle source

Returns a hash containing all evaluated macro attributes @param [Hash] options a hash of options @option options [Boolean] :strip whether the value is stripped or not @return [Hash] the macro attributes @since 0.3.0

# File lib/glyph/macro.rb, line 91
def attributes(options={:strip => true, :null_if_blank => true})
        return @attributes if @attributes
        @attributes = {}
        @node.attributes.each do |value|
                @attributes[value[:name]] = value.evaluate(@node, :attrs => true)
                @attributes[value[:name]].strip! if options[:strip]
                @attributes[value[:name]] = nil if @attributes[value[:name]].blank? && options[:null_if_blank]
        end
        @attributes
end
Also aliased as: attrs
attrs(options={:strip => true, :null_if_blank => true})
Alias for: attributes
bookmark(hash) click to toggle source

@see Glyph::Document#bookmark

# File lib/glyph/macro.rb, line 221
def bookmark(hash)
        @node[:document].bookmark hash
end
bookmark?(ident) click to toggle source

@see Glyph::Document#bookmark?

# File lib/glyph/macro.rb, line 226
def bookmark?(ident)
        @node[:document].bookmark? ident
end
dispatch(&block) click to toggle source

Stores a block of code to be “dispatched” via macro composition @since 0.5.0 @example

# Macro definition (Ruby)
macro :greet do
                  dispatch do |node|
                          "#{node[:name]}, #{node.param 0}!"
                  end
end

          # macro usage (Glyph)
          greet/Hello[World] --[Outputs: Hello, World!]
          greet/GoodBye[John] --[Outputs: Goodbye, John!]
# File lib/glyph/macro.rb, line 275
def dispatch(&block)
        @node[:dispatch] = block
        value
end
expand() click to toggle source

Executes a macro definition in the context of self

# File lib/glyph/macro.rb, line 319
def expand
        block = Glyph::MACROS[@name]
        macro_error "Undefined macro '#@name'" unless block
        instance_exec(@node, &block).to_s.gsub(/\\?([\[\]\|])/){"\\#$1"}
end
header(hash) click to toggle source

@see Glyph::Document#header

# File lib/glyph/macro.rb, line 236
def header(hash)
        @node[:document].header hash
end
header?(ident) click to toggle source

@see Glyph::Document#header?

# File lib/glyph/macro.rb, line 231
def header?(ident)
        @node[:document].header? ident
end
inject(text) click to toggle source

Parses text and injects the syntax tree into the current node @since 0.5.0 @param [String] text the text to parse @return [Glyph::Interpreter] the interpreter instance used to parse text

# File lib/glyph/macro.rb, line 301
def inject(text)
        context = create_context
        interpreter = Glyph::Interpreter.new text, context
        subtree = interpreter.parse
        subtree[:source] = context[:source]
        @node << subtree
        interpreter
end
interpret(string) click to toggle source

Instantiates a Glyph::Interpreter and interprets a string @param [String] string the string to interpret @return [String] the interpreted output

# File lib/glyph/macro.rb, line 211
def interpret(string)
        @node[:escape] ? string : inject(string).document.output
end
macro_error(msg, klass=Glyph::MacroError) click to toggle source

Raises a macro error (preventing document post-processing) @param [String] msg the message to print @raise [Glyph::MacroError]

# File lib/glyph/macro.rb, line 182
def macro_error(msg, klass=Glyph::MacroError)
        @node[:document].errors << msg if @node[:document]
        raise klass.new(msg, self)
end
macro_todo(message) click to toggle source

Returns a todo message to include in the document in case of errors. @param [String] message the message to include in the document @return [String] the resulting todo message @since 0.2.0

# File lib/glyph/macro.rb, line 171
def macro_todo(message)
        draft = Glyph['document.draft']
        Glyph['document.draft'] = true unless draft
        res = interpret "![#{message}]"
        Glyph['document.draft'] = false unless draft
        res
end
macro_warning(msg, e=nil) click to toggle source

Prints a macro earning @param [String] msg the message to print @param [Exception] e the exception raised @since 0.2.0

# File lib/glyph/macro.rb, line 191
def macro_warning(msg, e=nil)
        if e.is_a?(Glyph::MacroError) then
                e.display 
        else
                message = "#{msg}\n    source: #{@source_name}\n    path: #{path}"
                if Glyph.debug? then
                        message << %{\n#{"-"*54}\n#{@node.to_s.gsub(/\t/, ' ')}\n#{"-"*54}} 
                        if e then
                                message << "\n"+"-"*20+"[ Backtrace: ]"+"-"*20
                                message << "\n"+e.backtrace.join("\n")
                                message << "\n"+"-"*54
                        end
                end
                Glyph.warning message
        end
end
param(n, options={:strip => true, :null_if_blank => true})
Alias for: parameter
parameter(n, options={:strip => true, :null_if_blank => true}) click to toggle source

Returns an evaluated macro parameter by index @param [Fixnum] n the index of the parameter @param [Hash] options a hash of options @option options [Boolean] :strip whether the value is stripped or not @return [String, nil] the value of the parameter @since 0.3.0

# File lib/glyph/macro.rb, line 76
def parameter(n, options={:strip => true, :null_if_blank => true})
        return @parameters[n] if @parameters && @parameters[n]
        return nil unless @node.parameter(n)
        @parameters = Array.new(@node.parameters.length) unless @parameters
        @parameters[n] = @node.parameter(n).evaluate(@node, :params => true).to_s
        @parameters[n].strip! if options[:strip]
        @parameters[n] = nil if @parameters[n].blank? && options[:null_if_blank]
        @parameters[n]
end
Also aliased as: param
parameters(options={:strip => true, :null_if_blank => true}) click to toggle source

Returns an array containing all evaluated macro parameters @param [Hash] options a hash of options @option options [Boolean] :strip whether the value is stripped or not @return [Array] the macro parameters @since 0.3.0

# File lib/glyph/macro.rb, line 107
def parameters(options={:strip => true, :null_if_blank => true})
        return @parameters if @parameters
        @parameters = []
        @node.parameters.each do |value|
                @parameters << value.evaluate(@node, :params => true)
                @parameters[@parameters.length-1].strip! if options[:strip]
                @parameters[@parameters.length-1] = nil if @parameters.last.blank? && options[:null_if_blank]
        end
        @parameters
end
Also aliased as: params
params(options={:strip => true, :null_if_blank => true})
Alias for: parameters
parse(text) click to toggle source

Parses text @since 0.5.0 @param [String] text the text to parse @return [Glyph::Node] the syntax tree generated by parsing

# File lib/glyph/macro.rb, line 314
def parse(text)
        Glyph::Interpreter.new(text, create_context).parse
end
path() click to toggle source

Returns the “path” to the macro within the syntax tree. @return [String] the macro path @since 0.3.0

# File lib/glyph/macro.rb, line 140
def path
        macros = []
        @node.ascend do |n|
                case 
                when n.is_a?(Glyph::MacroNode) then
                        if n[:name] == :"|xml|" then
                                name = "xml[#{n[:element]}]"
                        else
                                break if n[:name] == :include
                                name = n[:name].to_s
                        end
                when n.is_a?(Glyph::ParameterNode) then
                        if n.parent.parameters.length == 1 then
                                name = nil
                        else
                                name = n[:name].to_s
                        end
                when n.is_a?(Glyph::AttributeNode) then
                        name = "@#{n[:name]}"
                else
                        name = nil
                end
                macros << name
        end
        macros.reverse.compact.join('/')
end
placeholder(&block) click to toggle source

@see Glyph::Document#placeholder

# File lib/glyph/macro.rb, line 216
def placeholder(&block)
        @node[:document].placeholder &block
end
raw_attr(name)
Alias for: raw_attribute
raw_attribute(name) click to toggle source

Returns a Glyph code representation of the specified attribute @param [String, Symbol] name the name of the attribute @return [String, nil] the string representation of the attribute @since 0.3.0

# File lib/glyph/macro.rb, line 50
def raw_attribute(name)
        @node.attribute(name).contents.to_s rescue nil
end
Also aliased as: raw_attr
raw_param(n)
Alias for: raw_parameter
raw_parameter(n) click to toggle source

Returns a Glyph code representation of the specified parameter @param [Fixnum] n the index of the parameter @return [String, nil] the string representation of the parameter @since 0.3.0

# File lib/glyph/macro.rb, line 42
def raw_parameter(n)
        @node.parameter(n).contents.to_s rescue nil
end
Also aliased as: raw_param
raw_value() click to toggle source

Equivalent to Glyph::Macro#raw_parameter(0). @since 0.3.0

# File lib/glyph/macro.rb, line 133
def raw_value
        raw_parameter(0)
end
render(rep=nil, data=nil) click to toggle source

@since 0.5.0 Renders a macro representation @param [Symbol, String] rep the representation to render @param [Hash] data the data to pass to the representation

# File lib/glyph/macro.rb, line 254
def render(rep=nil, data=nil)
        rep ||= @name
        data ||= @data
        block = Glyph::REPS[rep.to_sym]
        macro_error "No macro representation for '#{rep}'", e unless block
        instance_exec(data, &block).to_s
end
snippet(key, value) click to toggle source

@see Glyph::Document#snippet

# File lib/glyph/macro.rb, line 241
def snippet(key, value)
        @node[:document].snippet key, value
end
snippet?(ident) click to toggle source

@see Glyph::Document#snippet?

# File lib/glyph/macro.rb, line 246
def snippet?(ident)
        @node[:document].snippet? ident
end
update_source(name, file=nil, topic=nil) click to toggle source

Resets the name of the updated source (call before calling Macro#interpret) @param [String] name the source name @param [String] file the source file @param [String] topic the topic file @since 0.3.0

# File lib/glyph/macro.rb, line 33
def update_source(name, file=nil, topic=nil)
        file ||= @node[:source][:file] rescue nil
        @updated_source = {:name => name, :file => file, :topic => topic}
end
value() click to toggle source

Equivalent to Glyph::Macro#parameter(0). @since 0.3.0

# File lib/glyph/macro.rb, line 127
def value
        parameter(0)
end

Private Instance Methods

create_context() click to toggle source
# File lib/glyph/macro.rb, line 327
def create_context
        context = {}
        context[:source] = @updated_source || @node[:source]
        context[:embedded] = true
        context[:document] = @node[:document]
        context
end