mallinna 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05a38f928da3bea1a216060832b7a371efcae6e7
4
+ data.tar.gz: 7262a8d7a83b458fe5c1943bb101013e402b546a
5
+ SHA512:
6
+ metadata.gz: 565b2a393437c24dcebe207cb1efa4e828b819d6bb980dd7a17dc13f28124f8f2eb15aebe2410a91f589c320e8690e92322069bf2d4fe0503eb1af8f54a8bc2c
7
+ data.tar.gz: ac44b2df593e894b243eaac63e41892d3c2ee74b5920f2230c0fe49273528f077215a213a4aa21a7870c11a908a55ebca57f0b8cda6419b332856a4b9e425732
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,73 @@
1
+ # Malline
2
+
3
+ Malline is template engine targeting IOS/JunOS or generally configurations (or
4
+ more accurately what ever text stuff I'm doing).
5
+
6
+ It surfaced from the need to do something like this in ERB:
7
+ ```
8
+ interfaces {
9
+ <%= name %> {
10
+ description "<%if description %>";
11
+ }
12
+ }
13
+ ```
14
+
15
+ where description "description"; is only output if the code evaluates true,
16
+ keeping the template clean in common use-case
17
+
18
+ ```
19
+ Consider this code
20
+ require_relative './lib/malline'
21
+ require 'pry'
22
+ class Int
23
+ attr_accessor :name, :mtu, :description, :poop
24
+ def initialize
25
+ @name = 'xe-1/2/3.42'
26
+ @mtu = 1500
27
+ @description = 'K: S-123455 - poop customer'
28
+ @poop = true
29
+ end
30
+ def get_binding
31
+ binding
32
+ end
33
+ end
34
+
35
+ template = <<EOF
36
+ interfaces {
37
+ <% name %> {
38
+ mtu <%if mtu %>;
39
+ description "<%if description %>";
40
+ }
41
+ }
42
+ EOF
43
+
44
+ int = Int.new
45
+ cfg = Malline.run template, int.get_binding
46
+ binding.pry
47
+ ```
48
+
49
+ Real use might look something like this:
50
+ ```
51
+ [1] pry(main)> puts cfg
52
+ interfaces {
53
+ xe-1/2/3.42 {
54
+ mtu 1500;
55
+ description "K: S-123455 - poop customer";
56
+ }
57
+ }
58
+ => nil
59
+ [2] pry(main)> int.mtu = 900
60
+ => 900
61
+ [3] pry(main)> int.description = nil
62
+ => nil
63
+ [4] pry(main)> puts Malline.run template, int.get_binding
64
+ interfaces {
65
+ xe-1/2/3.42 {
66
+ mtu 900;
67
+ }
68
+ }
69
+ => nil
70
+ ```
71
+
72
+
73
+
@@ -0,0 +1,48 @@
1
+ require 'rake/testtask'
2
+
3
+ rule '.rb' => '.y' do |t|
4
+ sh "racc -l -o #{t.name} #{t.source}"
5
+ end
6
+ gemspec = eval(File.read(Dir['*.gemspec'].first))
7
+ file = [gemspec.name, gemspec.version].join('-') + '.gem'
8
+
9
+ desc 'Validate gemspec'
10
+ task :gemspec do
11
+ gemspec.validate
12
+ end
13
+
14
+ desc 'Run minitest'
15
+ task :test => :compile do
16
+ Rake::TestTask.new do |t|
17
+ t.libs.push "lib"
18
+ all = FileList['spec/*_spec.rb']
19
+ first = %w(spec/lexer_spec.rb spec/handler_spec.rb)
20
+ t.test_files = [first, all-first].flatten
21
+ t.verbose = true
22
+ end
23
+ end
24
+
25
+ desc 'Compile RACC parser'
26
+ task :compile => 'lib/malline/parser.rb'
27
+
28
+ desc 'Build gem'
29
+ task :build => [:gemspec, :test] do
30
+ system "gem build #{gemspec.name}.gemspec"
31
+ FileUtils.mkdir_p 'gems'
32
+ FileUtils.mv file, 'gems'
33
+ end
34
+
35
+ desc 'Install gem'
36
+ task :install => :build do
37
+ system "sudo sh -c \'umask 022; gem install gems/#{file}\'"
38
+ end
39
+
40
+ desc 'Remove gems'
41
+ task :clean do
42
+ FileUtils.rm_rf 'gems'
43
+ end
44
+
45
+ desc 'Push to rubygems'
46
+ task :push do
47
+ system "gem push gems/#{file}"
48
+ end
@@ -0,0 +1,14 @@
1
+ module Malline
2
+ require_relative './malline/lexer'
3
+ require_relative './malline/parser'
4
+ require_relative './malline/compiler.rb'
5
+
6
+ def self.run template, binding
7
+ lex = Lexer.new template
8
+ par = Parser.new lex
9
+ han = par.parse
10
+ com = Compiler.new han.parsed
11
+ template = com.compile
12
+ eval(template, binding)
13
+ end
14
+ end
@@ -0,0 +1,95 @@
1
+ module Malline
2
+ class Compiler
3
+ VAR = '_malline_'
4
+ OUT = VAR + '_out'
5
+ class InvalidKind < NameError; end
6
+ attr_reader :out
7
+ def initialize parsed
8
+ @parsed = parsed
9
+ @out = nil
10
+ @cmd = {
11
+ :if => {
12
+ :now => 0,
13
+ :line => [],
14
+ :id => [],
15
+ },
16
+ }
17
+ end
18
+
19
+ def compile
20
+ @out = resolve(combine)
21
+ end
22
+
23
+ def combine
24
+ out = []
25
+ @parsed.each do |e|
26
+ case kind=e.shift
27
+ when :data then data(out, *e)
28
+ when :code then code(out, *e)
29
+ else
30
+ raise InvalidKind, "'#{kind}' was not recognized"
31
+ end
32
+ end
33
+ out
34
+ end
35
+
36
+ def data out, str, lines
37
+ lines = (lines.first .. lines.last).to_a
38
+ str.lines.each_with_index do |line, index|
39
+ linenr = lines[index]
40
+ line = '%s.concat \'%s\'' % [OUT, line.gsub(/'/, %q(\\\'))]
41
+ out << [line, linenr]
42
+ end
43
+ end
44
+
45
+ def code out, cmd, str, lines
46
+ lines = (lines.first .. lines.last).to_a
47
+ str.lines.each_with_index do |line, index|
48
+ linenr = lines[index]
49
+ line = cmd_if(line, lines, @cmd[:if][:now]+=1) if cmd == :if
50
+ line = '%s.concat %s' % [OUT, line] unless cmd == :s
51
+ out << ["#{line}.to_s", linenr]
52
+ end
53
+ end
54
+
55
+
56
+ def cmd_if str, lines, id
57
+ name = VAR+'if_'+id.to_s
58
+ (lines.first .. lines.last).each do |line|
59
+ @cmd[:if][:line][line] ||= []
60
+ @cmd[:if][:line][line] << id
61
+ @cmd[:if][:id][id] = [name, str]
62
+ end
63
+ name
64
+ end
65
+
66
+ def resolve out_org
67
+ out = ["#{OUT}='';"]
68
+ cmp = []
69
+ seen = []
70
+ out_org.each do |line, line_nr|
71
+ resolve_cmd_if(line_nr, cmp, out) unless seen.include? line_nr
72
+ seen << line_nr
73
+ if not cmp.empty?
74
+ line = line + ' if ' + cmp.join(' and ')
75
+ end
76
+ out << line + ';'
77
+ end
78
+ out << "#{OUT}"
79
+ out.join "\n"
80
+ end
81
+
82
+ def resolve_cmd_if line_nr, cmp, out
83
+ cmp.clear
84
+ set = []
85
+ [@cmd[:if][:line][line_nr]].flatten.compact.each do |cmd_id|
86
+ varname, varvalue = @cmd[:if][:id][cmd_id]
87
+ set << [varname,varvalue]
88
+ cmp << varname
89
+ end
90
+ set.each do |name, value|
91
+ out << name + '=' + value + ';'
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,17 @@
1
+ module Malline
2
+ class Handler
3
+ attr_reader :parsed
4
+ attr_accessor :token_line
5
+ def initialize
6
+ @parsed = []
7
+ end
8
+
9
+ def code string, cmd=nil
10
+ @parsed << [:code, cmd, string, token_line]
11
+ end
12
+
13
+ def data string
14
+ @parsed << [:data, string, token_line]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ require 'strscan'
2
+ require 'stringio'
3
+
4
+ module Malline
5
+ class Lexer
6
+ TOKEN = {
7
+ :START_CODE => /<%(if|s)?/,
8
+ :END_CODE => /%>/,
9
+ }
10
+
11
+ def initialize io
12
+ io = StringIO.new io if io.class == String
13
+ @ss = StringScanner.new io.read
14
+ @token, @state = [], [:CODE, :DATA]
15
+ end
16
+
17
+ def next_token
18
+ return @token.shift unless @token.empty?
19
+ return if @ss.eos?
20
+
21
+ start = line
22
+ name = @state.rotate!.first == :DATA ? :START_CODE : :END_CODE
23
+ if data = @ss.scan_until(TOKEN[name])
24
+ @token << [name, @ss.matched, start, line]
25
+ @token << [:CMD, @ss.matched[2..-1], start, line] if @ss.matched.size > 2
26
+ [:DATA, data[0..-(@ss.matched.size+1)], start, line]
27
+ else #gobble gobble gobble
28
+ [:DATA, @ss.scan(/.*/m), start, line]
29
+ end
30
+ end
31
+
32
+ def line
33
+ @ss.string[0..@ss.pos].lines.count
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,152 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.11
4
+ # from Racc grammer file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ module Malline
9
+ class Parser < Racc::Parser
10
+
11
+
12
+ require_relative 'handler'
13
+
14
+ def initialize lexer, handler=Handler.new
15
+ @lexer = lexer
16
+ @handler = handler
17
+ super()
18
+ end
19
+
20
+ def next_token
21
+ token, string, start_line, end_line = @lexer.next_token
22
+ @handler.token_line = [start_line, end_line]
23
+ [token, string] if token
24
+ end
25
+
26
+ def parse
27
+ do_parse
28
+ @handler
29
+ end
30
+ ##### State transition tables begin ###
31
+
32
+ racc_action_table = [
33
+ 7, 5, 5, 6, 6, 9, 11, 10, 12, 13,
34
+ 14, 15 ]
35
+
36
+ racc_action_check = [
37
+ 1, 0, 1, 0, 1, 5, 5, 5, 7, 10,
38
+ 11, 13 ]
39
+
40
+ racc_action_pointer = [
41
+ -1, 0, nil, nil, nil, 2, nil, 8, nil, nil,
42
+ 5, 7, nil, 8, nil, nil ]
43
+
44
+ racc_action_default = [
45
+ -9, -9, -2, -3, -4, -9, -8, -9, -1, -5,
46
+ -9, -9, 16, -9, -7, -6 ]
47
+
48
+ racc_goto_table = [
49
+ 2, 8, 1 ]
50
+
51
+ racc_goto_check = [
52
+ 2, 2, 1 ]
53
+
54
+ racc_goto_pointer = [
55
+ nil, 2, 0, nil, nil ]
56
+
57
+ racc_goto_default = [
58
+ nil, nil, nil, 3, 4 ]
59
+
60
+ racc_reduce_table = [
61
+ 0, 0, :racc_error,
62
+ 2, 7, :_reduce_none,
63
+ 1, 7, :_reduce_none,
64
+ 1, 8, :_reduce_none,
65
+ 1, 8, :_reduce_none,
66
+ 2, 9, :_reduce_none,
67
+ 4, 9, :_reduce_6,
68
+ 3, 9, :_reduce_7,
69
+ 1, 10, :_reduce_8 ]
70
+
71
+ racc_reduce_n = 9
72
+
73
+ racc_shift_n = 16
74
+
75
+ racc_token_table = {
76
+ false => 0,
77
+ :error => 1,
78
+ :START_CODE => 2,
79
+ :END_CODE => 3,
80
+ :DATA => 4,
81
+ :CMD => 5 }
82
+
83
+ racc_nt_base = 6
84
+
85
+ racc_use_result_var = true
86
+
87
+ Racc_arg = [
88
+ racc_action_table,
89
+ racc_action_check,
90
+ racc_action_default,
91
+ racc_action_pointer,
92
+ racc_goto_table,
93
+ racc_goto_check,
94
+ racc_goto_default,
95
+ racc_goto_pointer,
96
+ racc_nt_base,
97
+ racc_reduce_table,
98
+ racc_token_table,
99
+ racc_shift_n,
100
+ racc_reduce_n,
101
+ racc_use_result_var ]
102
+
103
+ Racc_token_to_s_table = [
104
+ "$end",
105
+ "error",
106
+ "START_CODE",
107
+ "END_CODE",
108
+ "DATA",
109
+ "CMD",
110
+ "$start",
111
+ "values",
112
+ "value",
113
+ "code_block",
114
+ "data" ]
115
+
116
+ Racc_debug_parser = false
117
+
118
+ ##### State transition tables end #####
119
+
120
+ # reduce 0 omitted
121
+
122
+ # reduce 1 omitted
123
+
124
+ # reduce 2 omitted
125
+
126
+ # reduce 3 omitted
127
+
128
+ # reduce 4 omitted
129
+
130
+ # reduce 5 omitted
131
+
132
+ def _reduce_6(val, _values, result)
133
+ @handler.code(val[2], val[1].to_sym)
134
+ result
135
+ end
136
+
137
+ def _reduce_7(val, _values, result)
138
+ @handler.code val[1]
139
+ result
140
+ end
141
+
142
+ def _reduce_8(val, _values, result)
143
+ @handler.data val.first
144
+ result
145
+ end
146
+
147
+ def _reduce_none(val, _values, result)
148
+ val[0]
149
+ end
150
+
151
+ end # class Parser
152
+ end # module Malline
@@ -0,0 +1,40 @@
1
+ class Malline::Parser
2
+ token START_CODE END_CODE DATA CMD
3
+ rule
4
+ values
5
+ : values value
6
+ | value
7
+ ;
8
+ value
9
+ : code_block
10
+ | data
11
+ ;
12
+ code_block
13
+ : START_CODE END_CODE
14
+ | START_CODE CMD DATA END_CODE { @handler.code(val[2], val[1].to_sym) }
15
+ | START_CODE DATA END_CODE { @handler.code val[1] }
16
+ ;
17
+ data : DATA { @handler.data val.first }
18
+
19
+ end
20
+
21
+ ---- inner
22
+
23
+ require_relative 'handler'
24
+
25
+ def initialize lexer, handler=Handler.new
26
+ @lexer = lexer
27
+ @handler = handler
28
+ super()
29
+ end
30
+
31
+ def next_token
32
+ token, string, start_line, end_line = @lexer.next_token
33
+ @handler.token_line = [start_line, end_line]
34
+ [token, string] if token
35
+ end
36
+
37
+ def parse
38
+ do_parse
39
+ @handler
40
+ end
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'mallinna'
3
+ s.version = '0.0.2'
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = [ 'Saku Ytti' ]
6
+ s.email = %w( saku@ytti.fi )
7
+ s.homepage = 'https://github.com/ytti/malline'
8
+ s.summary = 'Templating language targeting IOS/JunOS configs'
9
+ s.description = 'Mostly like ERB, but <%if foo%> conditional will omit whole line unless code evaluates true'
10
+ s.rubyforge_project = s.name
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_path = 'lib'
13
+
14
+ # s.add_dependency 'bundler'
15
+
16
+ s.add_development_dependency 'racc'
17
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'spec_helper.rb'
2
+
3
+ class Int
4
+ attr_accessor :name, :mtu, :description, :vrf
5
+ def initialize
6
+ @name = 'xe-1/2/3'
7
+ @mtu = 1500
8
+ @description = 'K: S-12345 foobar \'quote\' xyzzy'
9
+ @vrf = 'VRF0001'
10
+ end
11
+ def get_binding; binding; end
12
+ end
13
+
14
+ describe Compiler do
15
+ #it "can be created with string argument" do
16
+ # Lexer.new('k').must_be_instance_of Lexer
17
+ #end
18
+
19
+ #it "can't be created without an argument" do
20
+ # ->{Lexer.new}.must_raise ArgumentError
21
+ #end
22
+
23
+ it "must pass junos example" do
24
+ int = Int.new
25
+ str = Malline.run TemplateJunOS, int.get_binding
26
+ str.must_equal ResultJunOS[0]
27
+ int.description = nil
28
+ int.mtu = 42
29
+ str = Malline.run TemplateJunOS, int.get_binding
30
+ str.must_equal ResultJunOS[1]
31
+ end
32
+
33
+ it "must pass ios example" do
34
+ int = Int.new
35
+ int.name = 'GigabitEthernet0/42'
36
+ str = Malline.run TemplateIOS, int.get_binding
37
+ str.must_equal ResultIOS[0]
38
+ int.description = 'f00fc7c8'
39
+ int.mtu = nil
40
+ int.vrf = 'xyzzy'
41
+ str = Malline.run TemplateIOS, int.get_binding
42
+ str.must_equal ResultIOS[1]
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'spec_helper.rb'
2
+
3
+ def get_handler string
4
+ lex = Lexer.new string
5
+ par = Parser.new lex
6
+ par.parse
7
+ end
8
+
9
+ describe Handler do
10
+
11
+ it "can be created" do
12
+ Handler.new.must_be_instance_of Handler
13
+ end
14
+
15
+ it "must get correctly parsed data" do
16
+ # yeah bit of a cope out :)
17
+ TEST.each do |tst|
18
+ han = get_handler tst[:string]
19
+ han.parsed.must_equal tst[:parsed]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'spec_helper.rb'
2
+ describe Lexer do
3
+ it "can be created with string argument" do
4
+ Lexer.new('k').must_be_instance_of Lexer
5
+ end
6
+
7
+ it "can't be created without an argument" do
8
+ ->{Lexer.new}.must_raise ArgumentError
9
+ end
10
+
11
+ it "must lex correctly" do
12
+ # yeah bit of a cope out :)
13
+ TEST.each do |tst|
14
+ lex = Lexer.new tst[:string]
15
+ ary, token = [], nil
16
+ ary << token while token = lex.next_token
17
+ ary.must_equal tst[:lex]
18
+ end
19
+ end
20
+
21
+ describe '#line' do
22
+ it 'must not consider trailing \n as new line' do
23
+ lex = Lexer.new "foo\n"
24
+ ss = lex.instance_variable_get :@ss
25
+ ss.scan_until(/.*/m)
26
+ lex.line.must_equal 1
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,82 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require_relative '../lib/malline.rb'
4
+ include Malline
5
+
6
+ class Int
7
+ attr_accessor :name, :mtu, :description, :vrf
8
+ def initialize
9
+ @name = 'xe-1/2/3'
10
+ @mtu = 1500
11
+ @description = 'K: S-12345 foobar \'quote\' xyzzy'
12
+ @vrf = 'VRF0001'
13
+ end
14
+ def get_binding; binding; end
15
+ end
16
+
17
+ TemplateJunOS = <<EOF
18
+ interfaces {
19
+ <% name %> {
20
+ mtu <%if mtu %>;
21
+ description "<%if description %>";
22
+ }
23
+ }
24
+ EOF
25
+ TemplateIOS = <<EOF
26
+ interface <% name %>
27
+ description <%if description %>
28
+ mtu <%if mtu %>
29
+ vrf forwarding <%if vrf %>
30
+ EOF
31
+
32
+ ResultJunOS = []
33
+ ResultJunOS << <<EOF
34
+ interfaces {
35
+ xe-1/2/3 {
36
+ mtu 1500;
37
+ description "K: S-12345 foobar 'quote' xyzzy";
38
+ }
39
+ }
40
+ EOF
41
+ ResultJunOS << <<EOF
42
+ interfaces {
43
+ xe-1/2/3 {
44
+ mtu 42;
45
+ }
46
+ }
47
+ EOF
48
+
49
+ ResultIOS = []
50
+ ResultIOS << <<EOF
51
+ interface GigabitEthernet0/42
52
+ description K: S-12345 foobar 'quote' xyzzy
53
+ mtu 1500
54
+ vrf forwarding VRF0001
55
+ EOF
56
+ ResultIOS << <<EOF
57
+ interface GigabitEthernet0/42
58
+ description f00fc7c8
59
+ vrf forwarding xyzzy
60
+ EOF
61
+
62
+
63
+ TEST = [
64
+ {
65
+ :string => "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
66
+ :lex => [[:DATA, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 1, 1]],
67
+ :parsed => [[:data, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", [1, 1]]],
68
+ },
69
+
70
+ {
71
+ :string => "Lorem ipsum <%dolor sit amet%>, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
72
+ :lex => [[:DATA, "Lorem ipsum ", 1, 1], [:START_CODE, "<%", 1, 1], [:DATA, "dolor sit amet", 1, 1], [:END_CODE, "%>", 1, 1], [:DATA, ", consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 1, 1]],
73
+ :parsed => [[:data, "Lorem ipsum ", [1, 1]], [:code, nil, "dolor sit amet", [1, 1]], [:data, ", consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", [1, 1]]],
74
+ },
75
+
76
+ {
77
+ :string => "Lorem ipsum <%dolor\nsit amet%>, con\nsectetur <%if testing\n bar\n fooi %> adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
78
+ :lex => [[:DATA, "Lorem ipsum ", 1, 1], [:START_CODE, "<%", 1, 1], [:DATA, "dolor\nsit amet", 1, 2], [:END_CODE, "%>", 1, 2], [:DATA, ", con\nsectetur ", 2, 3], [:START_CODE, "<%if", 2, 3], [:CMD, "if", 2, 3], [:DATA, " testing\n bar\n fooi ", 3, 5], [:END_CODE, "%>", 3, 5], [:DATA, " adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 5, 5]],
79
+ :parsed => [[:data, "Lorem ipsum ", [1, 1]], [:code, nil, "dolor\nsit amet", [1, 2]], [:data, ", con\nsectetur ", [2, 3]], [:code, :if, " testing\n bar\n fooi ", [3, 5]], [:data, " adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", [5, 5]]],
80
+ },
81
+
82
+ ]
data/tst.rb ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative './lib/malline'
4
+ class Int
5
+ attr_accessor :name, :mtu, :description, :poop
6
+ def initialize
7
+ @name = 'xe-1/2/3.42'
8
+ @mtu = 1500
9
+ @description = 'K: S-123455 - poop customer'
10
+ end
11
+ def get_binding; binding; end
12
+ end
13
+
14
+ template = <<EOF
15
+ interfaces {
16
+ <% name %> {
17
+ mtu <%if mtu %>;
18
+ description "<%if description %>";
19
+ }
20
+ }
21
+ EOF
22
+
23
+ puts Malline.run template, Int.new.get_binding
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mallinna
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Saku Ytti
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: racc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Mostly like ERB, but <%if foo%> conditional will omit whole line unless
28
+ code evaluates true
29
+ email:
30
+ - saku@ytti.fi
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - Gemfile
36
+ - README.md
37
+ - Rakefile
38
+ - lib/malline.rb
39
+ - lib/malline/compiler.rb
40
+ - lib/malline/handler.rb
41
+ - lib/malline/lexer.rb
42
+ - lib/malline/parser.rb
43
+ - lib/malline/parser.y
44
+ - mallinna.gemspec
45
+ - spec/compiler_spec.rb
46
+ - spec/handler_spec.rb
47
+ - spec/lexer_spec.rb
48
+ - spec/spec_helper.rb
49
+ - tst.rb
50
+ homepage: https://github.com/ytti/malline
51
+ licenses: []
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project: mallinna
69
+ rubygems_version: 2.0.14
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Templating language targeting IOS/JunOS configs
73
+ test_files: []
74
+ has_rdoc: