Class: Glyph::Macro

Inherits:
Object
  • Object
show all
Includes:
Validators, Utils
Defined in:
lib/glyph/macro.rb,
lib/glyph/macro_validators.rb

Overview

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.

Defined Under Namespace

Modules: Validators

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#clean_xml_document, #complex_output?, #current_output_setting, #debug, #error, #file_copy, #file_load, #file_write, #info, #load_files_from_dir, #macro_alias?, #macro_aliases_for, #macro_definition_for, #macro_eq?, #msg, #multiple_output_files?, #project?, #run_external_command, #titled_sections, #warning, #with_files_from, #yaml_dump, #yaml_load

Methods included from Validators

#exact_parameters, #max_parameters, #min_parameters, #no_mutual_inclusion_in, #no_parameters, #not_within, #required_attribute, #safety_check, #valid_xml_attribute, #valid_xml_element, #validate, #within

Constructor Details

#initialize(node) ⇒ Macro

Creates a new macro instance from a Node

Parameters:

  • node (Node)

    a node populated with macro data



17
18
19
20
21
22
23
24
25
# 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

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



13
14
15
# File 'lib/glyph/macro.rb', line 13

def name
  @name
end

#nodeObject (readonly)

Returns the value of attribute node.



13
14
15
# File 'lib/glyph/macro.rb', line 13

def node
  @node
end

#source_fileObject (readonly)

Returns the value of attribute source_file.



13
14
15
# File 'lib/glyph/macro.rb', line 13

def source_file
  @source_file
end

#source_nameObject (readonly)

Returns the value of attribute source_name.



13
14
15
# File 'lib/glyph/macro.rb', line 13

def source_name
  @source_name
end

#source_topicObject (readonly)

Returns the value of attribute source_topic.



13
14
15
# File 'lib/glyph/macro.rb', line 13

def source_topic
  @source_topic
end

Instance Method Details

#apply(text) ⇒ String

Performs parameter/attribute substitution and interprets text

Parameters:

  • text (String)

    the text to interpret

Returns:

  • (String)

    the interpreted output

Since:

  • 0.5.0



284
285
286
287
288
289
290
291
292
293
294
295
# 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

#attribute(name, options = {:strip => true, :null_if_blank => true}) ⇒ String? Also known as: attr

Returns an evaluated macro attribute by name

Parameters:

  • name (String, Symbol)

    the name of the attribute

  • options (Hash) (defaults to: {:strip => true, :null_if_blank => true})

    a hash of options

Options Hash (options):

  • :strip (Boolean)

    whether the value is stripped or not

Returns:

  • (String, nil)

    the value of the attribute

Since:

  • 0.3.0



60
61
62
63
64
65
66
67
68
# 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

#attributes(options = {:strip => true, :null_if_blank => true}) ⇒ Hash Also known as: attrs

Returns a hash containing all evaluated macro attributes

Parameters:

  • options (Hash) (defaults to: {:strip => true, :null_if_blank => true})

    a hash of options

Options Hash (options):

  • :strip (Boolean)

    whether the value is stripped or not

Returns:

  • (Hash)

    the macro attributes

Since:

  • 0.3.0



91
92
93
94
95
96
97
98
99
100
# 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

#bookmark(hash) ⇒ Object

See Also:



221
222
223
# File 'lib/glyph/macro.rb', line 221

def bookmark(hash)
	@node[:document].bookmark hash
end

#bookmark?(ident) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



226
227
228
# File 'lib/glyph/macro.rb', line 226

def bookmark?(ident)
	@node[:document].bookmark? ident
end

#dispatch(&block) ⇒ Object

Stores a block of code to be “dispatched” via macro composition # macro usage (Glyph) greet/Hello –[Outputs: Hello, World!] greet/GoodBye –[Outputs: Goodbye, John!]

Examples:

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

Since:

  • 0.5.0



275
276
277
278
# File 'lib/glyph/macro.rb', line 275

def dispatch(&block)
	@node[:dispatch] = block
	value
end

#expandObject

Executes a macro definition in the context of self



319
320
321
322
323
# 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) ⇒ Object

See Also:



236
237
238
# File 'lib/glyph/macro.rb', line 236

def header(hash)
	@node[:document].header hash
end

#header?(ident) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



231
232
233
# File 'lib/glyph/macro.rb', line 231

def header?(ident)
	@node[:document].header? ident
end

#inject(text) ⇒ Glyph::Interpreter

Parses text and injects the syntax tree into the current node

Parameters:

  • text (String)

    the text to parse

Returns:

Since:

  • 0.5.0



301
302
303
304
305
306
307
308
# 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) ⇒ String

Instantiates a Glyph::Interpreter and interprets a string

Parameters:

  • string (String)

    the string to interpret

