Module: WLang
- Defined in:
- lib/wlang.rb,
lib/wlang/rule.rb,
lib/wlang/parser.rb,
lib/wlang/errors.rb,
lib/wlang/encoder.rb,
lib/wlang/version.rb,
lib/wlang/dialect.rb,
lib/wlang/rule_set.rb,
lib/wlang/template.rb,
lib/wlang/hash_scope.rb,
lib/wlang/dialect_dsl.rb,
lib/wlang/encoder_set.rb,
lib/wlang/parser_state.rb,
lib/wlang/wlang_command.rb,
lib/wlang/dialect_loader.rb,
lib/wlang/hosted_language.rb,
lib/wlang/intelligent_buffer.rb,
lib/wlang/dialects/sql_dialect.rb,
lib/wlang/dialects/yaml_dialect.rb,
lib/wlang/dialects/rdoc_dialect.rb,
lib/wlang/dialects/ruby_dialect.rb,
lib/wlang/wlang_command_options.rb,
lib/wlang/rulesets/basic_ruleset.rb,
lib/wlang/rulesets/ruleset_utils.rb,
lib/wlang/dialects/xhtml_dialect.rb,
lib/wlang/dialects/hosted_dialect.rb,
lib/wlang/rulesets/context_ruleset.rb,
lib/wlang/dialects/coderay_dialect.rb,
lib/wlang/dialects/redcloth_dialect.rb,
lib/wlang/rulesets/encoding_ruleset.rb,
lib/wlang/rulesets/buffering_ruleset.rb,
lib/wlang/dialects/bluecloth_dialect.rb,
lib/wlang/dialects/plain_text_dialect.rb,
lib/wlang/rulesets/imperative_ruleset.rb
Overview
Main module of the wlang code generator/template engine, providing a facade on wlang tools. See also the Roadmap section of README to enter the library.
Defined Under Namespace
Modules: Version Classes: Dialect, Encoder, EncoderSet, Error, EvalError, HashScope, HostedLanguage, IntelligentBuffer, ParseError, Parser, Rule, RuleSet, Template, UndefinedVariableError, WLangCommand
Constant Summary
- FILE_EXTENSION_REGEXP =
Regular expression for file extensions
/^\.[a-zA-Z0-9]+$/- DIALECT_NAME_REGEXP_STR =
Reusable string for building dialect name based regexps
"[-a-z]+"- DIALECT_NAME_REGEXP =
Regular expression for dialect names.
/^([-a-z]+)*$/- QUALIFIED_DIALECT_NAME_REGEXP_STR =
Reusable string for building dialect name based regexps
"[-a-z]+([\/][-a-z]+)*"- QUALIFIED_DIALECT_NAME_REGEXP =
Regular expression for dialect qualified names. Dialect qualified names are '/' seperated names, where a name is [-a-z]+.
Examples: wlang/xhtml/uri, wlang/plain-text, …
/^[-a-z]+([\/][-a-z]+)*$/- FILE_EXTENSIONS =
Provides installed extension => dialect mappings. File extensions (keys) contain the first dot (like .wtpl, .whtml, …). Dialects (values) are qualified names, not Dialect instances.
{}
- ENCODER_NAME_REGEXP_STR =
Reusable string for building encoder name based regexps
"[-a-z]+"- ENCODER_NAME_REGEXP =
Regular expression for encoder names.
/^([-a-z]+)*$/- QUALIFIED_ENCODER_NAME_REGEXP_STR =
Reusable string for building qualified encoder name based regexps
"[-a-z]+([\/][-a-z]+)*"- QUALIFIED_ENCODER_NAME_REGEXP =
Regular expression for encoder qualified names. Encoder qualified names are '/' seperated names, where a name is [-a-z]+.
Examples: xhtml/entities-encoding, sql/single-quoting, …
/^([-a-z]+)([\/][-a-z]+)*$/- DATA_EXTENSIONS =
Provides installed extension => data loader mapping. File extensions (keys) contain the first dot (like .wtpl, .whtml, …). Data loades are Proc instances that take a single |uri| argument.
{}
- VERSION =
Version.to_s
Class Method Summary (collapse)
-
+ (Object) check_file_extension(ext)
Checks that ext is a valid file extension or raises an ArgumentError.
-
+ (Object) check_qualified_dialect_name(name)
Checks that name is a valid qualified dialect name or raises an ArgumentError.
-
+ (Object) check_qualified_encoder_name(name)
Checks that name is a valid qualified encoder name or raises an ArgumentError.
-
+ (Object) check_readable_file(file)
Raises an ArgumentError unless file is a real readable file.
-
+ (Object) data_loader(*exts, &block)
Adds a data loader for file extensions.
-
+ (Object) dialect(name, *extensions, &block)
Ensures, installs or query a dialect.
-
+ (Object) dialect_tree
Returns the root of the dialect tree.
-
+ (Object) encode(source, encoder_qname, options = {})
Shortcut for.
-
+ (Object) encoder(name)
Returns an encoder installed under a qualified name.
-
+ (Object) file_extension_map(extension, dialect_qname)
Maps a file extension to a dialect qualified name.
-
+ (Object) file_instantiate(file, context = nil, dialect = nil, block_symbols = :braces)
Instantiates a file written in some wlang dialect, using a given context (providing instantiation data).
-
+ (Object) file_template(file, dialect = nil, block_symbols = :braces)
Factors a template instance for a given file, optional dialect (if nil is passed, the dialect is infered from the extension) and block symbols (default to :braces).
-
+ (Object) infer_dialect(uri)
Infers a dialect from a file extension.
-
+ (Object) instantiate(source, context = {}, dialect = "wlang/active-string", block_symbols = :braces)
Instantiates a template written in some wlang dialect, using a given context (providing instantiation data).
-
+ (Object) load_data(uri, extension = nil)
Loads data from a given URI.
-
+ (Object) template(source, dialect = 'wlang/active-string', block_symbols = :braces)
Factors a template instance for a given string source, dialect (default to 'wlang/active-string') and block symbols (default to :braces).
Class Method Details
+ (Object) check_file_extension(ext)
Checks that ext is a valid file extension or raises an ArgumentError
30 31 32 33 |
# File 'lib/wlang.rb', line 30 def self.check_file_extension(ext) raise ArgumentError, "Invalid file extension #{ext} (/^\.[a-zA-Z-0-9]+$/ expected)", caller\ unless FILE_EXTENSION_REGEXP =~ ext end |
+ (Object) check_qualified_dialect_name(name)
Checks that name is a valid qualified dialect name or raises an ArgumentError
59 60 61 62 |
# File 'lib/wlang.rb', line 59 def self.check_qualified_dialect_name(name) raise ArgumentError, "Invalid dialect qualified name '#{name}' (/^[-a-z]+([\/][-a-z]+)*$/ expected)", caller\ unless QUALIFIED_DIALECT_NAME_REGEXP =~ name end |
+ (Object) check_qualified_encoder_name(name)
Checks that name is a valid qualified encoder name or raises an ArgumentError
196 197 198 199 |
# File 'lib/wlang.rb', line 196 def self.check_qualified_encoder_name(name) raise ArgumentError, "Invalid encoder qualified name #{name} (/^[-a-z]+([\/][-a-z]+)*$/ expected)", caller\ unless QUALIFIED_ENCODER_NAME_REGEXP =~ name end |
+ (Object) check_readable_file(file)
Raises an ArgumentError unless file is a real readable file
36 37 38 39 |
# File 'lib/wlang.rb', line 36 def self.check_readable_file(file) raise ArgumentError, "File #{file} is not readable or not a file"\ unless File.exists?(file) and File.file?(file) and File.readable?(file) end |
+ (Object) data_loader(*exts, &block)
Adds a data loader for file extensions. A data loader is a block of arity 1, taking a file as parameter and returning data decoded from the file.
Example:
# We have some MyXMLDataLoader class that is able to create a ruby object
# from things expressed .xml files
WLang::data_loader('.xml') {|file|
MyXMLDataLaoder.parse_file(file)
}
# Later in a template (see the buffering ruleset that gives you <<={...})
<<={resources.xml as resources}
<html>
*{resources as r}{
...
}
</html>
This method raises an ArgumentError if
-
no block is given or if the block is not of arity 1
-
any of the file extensions in exts is invalid
270 271 272 273 274 275 |
# File 'lib/wlang.rb', line 270 def self.data_loader(*exts, &block) raise(ArgumentError, "WLang::data_loader expects a block") unless block_given? raise(ArgumentError, "WLang::data_loader expects a block of arity 1") unless block.arity==1 exts.each {|ext| check_file_extension(ext) } exts.each {|ext| DATA_EXTENSIONS[ext] = block} end |
+ (Object) dialect(name, *extensions, &block)
Ensures, installs or query a dialect.
When name is a Dialect, returns it immediately. This helper is provided for methods that accept both qualified dialect name and dialect instance arguments. Calling WLang::dialect(arg) ensures that the result will be a Dialect instance in all cases (if the arg is valid).
Example:
# This methods does something with a wlang dialect. _dialect_ argument may
# be a Dialect instance or a qualified dialect name.
def my_method(dialect = 'wlang/active-string')
# ensures the Dialect instance or raises an ArgumentError if the dialect
# qualified name is invalid (returns nil otherwise !)
dialect = WLang::dialect(dialect)
end
When called with a block, this method installs a wlang dialect under name (which cannot be qualified). Extensions can be provided to let wlang automatically recognize files that are expressed in this dialect. The block is interpreted as code in the dialect DSL (domain specific language, see WLang::Dialect::DSL). Returns nil in this case.
Example:
# New dialect with 'my_dialect' qualified name and automatically installed
# to recognize '.wmyd' file extensions
WLang::dialect("my_dialect", '.wmyd') do
# see WLang::Dialect::DSL for this part of the code
end
When called without a block this method returns a Dialect instance installed under name (which can be a qualified name). Extensions are ignored in this case. Returns nil if not found, a Dialect instance otherwise.
Example:
# Lookup for the 'wlang/xhtml' dialect
wxhtml = WLang::dialect('wlang/xhtml')
This method raises an ArgumentError if
-
name is not a valid dialect qualified name
-
any of the file extension in extensions is invalid
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/wlang.rb', line 159 def self.dialect(name, *extensions, &block) # first case, already a dialect return name if Dialect===name # other cases, argument validations check_qualified_dialect_name(name) extensions.each {|ext| check_file_extension(ext)} if block_given? # first case, dialect installation raise "Unsupported qualified names in dialect installation"\ unless name.index('/').nil? Dialect::DSL.new(@dialect).dialect(name, *extensions, &block) else # second case, dialect lookup @dialect.dialect(name) end end |
+ (Object) dialect_tree
Returns the root of the dialect tree
78 79 80 |
# File 'lib/wlang.rb', line 78 def self.dialect_tree @dialect end |
+ (Object) encode(source, encoder_qname, options = {})
Shortcut for
WLang::encoder(encoder_qname).encode(source, )
This method raises an ArgumentError
-
if source is not a String
-
if the encoder qualified name is invalid
It raises a WLang::Error if the encoder cannot be found
229 230 231 232 233 234 235 |
# File 'lib/wlang.rb', line 229 def self.encode(source, encoder_qname, = {}) raise ArgumentError, "String expected for source" unless String===source check_qualified_encoder_name(encoder_qname) encoder = WLang::encoder(encoder_qname) raise WLang::Error, "Unable to find encoder #{encoder_qname}" if encoder.nil? encoder.encode(source, ) end |
+ (Object) encoder(name)
Returns an encoder installed under a qualified name. Returns nil if not found. If name is already an Encoder instance, returns it immediately.
Example:
encoder = WLang::encoder('xhtml/entities-encoding')
encoder.encode('something that needs html entities escaping')
This method raises an ArgumentError if name is not a valid encoder qualified name.
213 214 215 216 |
# File 'lib/wlang.rb', line 213 def self.encoder(name) check_qualified_encoder_name(name) @dialect.encoder(name) end |
+ (Object) file_extension_map(extension, dialect_qname)
Maps a file extension to a dialect qualified name.
Example:
# We create an 'example' dialect
WLang::dialect('example') do
# see WLang::dialect about creating a dialect
end
# We map .wex file extensions to our new dialect
WLang::file_extension_map('.wex', 'example')
This method raises an ArgumentError if the extension or dialect qualified name is not valid.
98 99 100 101 102 |
# File 'lib/wlang.rb', line 98 def self.file_extension_map(extension, dialect_qname) check_file_extension(extension) check_qualified_dialect_name(dialect_qname) WLang::FILE_EXTENSIONS[extension] = dialect_qname end |
+ (Object) file_instantiate(file, context = nil, dialect = nil, block_symbols = :braces)
Instantiates a file written in some wlang dialect, using a given context (providing instantiation data). If dialect is nil, tries to infer it from the file extension; otherwise dialect is expected to be a qualified dialect name or a Dialect instance. See instantiate about block_symbols.
Examples:
Wlang.file_instantiate "template.wtpl", {"who" => "Mr. Jones"}
Wlang.file_instantiate "template.xxx", {"who" => "Mr. Jones"}, "wlang/xhtml"
This method raises an ArgumentError if
-
file is not a readable file
-
context is not nil or a Hash
-
dialect is not a valid dialect qualified name, Dialect instance or nil
-
block_symbols is not in [:braces, :brackets, :parentheses]
It raises a WLang::Error
-
if no dialect can be infered from the file extension (if dialect was nil)
-
something goes wrong during instantiation (see WLang::Error and subclasses)
401 402 403 404 |
# File 'lib/wlang.rb', line 401 def self.file_instantiate(file, context = nil, dialect = nil, block_symbols = :braces) raise ArgumentError, "Hash expected for context argument" unless (context.nil? or Hash===context) file_template(file, dialect, block_symbols).instantiate(context || {}).to_s end |
+ (Object) file_template(file, dialect = nil, block_symbols = :braces)
Factors a template instance for a given file, optional dialect (if nil is passed, the dialect is infered from the extension) and block symbols (default to :braces)
Example:
# the file index.wtpl is a wlang source code in 'wlang/xhtml' dialect
# (automatically infered from file extension)
template = WLang::template('index.wtpl')
puts template.instantiate(:who => 'world') # puts 'Hello world!'
This method raises an ArgumentError
-
if file does not exists, is not a file or is not readable
-
if dialect is not a valid qualified dialect name, Dialect instance, or nil
-
block_symbols is not in [:braces, :brackets, :parentheses]
It raises a WLang::Error
-
if no dialect can be infered from the file extension (if dialect was nil)
339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/wlang.rb', line 339 def self.file_template(file, dialect = nil, block_symbols = :braces) check_readable_file(file) # Check the dialect dialect = self.infer_dialect(file) if dialect.nil? raise WLang::Error, "No known dialect for file extension '#{File.extname(file)}'\n"\ "Known extensions are: " << WLang::FILE_EXTENSIONS.keys.join(", ") if dialect.nil? # Build the template now template = template(File.read(file), dialect, block_symbols) template.source_file = file template end |
+ (Object) infer_dialect(uri)
Infers a dialect from a file extension. Returns nil if no dialect is currently mapped to the given extension (see file_extension_map)
This method never raises errors.
110 111 112 |
# File 'lib/wlang.rb', line 110 def self.infer_dialect(uri) WLang::FILE_EXTENSIONS[File.extname(uri)] end |
+ (Object) instantiate(source, context = {}, dialect = "wlang/active-string", block_symbols = :braces)
Instantiates a template written in some wlang dialect, using a given context (providing instantiation data). Returns instantiatiation as a String. If you want to instantiate the template in a specific buffer (a file or console for example), use Template. template is expected to be a String and context a Hash. To know available dialects, see WLang::StandardDialects. block_symbols can be :braces ('and '' pairs), :brackets ('[' and ']' pairs) or :parentheses ('(' and ')' pairs).
Examples:
WLang.instantiate "Hello ${who} !", {"who" => "Mr. Jones"}
WLang.instantiate "SELECT * FROM people WHERE name='{name}'", {"who" => "Mr. O'Neil"}, "wlang/sql"
WLang.instantiate "Hello $(who) !", {"who" => "Mr. Jones"}, "wlang/active-string", :parentheses
This method raises an ArgumentError if
-
source is not a String
-
context is not nil or a Hash
-
dialect is not a valid dialect qualified name or Dialect instance
-
block_symbols is not in [:braces, :brackets, :parentheses]
It raises a WLang::Error
-
something goes wrong during instantiation (see WLang::Error and subclasses)
376 377 378 379 |
# File 'lib/wlang.rb', line 376 def self.instantiate(source, context = {}, dialect="wlang/active-string", block_symbols = :braces) raise ArgumentError, "Hash expected for context argument" unless (context.nil? or Hash===context) template(source, dialect, block_symbols).instantiate(context || {}).to_s end |
+ (Object) load_data(uri, extension = nil)
Loads data from a given URI. If extension is omitted, tries to infer it from the uri, otherwise use it directly. Returns loaded data.
This method raises a WLang::Error if no data loader is installed for the found extension. It raises an ArgumentError if the file extension is invalid.
284 285 286 287 288 289 |
# File 'lib/wlang.rb', line 284 def self.load_data(uri, extension=nil) check_file_extension(extension = extension.nil? ? File.extname(uri) : extension) loader = DATA_EXTENSIONS[extension] raise ::WLang::Error, "No data loader for #{extension}" if loader.nil? loader.call(uri) end |
+ (Object) template(source, dialect = 'wlang/active-string', block_symbols = :braces)
Factors a template instance for a given string source, dialect (default to 'wlang/active-string') and block symbols (default to :braces)
Example:
# The template source code must be interpreted as wlang/xhtml
template = WLang::template('<p>Hello ${who}!</p>', 'wlang/xhtml')
str = template.instantiate(:hello => 'world')
# We may also use other block symbols...
template = WLang::template('<p>Hello $(who)!</p>', 'wlang/xhtml', :parentheses)
str = template.instantiate(:hello => 'world')
This method raises an ArgumentError if
-
source is not a String
-
dialect is not a valid dialect qualified name or Dialect instance
-
block_symbols is not in [:braces, :brackets, :parentheses]
312 313 314 315 316 317 |
# File 'lib/wlang.rb', line 312 def self.template(source, dialect = 'wlang/active-string', block_symbols = :braces) raise ArgumentError, "String expected for source" unless String===source raise ArgumentError, "Invalid symbols for block #{block_symbols}"\ unless ::WLang::Template::BLOCK_SYMBOLS.keys.include?(block_symbols) template = Template.new(source, WLang::dialect(dialect), block_symbols) end |