wlang 0.10.2 → 2.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +3 -121
- data/Gemfile +23 -1
- data/Gemfile.lock +32 -28
- data/LICENCE.md +18 -21
- data/Manifest.txt +4 -5
- data/README.md +100 -174
- data/Rakefile +1 -13
- data/bin/wlang +3 -29
- data/lib/wlang.rb +21 -394
- data/lib/wlang/command.rb +94 -0
- data/lib/wlang/compiler.rb +78 -0
- data/lib/wlang/compiler/autospacing.rb +60 -0
- data/lib/wlang/compiler/dialect_enforcer.rb +91 -0
- data/lib/wlang/compiler/filter.rb +32 -0
- data/lib/wlang/compiler/grammar.citrus +67 -0
- data/lib/wlang/compiler/parser.rb +26 -0
- data/lib/wlang/compiler/proc_call_removal.rb +15 -0
- data/lib/wlang/compiler/static_merger.rb +28 -0
- data/lib/wlang/compiler/strconcat_flattener.rb +25 -0
- data/lib/wlang/compiler/to_ruby_abstraction.rb +22 -0
- data/lib/wlang/compiler/to_ruby_code.rb +55 -0
- data/lib/wlang/dialect.rb +40 -237
- data/lib/wlang/dialect/dispatching.rb +51 -0
- data/lib/wlang/dialect/evaluation.rb +30 -0
- data/lib/wlang/dialect/tags.rb +50 -0
- data/lib/wlang/dummy.rb +32 -0
- data/lib/wlang/html.rb +106 -0
- data/lib/wlang/loader.rb +6 -0
- data/lib/wlang/mustang.rb +90 -0
- data/lib/wlang/scope.rb +57 -0
- data/lib/wlang/scope/binding_scope.rb +18 -0
- data/lib/wlang/scope/object_scope.rb +25 -0
- data/lib/wlang/scope/proxy_scope.rb +18 -0
- data/lib/wlang/scope/root_scope.rb +24 -0
- data/lib/wlang/template.rb +16 -86
- data/lib/wlang/version.rb +9 -8
- data/spec/fixtures/dialect/foobar.rb +31 -0
- data/spec/fixtures/dialect/upcasing.rb +13 -0
- data/spec/fixtures/templates/hello.tpl +1 -0
- data/spec/integration/examples/1-basics.txt +65 -0
- data/spec/integration/examples/2-imperative.txt +51 -0
- data/spec/integration/examples/3-partials.txt +76 -0
- data/spec/integration/examples/4-recursion.txt +16 -0
- data/spec/integration/html/test_ampersand.rb +15 -0
- data/spec/integration/html/test_bang.rb +38 -0
- data/spec/integration/html/test_caret.rb +33 -0
- data/spec/integration/html/test_dollar.rb +16 -0
- data/spec/integration/html/test_greater.rb +23 -0
- data/spec/integration/html/test_modulo.rb +16 -0
- data/spec/integration/html/test_plus.rb +48 -0
- data/spec/integration/html/test_question.rb +33 -0
- data/spec/integration/html/test_sharp.rb +21 -0
- data/spec/integration/html/test_slash.rb +16 -0
- data/spec/integration/html/test_star.rb +37 -0
- data/spec/integration/test_dummy.rb +51 -0
- data/spec/integration/test_examples.rb +29 -0
- data/spec/integration/test_mustang.rb +120 -0
- data/spec/integration/test_readme.rb +56 -0
- data/spec/integration/test_upcasing.rb +22 -0
- data/spec/spec_helper.rb +62 -1
- data/spec/test_wlang.rb +101 -0
- data/spec/unit/compiler/autospacing/test_right_strip.rb +30 -0
- data/spec/unit/compiler/autospacing/test_unindent.rb +30 -0
- data/spec/unit/compiler/test_dialect_enforcer.rb +168 -0
- data/spec/unit/compiler/test_grammar.rb +207 -0
- data/spec/unit/compiler/test_parser.rb +69 -0
- data/spec/unit/compiler/test_proc_call_removal.rb +24 -0
- data/spec/unit/compiler/test_static_merger.rb +29 -0
- data/spec/unit/compiler/test_strconcat_flattener.rb +30 -0
- data/spec/unit/compiler/test_to_ruby_abstraction.rb +59 -0
- data/spec/unit/compiler/test_to_ruby_code.rb +24 -0
- data/spec/unit/dialect/test_compile.rb +52 -0
- data/spec/unit/dialect/test_dispatching.rb +19 -0
- data/spec/unit/dialect/test_evaluate.rb +41 -0
- data/spec/unit/dialect/test_render.rb +33 -0
- data/spec/unit/dialect/test_tags.rb +32 -0
- data/spec/unit/dialect/test_with_scope.rb +18 -0
- data/spec/unit/scope/test_binding_scope.rb +27 -0
- data/spec/unit/scope/test_coerce.rb +22 -0
- data/spec/unit/scope/test_object_scope.rb +38 -0
- data/spec/unit/scope/test_proxy_scope.rb +22 -0
- data/spec/unit/scope/test_root_scope.rb +22 -0
- data/spec/unit/test_assumptions.rb +29 -0
- data/spec/unit/test_scope.rb +57 -0
- data/tasks/debug_mail.rake +42 -45
- data/tasks/gem.rake +22 -17
- data/tasks/spec_test.rake +9 -17
- data/tasks/unit_test.rake +11 -12
- data/tasks/yard.rake +13 -13
- data/wlang.gemspec +36 -32
- data/wlang.noespec +27 -35
- metadata +268 -451
- data/doc/specification/about.rdoc +0 -61
- data/doc/specification/analytics.wtpl +0 -13
- data/doc/specification/dialect.wtpl +0 -14
- data/doc/specification/dialects.wtpl +0 -3
- data/doc/specification/examples.rb +0 -3
- data/doc/specification/glossary.wtpl +0 -14
- data/doc/specification/hosting.rdoc +0 -0
- data/doc/specification/overview.rdoc +0 -116
- data/doc/specification/rulesets.wtpl +0 -87
- data/doc/specification/specification.css +0 -53
- data/doc/specification/specification.html +0 -1690
- data/doc/specification/specification.js +0 -8
- data/doc/specification/specification.wtpl +0 -42
- data/doc/specification/specification.yml +0 -432
- data/doc/specification/symbols.wtpl +0 -16
- data/lib/wlang/dialect_dsl.rb +0 -141
- data/lib/wlang/dialect_loader.rb +0 -74
- data/lib/wlang/dialects/bluecloth_dialect.rb +0 -16
- data/lib/wlang/dialects/coderay_dialect.rb +0 -45
- data/lib/wlang/dialects/hosted_dialect.rb +0 -50
- data/lib/wlang/dialects/plain_text_dialect.rb +0 -69
- data/lib/wlang/dialects/rdoc_dialect.rb +0 -33
- data/lib/wlang/dialects/redcloth_dialect.rb +0 -16
- data/lib/wlang/dialects/ruby_dialect.rb +0 -118
- data/lib/wlang/dialects/sql_dialect.rb +0 -38
- data/lib/wlang/dialects/standard_dialects.rb +0 -181
- data/lib/wlang/dialects/xhtml_dialect.rb +0 -63
- data/lib/wlang/dialects/yaml_dialect.rb +0 -30
- data/lib/wlang/encoder.rb +0 -62
- data/lib/wlang/encoder_set.rb +0 -122
- data/lib/wlang/errors.rb +0 -80
- data/lib/wlang/ext/hash_methodize.rb +0 -13
- data/lib/wlang/ext/string.rb +0 -44
- data/lib/wlang/hash_scope.rb +0 -89
- data/lib/wlang/hosted_language.rb +0 -146
- data/lib/wlang/intelligent_buffer.rb +0 -94
- data/lib/wlang/parser.rb +0 -332
- data/lib/wlang/parser_state.rb +0 -94
- data/lib/wlang/rule.rb +0 -66
- data/lib/wlang/rule_set.rb +0 -106
- data/lib/wlang/rulesets/basic_ruleset.rb +0 -83
- data/lib/wlang/rulesets/buffering_ruleset.rb +0 -115
- data/lib/wlang/rulesets/context_ruleset.rb +0 -111
- data/lib/wlang/rulesets/encoding_ruleset.rb +0 -73
- data/lib/wlang/rulesets/imperative_ruleset.rb +0 -132
- data/lib/wlang/rulesets/ruleset_utils.rb +0 -317
- data/lib/wlang/wlang_command.rb +0 -51
- data/lib/wlang/wlang_command_options.rb +0 -163
- data/spec/basic_object.spec +0 -40
- data/spec/coderay_dialect.spec +0 -8
- data/spec/dialect/apply_post_transform.spec +0 -16
- data/spec/global_extensions.rb +0 -2
- data/spec/hash_scope.spec +0 -76
- data/spec/redcloth_dialect.spec +0 -24
- data/spec/test_all.rb +0 -8
- data/spec/wlang.spec +0 -53
- data/spec/wlang_spec.rb +0 -8
- data/spec/xhtml_dialect.spec +0 -22
- data/tasks/genspec.rake +0 -5
- data/test/blackbox/basic/execution_1.exp +0 -1
- data/test/blackbox/basic/execution_1.tpl +0 -1
- data/test/blackbox/basic/execution_2.exp +0 -1
- data/test/blackbox/basic/execution_2.tpl +0 -1
- data/test/blackbox/basic/execution_3.exp +0 -1
- data/test/blackbox/basic/execution_3.tpl +0 -1
- data/test/blackbox/basic/execution_4.exp +0 -1
- data/test/blackbox/basic/execution_4.tpl +0 -1
- data/test/blackbox/basic/inclusion_1.exp +0 -1
- data/test/blackbox/basic/inclusion_1.tpl +0 -1
- data/test/blackbox/basic/inclusion_2.exp +0 -1
- data/test/blackbox/basic/inclusion_2.tpl +0 -1
- data/test/blackbox/basic/injection_1.exp +0 -1
- data/test/blackbox/basic/injection_1.tpl +0 -1
- data/test/blackbox/basic/injection_2.exp +0 -1
- data/test/blackbox/basic/injection_2.tpl +0 -1
- data/test/blackbox/basic/modulation_1.exp +0 -1
- data/test/blackbox/basic/modulation_1.tpl +0 -1
- data/test/blackbox/basic/modulation_2.exp +0 -1
- data/test/blackbox/basic/modulation_2.tpl +0 -1
- data/test/blackbox/basic/recursive_app_1.exp +0 -1
- data/test/blackbox/basic/recursive_app_1.tpl +0 -1
- data/test/blackbox/basic/recursive_app_2.exp +0 -1
- data/test/blackbox/basic/recursive_app_2.tpl +0 -1
- data/test/blackbox/buffering/data_1.rb +0 -1
- data/test/blackbox/buffering/data_assignment_1.exp +0 -1
- data/test/blackbox/buffering/data_assignment_1.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_2.exp +0 -1
- data/test/blackbox/buffering/data_assignment_2.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_3.exp +0 -1
- data/test/blackbox/buffering/data_assignment_3.tpl +0 -1
- data/test/blackbox/buffering/data_assignment_4.exp +0 -1
- data/test/blackbox/buffering/data_assignment_4.tpl +0 -1
- data/test/blackbox/buffering/input_1.exp +0 -1
- data/test/blackbox/buffering/input_1.tpl +0 -1
- data/test/blackbox/buffering/input_2.exp +0 -1
- data/test/blackbox/buffering/input_2.tpl +0 -1
- data/test/blackbox/buffering/input_3.exp +0 -1
- data/test/blackbox/buffering/input_3.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion.exp +0 -1
- data/test/blackbox/buffering/input_inclusion.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_1.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_1.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_2.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_2.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_3.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_3.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_4.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_4.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_5.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_5.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_6.exp +0 -1
- data/test/blackbox/buffering/input_inclusion_6.tpl +0 -1
- data/test/blackbox/buffering/input_inclusion_7.exp +0 -0
- data/test/blackbox/buffering/input_inclusion_7.tpl +0 -1
- data/test/blackbox/buffering/text_1.txt +0 -1
- data/test/blackbox/buffering/wlang.txt +0 -1
- data/test/blackbox/context/assignment_1.exp +0 -1
- data/test/blackbox/context/assignment_1.tpl +0 -1
- data/test/blackbox/context/assignment_2.exp +0 -1
- data/test/blackbox/context/assignment_2.tpl +0 -1
- data/test/blackbox/context/assignment_3.exp +0 -2
- data/test/blackbox/context/assignment_3.tpl +0 -2
- data/test/blackbox/context/assignment_4.exp +0 -1
- data/test/blackbox/context/assignment_4.tpl +0 -1
- data/test/blackbox/context/block_assignment_1.exp +0 -1
- data/test/blackbox/context/block_assignment_1.tpl +0 -1
- data/test/blackbox/context/block_assignment_2.exp +0 -1
- data/test/blackbox/context/block_assignment_2.tpl +0 -1
- data/test/blackbox/context/modulo_assignment_1.exp +0 -1
- data/test/blackbox/context/modulo_assignment_1.tpl +0 -1
- data/test/blackbox/context/modulo_assignment_2.exp +0 -1
- data/test/blackbox/context/modulo_assignment_2.tpl +0 -1
- data/test/blackbox/data_1.rb +0 -1
- data/test/blackbox/postblock/hello.exp +0 -1
- data/test/blackbox/postblock/hello.pre +0 -1
- data/test/blackbox/postblock/hello.tpl +0 -1
- data/test/blackbox/postblock/hello_input_inclusion.exp +0 -1
- data/test/blackbox/postblock/hello_input_inclusion.tpl +0 -1
- data/test/blackbox/postblock/hello_to_authors.exp +0 -1
- data/test/blackbox/postblock/hello_to_authors.tpl +0 -1
- data/test/blackbox/poststring/hello.exp +0 -1
- data/test/blackbox/poststring/hello.tpl +0 -1
- data/test/blackbox/test_all.rb +0 -70
- data/test/standard_dialects/ruby/data.rb +0 -7
- data/test/standard_dialects/ruby/inclusion.exp +0 -6
- data/test/standard_dialects/ruby/inclusion.tpl +0 -6
- data/test/standard_dialects/test_all.rb +0 -29
- data/test/standard_dialects/yaml/assumptions_test.rb +0 -13
- data/test/standard_dialects/yaml/data.rb +0 -3
- data/test/standard_dialects/yaml/inclusion_1.exp +0 -7
- data/test/standard_dialects/yaml/inclusion_1.tpl +0 -2
- data/test/standard_dialects/yaml/inclusion_2.exp +0 -5
- data/test/standard_dialects/yaml/inclusion_2.tpl +0 -3
- data/test/unit/test_all.rb +0 -9
- data/test/unit/wlang/anagram_bugs_test.rb +0 -111
- data/test/unit/wlang/basic_ruleset_test.rb +0 -52
- data/test/unit/wlang/buffering_ruleset_test.rb +0 -102
- data/test/unit/wlang/buffering_template1.wtpl +0 -1
- data/test/unit/wlang/buffering_template2.wtpl +0 -1
- data/test/unit/wlang/buffering_template3.wtpl +0 -1
- data/test/unit/wlang/buffering_template4.wtpl +0 -1
- data/test/unit/wlang/buffering_template5.wtpl +0 -1
- data/test/unit/wlang/context_ruleset_test.rb +0 -32
- data/test/unit/wlang/data.rb +0 -3
- data/test/unit/wlang/encoder_set_test.rb +0 -42
- data/test/unit/wlang/imperative_ruleset_test.rb +0 -107
- data/test/unit/wlang/intelligent_buffer_test.rb +0 -194
- data/test/unit/wlang/othersymbols_test.rb +0 -16
- data/test/unit/wlang/parser_test.rb +0 -88
- data/test/unit/wlang/plain_text_dialect_test.rb +0 -21
- data/test/unit/wlang/ruby_dialect_test.rb +0 -100
- data/test/unit/wlang/ruby_expected.rb +0 -3
- data/test/unit/wlang/ruby_template.wrb +0 -3
- data/test/unit/wlang/ruleset_utils_test.rb +0 -245
- data/test/unit/wlang/specification_examples_test.rb +0 -54
- data/test/unit/wlang/test_utils.rb +0 -25
- data/test/unit/wlang/wlang_test.rb +0 -80
data/lib/wlang/encoder.rb
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
module WLang
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
# Encapsulates some encoding algorithm. This class is to EncoderSet what Rule
|
|
5
|
-
# is to RuleSet. Encoders are always installed on a EncoderSet (using EncoderSet#add_encoder),
|
|
6
|
-
# which is itself installed on a Dialect. Note that the method mentionned previously
|
|
7
|
-
# provides a DRY shortcut, allowing not using this class directly.
|
|
8
|
-
#
|
|
9
|
-
# Example:
|
|
10
|
-
# # Encoder subclassing can be avoided by providing a block to new
|
|
11
|
-
# # The following encoder job is to upcase the text:
|
|
12
|
-
# encoder = Encoder.new do |src,options|
|
|
13
|
-
# src.upcase
|
|
14
|
-
# end
|
|
15
|
-
#
|
|
16
|
-
# # It is even better to use the DSL
|
|
17
|
-
# WLang::dialect("mydialect") do
|
|
18
|
-
# # The following encoder job is to upcase the text and will be installed
|
|
19
|
-
# # under mydialect/myupcaser qualified name
|
|
20
|
-
# encoder("myupcaser") do |src,options|
|
|
21
|
-
# src.upcase
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
24
|
-
#
|
|
25
|
-
# Creating a a new encoder can be made in two ways: by subclassing this class and
|
|
26
|
-
# overriding the encoder method or by passing a block to new. In both cases,
|
|
27
|
-
# <b>encoders should always be stateless</b>, to allow reusable dialects that could
|
|
28
|
-
# even be used in a multi-threading environment.
|
|
29
|
-
#
|
|
30
|
-
# == Detailed API
|
|
31
|
-
class Encoder
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
# Creates a new encoder. If no block is given, the invocation of new MUST be made
|
|
35
|
-
# on a subclass overriding encoder. Otherwise, the block is considered as the
|
|
36
|
-
# effective stateless implementation of encoder and will be called with the
|
|
37
|
-
# same arguments.
|
|
38
|
-
#
|
|
39
|
-
def initialize(&block)
|
|
40
|
-
@block = block
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
# Fired by the parser when a rule request encoding of some instantiated text.
|
|
45
|
-
# Typical example is the standard tag <tt>^{encoder/qualified/name}{...}</tt>
|
|
46
|
-
# (see WLang::RuleSet::Basic) which requires the second block instantiation to
|
|
47
|
-
# be encoded by the encoder whose qualified name is given by the first block.
|
|
48
|
-
# This method must simply return the encoded text.
|
|
49
|
-
#
|
|
50
|
-
# Arguments:
|
|
51
|
-
# - src: source text to encode.
|
|
52
|
-
# - options: encoding options through a Hash. Available options are documented
|
|
53
|
-
# by encoders themselve.
|
|
54
|
-
#
|
|
55
|
-
def encode(src, options = {})
|
|
56
|
-
raise(NotImplementedError) unless @block
|
|
57
|
-
@block.call(src, options)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
end # class Encoder
|
|
61
|
-
|
|
62
|
-
end
|
data/lib/wlang/encoder_set.rb
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
require 'wlang/encoder'
|
|
2
|
-
module WLang
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
# This class allows grouping encoders together to build a given dialect.
|
|
6
|
-
# Encoders are always added with add_encoder, which also allows creating simple
|
|
7
|
-
# encoders on the fly (that is, without subclassing Encoder).
|
|
8
|
-
#
|
|
9
|
-
# Examples:
|
|
10
|
-
# # we will create a simple encoder set with two encoders, one for upcasing
|
|
11
|
-
# # the other for downcasing.
|
|
12
|
-
# encoders = EncoderSet.new
|
|
13
|
-
# encoder.add_encoder 'upcaser' do |src,options|
|
|
14
|
-
# src.upcase
|
|
15
|
-
# end
|
|
16
|
-
# encoder.add_encoder 'downcaser' do |src,options|
|
|
17
|
-
# src.downcase
|
|
18
|
-
# end
|
|
19
|
-
#
|
|
20
|
-
# == Detailed API
|
|
21
|
-
class EncoderSet
|
|
22
|
-
|
|
23
|
-
# Creates an empty encoder set.
|
|
24
|
-
def initialize
|
|
25
|
-
@encoders = {}
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Yields the block with name, encoder pairs
|
|
29
|
-
def each
|
|
30
|
-
@encoders.each_pair{|name,encoder| yield(name, encoder)}
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
# Adds an encoder under a specific name. Supported signatures are as follows:
|
|
35
|
-
# - _name_ is a symbol: _encoder_ and _block_ are ignored and encoder is
|
|
36
|
-
# interpreted as being a method of the String class whose name is the symbol.
|
|
37
|
-
# - _name_ is a String and a block is provided: encoder is expected to be
|
|
38
|
-
# implemented by the block which takes |src,options| arguments.
|
|
39
|
-
# - _name_ is a String and _encoder_ is a Proc: same as if _encoder_ was a
|
|
40
|
-
# given block.
|
|
41
|
-
#
|
|
42
|
-
# Examples:
|
|
43
|
-
# encoders = EncoderSet.new
|
|
44
|
-
# # add an encoder by reusing String method
|
|
45
|
-
# encoders.add_encoder(:upcase)
|
|
46
|
-
#
|
|
47
|
-
# # add an encoder by providing a block
|
|
48
|
-
# encoders.add_encoder("ucase") do |src,options|
|
|
49
|
-
# src.upcase
|
|
50
|
-
# end
|
|
51
|
-
#
|
|
52
|
-
# # add an encoder by providing a Proc
|
|
53
|
-
# upcaser = Proc.new {|src,options| src.upcase}
|
|
54
|
-
# encoders.add_encoder("upcase", upcaser)
|
|
55
|
-
#
|
|
56
|
-
def add_encoder(name, encoder=nil, &block)
|
|
57
|
-
# handle String method through symbol
|
|
58
|
-
if Symbol===name
|
|
59
|
-
encoder, block = nil, Proc.new {|src,options| src.send(name)}
|
|
60
|
-
name = name.to_s
|
|
61
|
-
elsif Proc===encoder
|
|
62
|
-
encoder, block = nil, encoder
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# check arguments
|
|
66
|
-
if encoder.nil?
|
|
67
|
-
raise(ArgumentError,"Block required") if block.nil?
|
|
68
|
-
encoder = Encoder.new(&block)
|
|
69
|
-
end
|
|
70
|
-
raise(ArgumentError, "Encoder expected") unless Encoder===encoder
|
|
71
|
-
|
|
72
|
-
# save encoder
|
|
73
|
-
@encoders[name] = encoder
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
# Adds reusable encoders defined in a Ruby module. _mod_ must be a Module instance.
|
|
78
|
-
# If _pairs_ is ommitted (nil), all encoders of the module are added, under their
|
|
79
|
-
# standard names (see DEFAULT_ENCODERS under WLang::EncoderSet::XHtml for example).
|
|
80
|
-
# Otherwise, _pairs_ is expected to be a Hash providing a mapping between encoder
|
|
81
|
-
# names and _mod_ methods (whose names are given by ruby symbols).
|
|
82
|
-
#
|
|
83
|
-
def add_encoders(mod, pairs=nil)
|
|
84
|
-
raise(ArgumentError,"Module expected",caller) unless Module===mod
|
|
85
|
-
pairs = mod::DEFAULT_ENCODERS if pairs.nil?
|
|
86
|
-
pairs.each_pair do |name,method|
|
|
87
|
-
meth = mod.method(method)
|
|
88
|
-
raise(ArgumentError,"No such method: #{method} in #{mod}") if meth.nil?
|
|
89
|
-
add_encoder(name, &meth.to_proc)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Checks if an encoder is installed under _name.
|
|
94
|
-
def has_encoder?(name)
|
|
95
|
-
@encoders.has_key?(name)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Returns an encoder by its name, nil if no such encoder.
|
|
99
|
-
def get_encoder(name)
|
|
100
|
-
@encoders[name]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
# Shortcut for <tt>get_encoder(encoder).encode(source,options)</tt>
|
|
105
|
-
#
|
|
106
|
-
def encode(encoder, src, options=nil)
|
|
107
|
-
if String===encoder then
|
|
108
|
-
ename, encoder = encoder, get_encoder(encoder)
|
|
109
|
-
raise(ArgumentError,"No such encoder: #{ename}") if encoder.nil?
|
|
110
|
-
end
|
|
111
|
-
raise(ArgumentError,"Invalid encoder: #{encoder}") unless Encoder===encoder
|
|
112
|
-
encoder.encode(src, options)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Returns a string with comma separated encoder names.
|
|
116
|
-
def to_s
|
|
117
|
-
@encoders.keys.join(", ")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
end # class EncoderSet
|
|
121
|
-
|
|
122
|
-
end
|
data/lib/wlang/errors.rb
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
module WLang
|
|
2
|
-
|
|
3
|
-
# Main error of all WLang errors.
|
|
4
|
-
class Error < StandardError
|
|
5
|
-
|
|
6
|
-
# The parser state whe this error has been raised
|
|
7
|
-
attr_accessor :parser_state
|
|
8
|
-
|
|
9
|
-
# Optional cause (other lower level exception)
|
|
10
|
-
attr_accessor :cause
|
|
11
|
-
|
|
12
|
-
# Creates an error instance with a given parser state
|
|
13
|
-
def initialize(msg = nil, parser_state = nil, cause = nil)
|
|
14
|
-
raise ArgumentError, "msg expected to be nil or a String" unless (msg.nil? or String===msg)
|
|
15
|
-
raise ArgumentError, "parser_state expected to be nil or a State"\
|
|
16
|
-
unless (parser_state.nil? or ::WLang::Parser::State===parser_state)
|
|
17
|
-
super(msg)
|
|
18
|
-
@parser_state = parser_state
|
|
19
|
-
@cause = cause
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Returns a friendly wlang backtrace
|
|
23
|
-
def wlang_backtrace
|
|
24
|
-
parser_state ? parser_state.backtrace : ["no backtrace information, sorry"]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end # class Error
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
# Raised by hosted languages when something fails during
|
|
31
|
-
# evaluation.
|
|
32
|
-
#
|
|
33
|
-
class EvalError < ::WLang::Error
|
|
34
|
-
|
|
35
|
-
# The expression whose evaluation failed
|
|
36
|
-
attr_accessor :expression
|
|
37
|
-
|
|
38
|
-
# Creates an error instance with an optional expression that
|
|
39
|
-
# failed
|
|
40
|
-
def initialize(msg = nil, parser_state = nil, expression = nil, cause = nil)
|
|
41
|
-
super(msg, parser_state, cause)
|
|
42
|
-
@expression = expression
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def to_s
|
|
46
|
-
"Evaluation of #{@expression} failed, #{@cause ? @cause.message : ''}"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
end # class EvalError
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
# Raised when a variable may not be found in the current
|
|
53
|
-
# parser scope
|
|
54
|
-
#
|
|
55
|
-
class UndefinedVariableError < ::WLang::EvalError
|
|
56
|
-
|
|
57
|
-
# Name of the variable that could not be found
|
|
58
|
-
attr_accessor :variable
|
|
59
|
-
|
|
60
|
-
# Creates an error instance with an optional variable name
|
|
61
|
-
def initialize(msg = nil, parser_state = nil, expression = nil, variable = nil)
|
|
62
|
-
super(msg, parser_state, expression)
|
|
63
|
-
@variable = variable
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def to_s
|
|
67
|
-
"Unable to find variable #{@variable}"
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
end # class UndefinedVariableError
|
|
71
|
-
|
|
72
|
-
# Error raised by a WLang parser instanciation when an error occurs.
|
|
73
|
-
class ParseError < ::WLang::Error
|
|
74
|
-
|
|
75
|
-
# Where did the parsing failed
|
|
76
|
-
attr_accessor :line, :column
|
|
77
|
-
|
|
78
|
-
end # class ParseError
|
|
79
|
-
|
|
80
|
-
end # module WLang
|
data/lib/wlang/ext/string.rb
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Installs _wlang_ utility methods on Ruby String.
|
|
3
|
-
#
|
|
4
|
-
class String
|
|
5
|
-
|
|
6
|
-
# Converts the string to a wlang template
|
|
7
|
-
def wlang_template(dialect = "wlang/active-string", block_symbols = :braces)
|
|
8
|
-
WLang::template(self, dialect, block_symbols)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
# Instantiates the string as a wlang template using
|
|
13
|
-
# a context object and a dialect.
|
|
14
|
-
#
|
|
15
|
-
def wlang_instantiate(context = nil, dialect = "wlang/active-string", block_symbols = :braces)
|
|
16
|
-
WLang::instantiate(self, context, dialect, block_symbols)
|
|
17
|
-
end
|
|
18
|
-
alias :wlang :wlang_instantiate
|
|
19
|
-
|
|
20
|
-
# Computes the column number for a given offset in
|
|
21
|
-
# this string
|
|
22
|
-
def __wlang_column_of(index)
|
|
23
|
-
return 1 if index == 0
|
|
24
|
-
newline_index = rindex("\n", index - 1)
|
|
25
|
-
if newline_index
|
|
26
|
-
index - newline_index
|
|
27
|
-
else
|
|
28
|
-
index + 1
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Computes the line number for a given offset in
|
|
33
|
-
# this string
|
|
34
|
-
def __wlang_line_of(index)
|
|
35
|
-
self[0...index].count("\n") + 1
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def __wlang_realign(offset, strip_first = false)
|
|
39
|
-
s = gsub(/^/, ' ' * offset)
|
|
40
|
-
strip_first ? s.gsub(/\A\s*/, "") : s
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
data/lib/wlang/hash_scope.rb
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
require 'delegate'
|
|
2
|
-
module WLang
|
|
3
|
-
#
|
|
4
|
-
# Implements a scoping mechanism on top of a ruby hash (accessible through pairing).
|
|
5
|
-
# Such a scope mimics hashses for has_key?, [] and []= methods. A scope has an
|
|
6
|
-
# accessible parent. Scopes form a tree, the root being accessible using its
|
|
7
|
-
# natural accessor. Scope lookup (has_key? and []) uses the hierarchy to find
|
|
8
|
-
# accessible variables.
|
|
9
|
-
#
|
|
10
|
-
# Branching a scope allows installing new variables that hide variables with the
|
|
11
|
-
# same name in the parent scope. Branching is made easy through the branch methods
|
|
12
|
-
# that accepts a block, passing the child as first argument:
|
|
13
|
-
#
|
|
14
|
-
# scope = HashScope.new(:name => 'wlang')
|
|
15
|
-
# puts scope[:name] # prints 'wlang'
|
|
16
|
-
# scope.branch(:name => 'other') do |child|
|
|
17
|
-
# puts child[:name] # prints 'other'
|
|
18
|
-
# end
|
|
19
|
-
# puts scope[:name] # prints 'wlang'
|
|
20
|
-
#
|
|
21
|
-
# This branching mechanism is intended to be used to keep a current scope as instance
|
|
22
|
-
# variable of a using class:
|
|
23
|
-
#
|
|
24
|
-
# # We create an initial scope at construction
|
|
25
|
-
# def initialize
|
|
26
|
-
# @scope = HashScope.new
|
|
27
|
-
# end
|
|
28
|
-
#
|
|
29
|
-
# # Appends the current scope with new key/value pairs. Yields the block
|
|
30
|
-
# # with the new scope and restore the original one after that.
|
|
31
|
-
# def do_something_with_a_new_scope(hash = {})
|
|
32
|
-
# @scope = @scope.branch(:name => 'other')
|
|
33
|
-
# yield if block_given?
|
|
34
|
-
# @scope = @scope.parent
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
class HashScope
|
|
38
|
-
|
|
39
|
-
# The parent scope, or nil if no such parent
|
|
40
|
-
attr_reader :parent
|
|
41
|
-
|
|
42
|
-
# The key/value pairing inside this scope
|
|
43
|
-
attr_reader :pairing
|
|
44
|
-
|
|
45
|
-
# Creates a scope instance with a parent and initial
|
|
46
|
-
# pairing through a Hash
|
|
47
|
-
def initialize(pairing = nil, parent = nil)
|
|
48
|
-
raise ArgumentError, "Hash expected for pairing #{pairing.class} received" unless (pairing.nil? or Hash===pairing)
|
|
49
|
-
@pairing = pairing || {}
|
|
50
|
-
@parent = parent
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Returns the root scope
|
|
54
|
-
def root
|
|
55
|
-
@root ||= (parent ? parent.root : self)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Checks if a key exists in this scope, delegating to
|
|
59
|
-
# parent if not found and allowed
|
|
60
|
-
def has_key?(key, delegate = true)
|
|
61
|
-
pairing.has_key?(key) || (!delegate.nil? && !parent.nil? && parent.has_key?(key))
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Returns the value associated to a key, delegating to parent
|
|
65
|
-
# if not found and allowed
|
|
66
|
-
def [](key, delegate = true)
|
|
67
|
-
pairing.has_key?(key) ? pairing[key] : (delegate && parent && parent[key])
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Associates a key to a value inside this scope
|
|
71
|
-
def []=(key, value)
|
|
72
|
-
pairing[key] = value
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Creates a new child scope and returns it. If a block is given,
|
|
76
|
-
# yields the block with the child scope
|
|
77
|
-
def branch(pairing = nil)
|
|
78
|
-
child = HashScope.new(pairing, self)
|
|
79
|
-
yield child if block_given?
|
|
80
|
-
child
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Converts this scope to a full hash with all variables
|
|
84
|
-
def to_h
|
|
85
|
-
parent ? parent.to_h.merge(pairing) : pairing.dup
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
end # class HashScope
|
|
89
|
-
end # module WLang
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
module WLang
|
|
2
|
-
#
|
|
3
|
-
# Implements the hosted language abstraction of WLang. The hosted language is
|
|
4
|
-
# mainly responsible of evaluating expressions (see evaluate). This abstraction
|
|
5
|
-
# may be implemented by a user's own class, providing that it respected the
|
|
6
|
-
# evaluate method specification.
|
|
7
|
-
#
|
|
8
|
-
# This default implementation implements the ruby hosted language. It works
|
|
9
|
-
# with ::WLang::HostedLanguage::DSL, which uses instance_eval for evaluating
|
|
10
|
-
# the expression. Calls to missing methods (without parameter and block) are
|
|
11
|
-
# converted in scope lookups. The DSL class is strictly private, as it uses
|
|
12
|
-
# a somewhat complex ruby introspection mechanism to ensure that scoping will
|
|
13
|
-
# not be perturbated by Kernel methods and Object private methods even if
|
|
14
|
-
# additional gems are loaded later.
|
|
15
|
-
#
|
|
16
|
-
# If you want to intall low-priority variables and tools available in all wlang
|
|
17
|
-
# templates (global scoping) you can reopen the HostedLanguage class itself and
|
|
18
|
-
# override variable_missing. Note that "low-priority" means that these methods
|
|
19
|
-
# will be hidden if a user installs a variable with the same name in its template.
|
|
20
|
-
#
|
|
21
|
-
# class WLang::HostedLanguage
|
|
22
|
-
#
|
|
23
|
-
# # Low-priority now variable
|
|
24
|
-
# def now
|
|
25
|
-
# Time.now
|
|
26
|
-
# end
|
|
27
|
-
#
|
|
28
|
-
# # Low-priority variables are checked before raising an UndefinedVariableError
|
|
29
|
-
# def variable_missing(name)
|
|
30
|
-
# case name
|
|
31
|
-
# when :who, ...
|
|
32
|
-
# self.send(name)
|
|
33
|
-
# else
|
|
34
|
-
# raise ::WLang::UndefinedVariableError.new(nil, nil, nil, name)
|
|
35
|
-
# end
|
|
36
|
-
# end
|
|
37
|
-
#
|
|
38
|
-
# end
|
|
39
|
-
#
|
|
40
|
-
# This class is thread safe, meaning that the same hosting language instance may be
|
|
41
|
-
# safely shared by concurrent wlang parsers. Extending or re-opening this class and using
|
|
42
|
-
# instance variables will make it non thread-safe.
|
|
43
|
-
#
|
|
44
|
-
class HostedLanguage
|
|
45
|
-
|
|
46
|
-
# The hosted language DSL, interpreting expressions
|
|
47
|
-
class DSL
|
|
48
|
-
|
|
49
|
-
# Methods that we keep
|
|
50
|
-
KEPT_METHODS = [ "__send__", "__id__", "instance_eval", "initialize", "object_id",
|
|
51
|
-
"singleton_method_added", "singleton_method_undefined", "method_missing",
|
|
52
|
-
"__evaluate__", "knows?"]
|
|
53
|
-
|
|
54
|
-
class << self
|
|
55
|
-
def __clean_scope__
|
|
56
|
-
# Removes all methods that are not needed to the class
|
|
57
|
-
(instance_methods + private_instance_methods).each do |m|
|
|
58
|
-
m_to_s = m.to_s
|
|
59
|
-
undef_method(m_to_s.to_sym) unless ('__' == m_to_s[0..1]) or KEPT_METHODS.include?(m_to_s)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Creates a DSL instance for a given hosted language and
|
|
65
|
-
# parser state
|
|
66
|
-
def initialize(hosted, parser_state)
|
|
67
|
-
@hosted, @parser_state = hosted, parser_state
|
|
68
|
-
class << self
|
|
69
|
-
__clean_scope__
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Delegates the missing lookup to the current parser scope or raises an
|
|
74
|
-
# UndefinedVariableError (calls @hosted.variable_missing precisely)
|
|
75
|
-
def method_missing(name, *args, &block)
|
|
76
|
-
if @parser_state and args.empty? and block.nil?
|
|
77
|
-
if effname = knows?(name)
|
|
78
|
-
@parser_state.scope[effname]
|
|
79
|
-
else
|
|
80
|
-
@hosted.variable_missing(name)
|
|
81
|
-
end
|
|
82
|
-
else
|
|
83
|
-
super(name, *args, &block)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Checks if a variable is known in the current parser scope
|
|
88
|
-
def knows?(name)
|
|
89
|
-
if @parser_state.scope.has_key?(name)
|
|
90
|
-
name
|
|
91
|
-
elsif @parser_state.scope.has_key?(name.to_s)
|
|
92
|
-
name.to_s
|
|
93
|
-
else
|
|
94
|
-
nil
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Evaluates an expression
|
|
99
|
-
def __evaluate__(__expression__)
|
|
100
|
-
__result__ = instance_eval(__expression__)
|
|
101
|
-
|
|
102
|
-
# backward compatibility with >= 0.8.4 where 'using self'
|
|
103
|
-
# was allowed. This will be removed in wlang 1.0.0
|
|
104
|
-
if __result__.object_id == self.object_id
|
|
105
|
-
Kernel.puts "Warning: using deprecated 'using self' syntax (#{@parser_state.where})\n"\
|
|
106
|
-
"will be removed in wlang 1.0.0. Use 'share all', extends "\
|
|
107
|
-
"::WLang::HostedLanguage::DSL with useful methods or create your own"\
|
|
108
|
-
" hosted language."
|
|
109
|
-
__result__ = @parser_state.scope.to_h
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
__result__
|
|
113
|
-
rescue ::WLang::Error => ex
|
|
114
|
-
ex.parser_state = @parser_state
|
|
115
|
-
ex.expression = __expression__ if ex.respond_to?(:expression=)
|
|
116
|
-
Kernel.raise ex
|
|
117
|
-
rescue Exception => ex
|
|
118
|
-
Kernel.raise ::WLang::EvalError.new(ex.message, @parser_state, __expression__, ex)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
end # class DSL
|
|
122
|
-
|
|
123
|
-
#
|
|
124
|
-
# Called when a variable cannot be found (name is a Symbol object). This default
|
|
125
|
-
# implementation raises an UndefinedVariableError. This method is intended to be
|
|
126
|
-
# overriden for handling such a situation more friendly or for installing
|
|
127
|
-
# low-priority global variables (see class documentation).
|
|
128
|
-
#
|
|
129
|
-
def variable_missing(name)
|
|
130
|
-
raise ::WLang::UndefinedVariableError.new(nil, nil, nil, name)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
#
|
|
134
|
-
# Evaluates a given expression in the context of a given
|
|
135
|
-
# parser state.
|
|
136
|
-
#
|
|
137
|
-
# This method should always raise
|
|
138
|
-
# - an UndefinedVariableError when a given template variable cannot be found.
|
|
139
|
-
# - an EvalError when something more severe occurs
|
|
140
|
-
#
|
|
141
|
-
def evaluate(expression, parser_state)
|
|
142
|
-
::WLang::HostedLanguage::DSL.new(self, parser_state).__evaluate__(expression)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
end # class HostedLanguage
|
|
146
|
-
end # module WLang
|