Returns:

  • (String)

    the interpreted output



211
212
213
# File 'lib/glyph/macro.rb', line 211

def interpret(string)
	@node[:escape] ? string : inject(string).document.output
end

#macro_error(msg, klass = Glyph::MacroError) ⇒ Object

Raises a macro error (preventing document post-processing)

Parameters:

  • msg (String)

    the message to print

Raises:



182
183
184
185
# 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) ⇒ String

Returns a todo message to include in the document in case of errors.

Parameters:

  • message (String)

    the message to include in the document

Returns:

  • (String)

    the resulting todo message

Since:

  • 0.2.0



171
172
173
174
175
176
177
# 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) ⇒ Object

Prints a macro earning

Parameters:

  • msg (String)

    the message to print

  • e (Exception) (defaults to: nil)

    the exception raised

Since:

  • 0.2.0



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# 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

#parameter(n, options = {:strip => true, :null_if_blank => true}) ⇒ String? Also known as: param

Returns an evaluated macro parameter by index

Parameters:

  • n (Fixnum)

    the index of the parameter

  • options (Hash) (defaults to: {:strip => true, :null_if_blank => true})

    a hash of options

Options Hash (options):

  • :strip (Boolean)

    whether the value is stripped or not

Returns:

  • (String, nil)

    the value of the parameter

Since:

  • 0.3.0



76
77
78
79
80
81
82
83
84
# 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

#parameters(options = {:strip => true, :null_if_blank => true}) ⇒ Array Also known as: params

Returns an array containing all evaluated macro parameters

Parameters:

  • options (Hash) (defaults to: {:strip => true, :null_if_blank => true})

    a hash of options

Options Hash (options):

  • :strip (Boolean)

    whether the value is stripped or not

Returns:

  • (Array)

    the macro parameters

Since:

  • 0.3.0



107
108
109
110
111
112
113
114
115
116
# 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

#parse(text) ⇒ Glyph::Node

Parses text

Parameters:

  • text (String)

    the text to parse

Returns:

  • (Glyph::Node)

    the syntax tree generated by parsing

Since:

  • 0.5.0



314
315
316
# File 'lib/glyph/macro.rb', line 314

def parse(text)
	Glyph::Interpreter.new(text, create_context).parse
end

#pathString

Returns the “path” to the macro within the syntax tree.

Returns:

Since:

  • 0.3.0



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# 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) ⇒ Object



216
217
218
# File 'lib/glyph/macro.rb', line 216

def placeholder(&block)
	@node[:document].placeholder &block
end

#raw_attribute(name) ⇒ String? Also known as: raw_attr

Returns a Glyph code representation of the specified attribute

Parameters:

Returns:

  • (String, nil)

    the string representation of the attribute

Since:

  • 0.3.0



50
51
52
# File 'lib/glyph/macro.rb', line 50

def raw_attribute(name)
	@node.attribute(name).contents.to_s rescue nil
end

#raw_parameter(n) ⇒ String? Also known as: raw_param

Returns a Glyph code representation of the specified parameter

Parameters:

  • n (Fixnum)

    the index of the parameter

Returns:

  • (String, nil)

    the string representation of the parameter

Since:

  • 0.3.0



42
43
44
# File 'lib/glyph/macro.rb', line 42

def raw_parameter(n)
	@node.parameter(n).contents.to_s rescue nil
end

#raw_valueObject

Equivalent to Glyph::Macro#raw_parameter(0).

Since:

  • 0.3.0



133
134
135
# File 'lib/glyph/macro.rb', line 133

def raw_value
	raw_parameter(0)
end

#render(rep = nil, data = nil) ⇒ Object

Renders a macro representation

Parameters:

  • rep (Symbol, String) (defaults to: nil)

    the representation to render

  • data (Hash) (defaults to: nil)

    the data to pass to the representation

Since:

  • 0.5.0



254
255
256
257
258
259
260
# 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) ⇒ Object

See Also:



241
242
243
# File 'lib/glyph/macro.rb', line 241

def snippet(key, value)
	@node[:document].snippet key, value
end

#snippet?(ident) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



246
247
248
# File 'lib/glyph/macro.rb', line 246

def snippet?(ident)
	@node[:document].snippet? ident
end

#update_source(name, file = nil, topic = nil) ⇒ Object

Resets the name of the updated source (call before calling Macro#interpret)

Parameters:

  • name (String)

    the source name

  • file (String) (defaults to: nil)

    the source file

  • topic (String) (defaults to: nil)

    the topic file

Since:

  • 0.3.0



33
34
35
36
# 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

#valueObject

Equivalent to Glyph::Macro#parameter(0).

Since:

  • 0.3.0



127
128
129
# File 'lib/glyph/macro.rb', line 127

def value
	parameter(0)
end