├── var ├── name ├── title ├── created ├── version ├── organization ├── summary ├── authors ├── copyrights ├── repositories ├── requirements ├── description └── resources ├── lib ├── erbside.yml ├── erbside │ ├── gemspec.rb │ ├── inline │ │ ├── bash.rb │ │ ├── ruby.rb │ │ ├── cpp.rb │ │ ├── css.rb │ │ ├── js.rb │ │ └── sgml.rb │ ├── context.rb │ ├── runner.rb │ ├── metadata.rb │ └── inline.rb └── erbside.rb ├── test ├── fixture │ ├── inline_complex.rb │ └── inline.rb └── inline_test.rb ├── Gemfile ├── demo ├── 00_intro.rdoc ├── 09_cli.rdoc ├── applique │ └── env.rb ├── 04_js.rdoc ├── 05_css.rdoc ├── 01_ruby.rdoc ├── 02_bash.rdoc ├── 06_sgml.rdoc └── 03_cpp.rdoc ├── bin └── erbside ├── work ├── defunct │ ├── webme │ │ └── options.yml │ ├── inline-old │ │ ├── css.rb │ │ ├── html.rb │ │ ├── cpp.rb │ │ ├── bash.rb │ │ ├── type.rb │ │ ├── js.rb │ │ └── ruby.rb │ ├── plan.rb │ ├── css │ │ ├── color.css │ │ ├── font.css │ │ └── struct.css │ ├── index.html │ ├── inline.rb │ ├── tiller.rb │ └── whole.rb ├── radio_earth.jpg └── plugins │ └── syckle │ └── erbside.rb ├── .gitignore ├── .yardopts ├── .travis.yml ├── Reapfile ├── MANIFEST ├── Assembly ├── .ruby ├── HISTORY.rdoc ├── NOTICE.rdoc ├── README.rdoc └── .gemspec /var/name: -------------------------------------------------------------------------------- 1 | erbside -------------------------------------------------------------------------------- /var/title: -------------------------------------------------------------------------------- 1 | Erbside -------------------------------------------------------------------------------- /lib/erbside.yml: -------------------------------------------------------------------------------- 1 | ../.ruby -------------------------------------------------------------------------------- /var/created: -------------------------------------------------------------------------------- 1 | 2009-07-15 -------------------------------------------------------------------------------- /var/version: -------------------------------------------------------------------------------- 1 | 0.4.0 2 | -------------------------------------------------------------------------------- /var/organization: -------------------------------------------------------------------------------- 1 | rubyworks -------------------------------------------------------------------------------- /test/fixture/inline_complex.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /var/summary: -------------------------------------------------------------------------------- 1 | ERB-based Inline Templating -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | gemspec 3 | -------------------------------------------------------------------------------- /demo/00_intro.rdoc: -------------------------------------------------------------------------------- 1 | = Erbside Demonstrandum 2 | -------------------------------------------------------------------------------- /var/authors: -------------------------------------------------------------------------------- 1 | --- 2 | - Thomas Sawyer 3 | -------------------------------------------------------------------------------- /bin/erbside: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'erbside' 3 | Erbside.cli 4 | -------------------------------------------------------------------------------- /work/defunct/webme/options.yml: -------------------------------------------------------------------------------- 1 | --- 2 | colors: 3 | back: green 4 | 5 | -------------------------------------------------------------------------------- /var/copyrights: -------------------------------------------------------------------------------- 1 | --- 2 | - (c) 2010 Rubyworks, Thomas Sawyer (BSD-2-Clause) 3 | -------------------------------------------------------------------------------- /var/repositories: -------------------------------------------------------------------------------- 1 | --- 2 | upstream: git://github.com/rubyworks/erbside.git 3 | -------------------------------------------------------------------------------- /work/radio_earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyworks/erbside/master/work/radio_earth.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .reap/digest 2 | .yardoc 3 | pkg 4 | log 5 | tmp 6 | web 7 | work/sandbox 8 | DEMO.* 9 | -------------------------------------------------------------------------------- /var/requirements: -------------------------------------------------------------------------------- 1 | --- 2 | - facets 3 | - qed (test) 4 | - citron (test) 5 | - detroit (build) 6 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --output-dir site/doc 2 | --title Erbside 3 | --readme README.rdoc 4 | lib 5 | - 6 | [A-Z]*.* 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rvm: 3 | - 1.8.7 4 | - 1.9.2 5 | - 1.9.3 6 | - rbx-2.0 7 | - jruby 8 | - ree 9 | script: "bundle exec qed -Ilib qed/" 10 | 11 | -------------------------------------------------------------------------------- /var/description: -------------------------------------------------------------------------------- 1 | Erbside is a simple project-oriented erb-based inline template system. 2 | Inline templates make it easy to do basic code generation without the 3 | need for duplicate files. 4 | -------------------------------------------------------------------------------- /var/resources: -------------------------------------------------------------------------------- 1 | --- 2 | home: http://rubyworks.github.com/erbside 3 | code: http://github.com/rubyworks/erbside 4 | docs: http://rubydoc.info/gems/erbside/frames 5 | mail: http://googlegroups.com/group/rubyworks-mailinglist 6 | -------------------------------------------------------------------------------- /Reapfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | file 'qed/' do 4 | File.open('QED.rdoc', 'w') do |f| 5 | Dir['qed/*.rdoc'].sort.each do |qed_file| 6 | f << File.read(qed_file) 7 | f << "\n\n" 8 | end 9 | end 10 | end 11 | 12 | 13 | -------------------------------------------------------------------------------- /demo/09_cli.rdoc: -------------------------------------------------------------------------------- 1 | == Commandline Interface 2 | 3 | Given a file named 'example.rb' containing: 4 | 5 | example # :erb: change <%= 1+1 %> 6 | 7 | Rendering via the commandline: 8 | 9 | $ erbside -o example.rb 10 | 11 | The result will be: 12 | 13 | change 2 # :erb: change <%= 1+1 %> 14 | 15 | -------------------------------------------------------------------------------- /test/inline_test.rb: -------------------------------------------------------------------------------- 1 | require 'erbside/inline' 2 | 3 | DIRECTORY = File.dirname(__FILE__) 4 | 5 | testcase "Erbside::Inline" do 6 | 7 | test 'inline rendering' do 8 | file = DIRECTORY + '/fixture/inline.rb' 9 | xs = Erbside::Inline.factory(file) 10 | es = xs.new(file) 11 | es.render 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /lib/erbside/gemspec.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rubygems' 3 | 4 | module Gem 5 | class Specification 6 | 7 | def [](k); send(k); end 8 | 9 | def to_h 10 | instance_variables.inject({}) do |h,k| 11 | h[k.sub('@','')] = instance_variable_get(k); h 12 | end 13 | end 14 | end 15 | 16 | end 17 | 18 | rescue LoadError 19 | end 20 | -------------------------------------------------------------------------------- /test/fixture/inline.rb: -------------------------------------------------------------------------------- 1 | # Stuff 2 | puts "Testing...." 3 | 4 | # :erb+14: <%= Dir['*'].sort.join("\n") %> 5 | HISTORY 6 | LICENSE 7 | MANIFEST 8 | README 9 | bin 10 | doc 11 | lib 12 | log 13 | meta 14 | pkg 15 | site 16 | task 17 | test 18 | work 19 | 20 | # Manifest generated 200X #:erb: ^generated <%= 2009 %> 21 | 22 | # Some comment 23 | puts "We are at the end." 24 | 25 | VERSION = "?" #:erb: VERSION = "<%= 1+1 %>" 26 | 27 | # Another comment 28 | puts "Yes we are." 29 | 30 | -------------------------------------------------------------------------------- /lib/erbside/inline/bash.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # Bash Adapter 6 | class Bash < Inline 7 | 8 | EXTENSIONS = %w{.sh} 9 | 10 | # 11 | def self.extensions 12 | EXTENSIONS 13 | end 14 | 15 | # 16 | def remarker 17 | '#' 18 | end 19 | 20 | # 21 | def remarker_block_begin 22 | '#=begin' 23 | end 24 | 25 | # 26 | def remarker_block_end 27 | '#=end' 28 | end 29 | 30 | end 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /lib/erbside/inline/ruby.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # Ruby 6 | class Ruby < Inline 7 | 8 | # 9 | EXTENSIONS = %w{.rb} 10 | 11 | # Ruby file extensions. 12 | def self.extensions 13 | EXTENSIONS 14 | end 15 | 16 | # 17 | def remarker 18 | '#' 19 | end 20 | 21 | # 22 | def remarker_block_begin 23 | '=begin' 24 | end 25 | 26 | # 27 | def remarker_block_end 28 | '=end' 29 | end 30 | 31 | end 32 | 33 | end 34 | 35 | -------------------------------------------------------------------------------- /work/defunct/inline-old/css.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | require 'till/inline/type' 6 | 7 | # = CSS Matcher 8 | # 9 | class CSS < Type 10 | 11 | EXTENSIONS = %w{ .css } 12 | 13 | def self.extensions ; EXTENSIONS ; end 14 | 15 | def self.start(line) 16 | if /^(\s*)(.*?)(\s*\/\*\s*\:till(\+\d*)?\:\s*)/ =~ line 17 | new($&, $1, $2, $3, $4, $') 18 | end 19 | end 20 | 21 | def stop?(line) 22 | if /^(.*?)\*\/(.*?)$/ =~ line 23 | $& 24 | end 25 | end 26 | 27 | end 28 | 29 | end 30 | 31 | end 32 | 33 | -------------------------------------------------------------------------------- /work/defunct/inline-old/html.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | require 'till/inline/type' 6 | 7 | # = HTML Matcher 8 | # 9 | class Html < Type 10 | 11 | EXTENSIONS = %w{ .html } 12 | 13 | def self.extensions ; EXTENSIONS ; end 14 | 15 | def self.start(line) 16 | if /^(\s*)(.*?)(\s*(/ =~ line 23 | $& 24 | end 25 | end 26 | 27 | end#class Html 28 | 29 | end#class Inline 30 | 31 | end#module Till 32 | 33 | -------------------------------------------------------------------------------- /work/defunct/plan.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | # = Tilling Plan 4 | # 5 | # A plan file is used to easily repeat a set of tills. 6 | # 7 | # myfile.html: 8 | # source: templates/myfile.rdoc 9 | # filter: erb, rdoc 10 | # 11 | class Plan 12 | 13 | include Enumerable 14 | 15 | # 16 | 17 | def initialize(root) 18 | file = Dir[File.join(root, '{.config,config}/till/plan.{yml,yaml}')].first 19 | @plan = file ? YAML.load(File.new(file) : {} 20 | end 21 | 22 | # 23 | 24 | def [](file) 25 | @plan[file] 26 | end 27 | 28 | # 29 | 30 | def each(&block) 31 | @plan.each(&block) 32 | end 33 | 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /lib/erbside/inline/cpp.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # C/C++ Adapter 6 | class Cpp < Inline 7 | 8 | EXTENSIONS = %w{ .c .cpp } 9 | 10 | def self.extensions 11 | EXTENSIONS 12 | end 13 | 14 | # 15 | def remarker 16 | '//' 17 | end 18 | 19 | # 20 | def remarker_block_begin 21 | '/*' 22 | end 23 | 24 | # 25 | def remarker_block_end 26 | '*/' 27 | end 28 | 29 | # 30 | def block_match 31 | b = Regexp.escape(remarker_block_begin) 32 | e = Regexp.escape(remarker_block_end) 33 | %r{^(\s*)(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*)((?m:.*?))(\s#{e})} 34 | end 35 | 36 | end 37 | 38 | end 39 | 40 | -------------------------------------------------------------------------------- /lib/erbside/inline/css.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # CSS Adapter 6 | class CSS < Inline 7 | 8 | # 9 | EXTENSIONS = %w{.css} 10 | 11 | # 12 | def self.extensions 13 | EXTENSIONS 14 | end 15 | 16 | # 17 | def remarker 18 | '//' 19 | end 20 | 21 | # 22 | def remarker_block_begin 23 | '/*' 24 | end 25 | 26 | # 27 | def remarker_block_end 28 | '*/' 29 | end 30 | 31 | # 32 | def block_match 33 | b = Regexp.escape(remarker_block_begin) 34 | e = Regexp.escape(remarker_block_end) 35 | %r{^(\s*)(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*)((?m:.*?))(\s#{e})} 36 | end 37 | 38 | end 39 | 40 | end 41 | 42 | -------------------------------------------------------------------------------- /lib/erbside/inline/js.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # Javascript Adapter 6 | class Javascript < Inline 7 | 8 | # 9 | EXTENSIONS = %w{.js} 10 | 11 | # 12 | def self.extensions 13 | EXTENSIONS 14 | end 15 | 16 | # 17 | def remarker 18 | '//' 19 | end 20 | 21 | # 22 | def remarker_block_begin 23 | '/*' 24 | end 25 | 26 | # 27 | def remarker_block_end 28 | '*/' 29 | end 30 | 31 | # 32 | def block_match 33 | b = Regexp.escape(remarker_block_begin) 34 | e = Regexp.escape(remarker_block_end) 35 | %r{^(\s*)(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*)((?m:.*?))(\s#{e})} 36 | end 37 | 38 | end 39 | 40 | end 41 | 42 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | #!mast .ruby .yardopts bin lib man qed spec test [A-Z]*.* 2 | .ruby 3 | .yardopts 4 | bin/erbside 5 | lib/erbside/context.rb 6 | lib/erbside/gemspec.rb 7 | lib/erbside/inline/bash.rb 8 | lib/erbside/inline/cpp.rb 9 | lib/erbside/inline/css.rb 10 | lib/erbside/inline/js.rb 11 | lib/erbside/inline/ruby.rb 12 | lib/erbside/inline/sgml.rb 13 | lib/erbside/inline.rb 14 | lib/erbside/metadata.rb 15 | lib/erbside/runner.rb 16 | lib/erbside.rb 17 | lib/erbside.yml 18 | qed/00_intro.rdoc 19 | qed/01_ruby.rdoc 20 | qed/02_bash.rdoc 21 | qed/03_cpp.rdoc 22 | qed/04_js.rdoc 23 | qed/05_css.rdoc 24 | qed/06_sgml.rdoc 25 | qed/09_cli.rdoc 26 | qed/applique/env.rb 27 | test/fixture/inline.rb 28 | test/fixture/inline_complex.rb 29 | test/inline_test.rb 30 | HISTORY.rdoc 31 | README.rdoc 32 | QED.rdoc 33 | NOTICE.rdoc 34 | -------------------------------------------------------------------------------- /work/defunct/inline-old/cpp.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | require 'till/inline/type' 6 | 7 | # 8 | class Cpp < Type 9 | 10 | EXTENSIONS = %w{ .c .cpp } 11 | 12 | def self.extensions ; EXTENSIONS ; end 13 | 14 | def self.start(line) 15 | if /^(\s*)(.*?)(\s*\/(\/|\*)\s*\:till(\+\d*)?\:\s*)/ =~ line 16 | new($&, $1, $2, $3, $4, $') 17 | end 18 | end 19 | 20 | def stop?(line) 21 | if marker =~ /\/\*/ 22 | if /^.*?\*\// =~ line 23 | $& 24 | end 25 | else 26 | if /^\s*\#\s*:end:/ =~ line 27 | $& 28 | elsif /^\s*(?!:\/\/)/ =~ line 29 | true 30 | end 31 | end 32 | end 33 | 34 | end 35 | 36 | end 37 | 38 | end 39 | 40 | -------------------------------------------------------------------------------- /Assembly: -------------------------------------------------------------------------------- 1 | --- 2 | email: 3 | service: Email 4 | mailto: 5 | - ruby-talk@ruby-lang.org 6 | - rubyworks-mailinglist@googlegroups.com 7 | 8 | github: 9 | gh_pages: web 10 | 11 | gem: 12 | active: true 13 | 14 | qed: 15 | files : demo/*.rdoc 16 | 17 | qedoc: 18 | title: Erbside Demonstrandum 19 | files: demo/*.rdoc 20 | output: 21 | - DEMO.rdoc 22 | - site/demo.html 23 | 24 | #erbside: 25 | # service : Custom 26 | # pipeline: main 27 | # generate: | 28 | # sh 'erbside lib/erbside.rb' 29 | # active: false 30 | 31 | #erbside: 32 | # service: erbside 33 | # active: false 34 | 35 | dnote: 36 | output: log/NOTES.rdoc 37 | 38 | yard: 39 | yardopts: true 40 | priority: 2 41 | active: false 42 | 43 | locat: 44 | active: false 45 | 46 | vclog: 47 | service : VClog 48 | active: false 49 | 50 | -------------------------------------------------------------------------------- /work/defunct/inline-old/bash.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | require 'till/inline/type' 6 | 7 | # = Base Script Matcher 8 | # 9 | class Bash < Type 10 | EXTENSIONS = %w{ .sh } 11 | #PATTERNS = [ 12 | # /^(.*?)\#([ \t]*\:till(\+\d*)?\:)(.*?\S.*?)$/, 13 | # /^(.*?)\#([ \t]*\:till(\+\d*)?\:)[ \t]*\n(?m:.*?)\#[ \t]*\:end\:/, 14 | #] 15 | 16 | def self.extensions ; EXTENSIONS ; end 17 | 18 | def self.start?(line) 19 | if /^(\s*)(.*?)(\s*\#\s*\:till(\+\d*)?\:\s*)/ =~ line 20 | new($&, $1, $2, $3, $4, $') 21 | end 22 | end 23 | 24 | def stop?(line) 25 | if /^\s*\#\s*:end:/ =~ line 26 | $& 27 | elsif /^\s*[^#]/ =~ line 28 | true 29 | end 30 | end 31 | end 32 | 33 | end 34 | 35 | end 36 | 37 | -------------------------------------------------------------------------------- /lib/erbside/context.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | # = Tilling Context 4 | # 5 | class Context 6 | 7 | require 'erbside/metadata' 8 | 9 | # 10 | attr :metadata 11 | 12 | # 13 | def initialize(file, resources=[]) 14 | @filename = file 15 | @directory = File.dirname(file) 16 | @metadata = Metadata.new(resources) 17 | end 18 | 19 | # 20 | def method_missing(s) 21 | @metadata.send(s) 22 | end 23 | 24 | # 25 | def root 26 | metadata.root 27 | end 28 | 29 | # 30 | def to_h 31 | @metadata.to_h 32 | end 33 | 34 | # Processes through erb. 35 | def render(text) 36 | Dir.chdir(@directory) do 37 | erb = ERB.new(text) 38 | erb.filename = @filename.to_s 39 | erb.result(binding) 40 | end 41 | end 42 | 43 | end 44 | 45 | end 46 | 47 | -------------------------------------------------------------------------------- /work/plugins/syckle/erbside.rb: -------------------------------------------------------------------------------- 1 | module Syckle::Plugins 2 | 3 | # = Erbside Generation 4 | # 5 | class Erbside < Service 6 | 7 | cycle :main, :generate 8 | cycle :site, :generate 9 | 10 | # Make automatic? 11 | #autorun do 12 | # ... 13 | #end 14 | 15 | available do |project| 16 | begin 17 | require 'erbside' 18 | true 19 | rescue LoadError 20 | false 21 | end 22 | end 23 | 24 | # 25 | #def safe?; @safe; end 26 | 27 | # 28 | def generate(options={}) 29 | options ||= {} 30 | 31 | dir = nil # defaults to curent directory 32 | 33 | options[:trial] = trial? 34 | options[:debug] = debug? 35 | options[:quiet] = quiet? 36 | options[:force] = force? 37 | 38 | tiller = Erbside::Runner.new(dir, options) 39 | tiller.till 40 | end 41 | 42 | end 43 | 44 | end 45 | 46 | -------------------------------------------------------------------------------- /demo/applique/env.rb: -------------------------------------------------------------------------------- 1 | #require 'tmpdir' 2 | require 'erbside' 3 | 4 | When "Given a file named '(((.*?)))'" do |name, text| 5 | File.open(name, 'w+'){ |f| f << text } 6 | end 7 | 8 | When "Rendering via the commandline" do |text| 9 | #@result = Erbside.cli('-o', 'example.rb') 10 | text.sub!(/^\$\s*/, '') 11 | @result = `#{text}` 12 | end 13 | 14 | When "result will be" do |text| 15 | text.strip.assert == @result.strip 16 | end 17 | 18 | When "The rendered result of '(((.*?)))' will be" do |file, text| 19 | result = "" 20 | runner = Erbside::Runner.new([file], :output=>result) 21 | runner.render 22 | 23 | text.strip.assert == result.strip 24 | end 25 | 26 | 27 | # out = File.join(@tmpdir, "fixture/inline.rb") 28 | # system "till -f #{out}" 29 | # expect = File.read('test/features/proofs/inline.rb') 30 | # result = File.read(out) 31 | # 32 | # assert_equal(expect, result) 33 | 34 | -------------------------------------------------------------------------------- /work/defunct/css/color.css: -------------------------------------------------------------------------------- 1 | /* COLOR */ 2 | 3 | body { color: ##EEEEEE; background: #ffffff; } 4 | h1, h2, h3, h4 { color: #007700; } 5 | a { color: #007700; } 6 | pre { color: white; } 7 | 8 | /* #header .title */ 9 | 10 | #header { } 11 | 12 | .title h1 { color: #007700; } 13 | .title pre { background: transparent; } 14 | 15 | .download { 16 | background: #80F780; 17 | border-color: #007700; 18 | color: ##EEEEEE; 19 | } 20 | 21 | .download a { color: #007700; } 22 | 23 | /* #nav .menu */ 24 | 25 | #nav { border-color: #007700; 26 | background: url(../images/fade.png) repeat-y #80F780; 27 | } 28 | 29 | .menu ul { background: transparent; } 30 | .menu ul li a { color: #007700; border-color: #80F780; } 31 | 32 | /* #main .doc */ 33 | 34 | .doc { } 35 | .doc a { color: #007700; } 36 | .doc a:hover { } 37 | .doc p { color: ##EEEEEE; } 38 | .doc h2 { color: #007700; border-color: #80F780; } 39 | .doc h3 { color: #007700; border-color: #80F780; } 40 | 41 | /* #footer .copyright */ 42 | 43 | /* #footer { background: #green; border-color: #007700; } */ 44 | .copyright { color: colors[:text]; } 45 | 46 | -------------------------------------------------------------------------------- /demo/04_js.rdoc: -------------------------------------------------------------------------------- 1 | == Javascript 2 | 3 | === Sideline Rendering 4 | 5 | Given a file named 'example.js' containing: 6 | 7 | var version = "?"; // :erb: var version = "<%= 1+1 %>"; 8 | 9 | The rendered result of 'example.js' will be: 10 | 11 | var version = "2"; // :erb: var version = "<%= 1+1 %>"; 12 | 13 | Given a file named 'example.js' containing: 14 | 15 | // Manifest generated 2009 #:erb: ^generated <%= 2009 %> 16 | 17 | The rendered result of 'example.js' will be: 18 | 19 | // Manifest generated 2009 #:erb: ^generated <%= 2009 %> 20 | 21 | === Multiline Rendering 22 | 23 | Given a file named 'example.js' containing: 24 | 25 | //:erb+1: <%= %w{z; y; x;}.sort.join("\n") %> 26 | blah blah blah 27 | 28 | The rendered result of 'example.js' will be: 29 | 30 | //:erb+3: <%= %w{z; y; x;}.sort.join("\n") %> 31 | x; 32 | y; 33 | z; 34 | 35 | === Block Rendering 36 | 37 | Given a file named 'example.js' containing: 38 | 39 | /* :erb+1: 40 | <%= %w{z; y; x;}.sort.join("\n") %> 41 | */ 42 | blah blah blah 43 | 44 | The rendered result of 'example.js' will be: 45 | 46 | /* :erb+3: 47 | <%= %w{z; y; x;}.sort.join("\n") %> 48 | */ 49 | x; 50 | y; 51 | z; 52 | 53 | -------------------------------------------------------------------------------- /demo/05_css.rdoc: -------------------------------------------------------------------------------- 1 | == CSS 2 | 3 | === Sideline Rendering 4 | 5 | Given a file named 'example.css' containing: 6 | 7 | { color: #000; } // :erb: { color: #<%= 1+1 %>00; } 8 | 9 | The rendered result of 'example.css' will be: 10 | 11 | { color: #200; } // :erb: { color: #<%= 1+1 %>00; } 12 | 13 | Rather then spell out the entire line we can use the front match 14 | marker. Given a file named 'example.css' containing: 15 | 16 | { color: #000; } // :erb: ^#<%= 2+2 %>00; } 17 | 18 | The rendered result of 'example.css' will be: 19 | 20 | { color: #400; } // :erb: ^#<%= 2+2 %>00; } 21 | 22 | === Multiline Rendering 23 | 24 | Given a file named 'example.css' containing: 25 | 26 | //:erb+1: <%= %w{z; y; x;}.sort.join("\n") %> 27 | blah blah blah 28 | 29 | The rendered result of 'example.css' will be: 30 | 31 | //:erb+3: <%= %w{z; y; x;}.sort.join("\n") %> 32 | x; 33 | y; 34 | z; 35 | 36 | === Block Rendering 37 | 38 | Given a file named 'example.css' containing: 39 | 40 | /* :erb+1: 41 | <%= %w{z; y; x;}.sort.join("\n") %> 42 | */ 43 | blah blah blah 44 | 45 | The rendered result of 'example.css' will be: 46 | 47 | /* :erb+3: 48 | <%= %w{z; y; x;}.sort.join("\n") %> 49 | */ 50 | x; 51 | y; 52 | z; 53 | 54 | -------------------------------------------------------------------------------- /work/defunct/css/font.css: -------------------------------------------------------------------------------- 1 | /* FONT */ 2 | 3 | html { font-family: sans-serif; font-size: 100%; } 4 | body { } 5 | pre { font-family: monospace; } 6 | td { text-align: left; } 7 | p { text-align: justify; font-size: 80%; font-weight: bold; line-height: 170%; } 8 | li { font-size: 80%; font-weight: bold; line-height: 110%; } 9 | a { text-decoration: none; } 10 | a:hover { text-decoration: underline; } 11 | 12 | /* #header .title */ 13 | 14 | .title { font-size: 80%; } 15 | .title h1 { font-size: 450%; font-weight: bold; } 16 | 17 | .download { font-size: 150%; text-align: center; } 18 | .download h1 { font-size: 64px; } 19 | .download h1 a:hover { text-decoration: none; } 20 | 21 | /* #main .doc */ 22 | 23 | .doc { } 24 | .doc a { font-size: 100%; } 25 | .doc a:hover { text-decoration: underline; } 26 | .doc h2 { font-size: 2em; font-weight: bold; } 27 | .doc h3 { font-style: italic;} 28 | 29 | /* #nav .menu */ 30 | 31 | .menu { text-align: left; } 32 | .menu ul li a { font-family: sans-serif; font-weight: bold; text-decoration: none; } 33 | .menu ul li a:hover { text-decoration: underline; } 34 | .menu ul li a:active { text-decoration: underline; } 35 | 36 | /* #footer .copyright */ 37 | 38 | .copyright { font: bold .8em sans-serif; } 39 | 40 | -------------------------------------------------------------------------------- /.ruby: -------------------------------------------------------------------------------- 1 | --- 2 | source: 3 | - var 4 | authors: 5 | - name: Thomas Sawyer 6 | email: transfire@gmail.com 7 | copyrights: 8 | - holder: Rubyworks, Thomas Sawyer 9 | year: '2010' 10 | license: BSD-2-Clause 11 | replacements: [] 12 | alternatives: [] 13 | requirements: 14 | - name: facets 15 | - name: qed 16 | groups: 17 | - test 18 | development: true 19 | - name: citron 20 | groups: 21 | - test 22 | development: true 23 | - name: detroit 24 | groups: 25 | - build 26 | development: true 27 | dependencies: [] 28 | conflicts: [] 29 | repositories: 30 | - uri: git://github.com/rubyworks/erbside.git 31 | scm: git 32 | name: upstream 33 | resources: 34 | home: http://rubyworks.github.com/erbside 35 | code: http://github.com/rubyworks/erbside 36 | docs: http://rubydoc.info/gems/erbside/frames 37 | mail: http://googlegroups.com/group/rubyworks-mailinglist 38 | extra: {} 39 | load_path: 40 | - lib 41 | revision: 0 42 | created: '2009-07-15' 43 | summary: ERB-based Inline Templating 44 | title: Erbside 45 | version: 0.4.0 46 | name: erbside 47 | description: ! "Erbside is a simple project-oriented erb-based inline template system. 48 | \nInline templates make it easy to do basic code generation without the\nneed for 49 | duplicate files." 50 | organization: rubyworks 51 | date: '2011-11-11' 52 | -------------------------------------------------------------------------------- /demo/01_ruby.rdoc: -------------------------------------------------------------------------------- 1 | == Ruby 2 | 3 | === Sideline Rendering 4 | 5 | Given a file named 'example.rb' containing: 6 | 7 | # ordinary comment 8 | VERSION = "?" # :erb: VERSION = "<%= 1+1 %>" 9 | 10 | The rendered result of 'example.rb' will be: 11 | 12 | # ordinary comment 13 | VERSION = "2" # :erb: VERSION = "<%= 1+1 %>" 14 | 15 | === Sideline Rendering with First Match Marker 16 | 17 | Given a file named 'example.rb' containing: 18 | 19 | # Script generated 200X #:erb: ^generated <%= 2009 %> 20 | 21 | The rendered result of 'example.rb' will be: 22 | 23 | # Script generated 2009 #:erb: ^generated <%= 2009 %> 24 | 25 | Notice in this case we rendered a comment. 26 | 27 | === Multiline Rendering 28 | 29 | Given a file named 'example.rb' containing: 30 | 31 | #:erb+1: <%= %w{z y x}.sort.join("\n") %> 32 | blah blah blah 33 | 34 | The rendered result of 'example.rb' will be: 35 | 36 | #:erb+3: <%= %w{z y x}.sort.join("\n") %> 37 | x 38 | y 39 | z 40 | 41 | === Block Rendering 42 | 43 | Given a file named 'example.rb' containing: 44 | 45 | =begin :erb+0: 46 | <%= %w{a b c}.map{ |x| "#{x}!" }.join("\n") %> 47 | =end 48 | 49 | The rendered result of 'example.rb' will be: 50 | 51 | =begin :erb+3: 52 | <%= %w{a b c}.map{ |x| "#{x}!" }.join("\n") %> 53 | =end 54 | a! 55 | b! 56 | c! 57 | 58 | -------------------------------------------------------------------------------- /demo/02_bash.rdoc: -------------------------------------------------------------------------------- 1 | == Bash 2 | 3 | === Sideline Rendering 4 | 5 | Given a file named 'example.sh' containing: 6 | 7 | # ordinary comment 8 | VERSION = "?" # :erb: VERSION = "<%= 1+1 %>" 9 | 10 | The rendered result of 'example.sh' will be: 11 | 12 | # ordinary comment 13 | VERSION = "2" # :erb: VERSION = "<%= 1+1 %>" 14 | 15 | === Sideline Rendering with First Match Marker 16 | 17 | Given a file named 'example.sh' containing: 18 | 19 | # Script generated 200X #:erb: ^generated <%= 2009 %> 20 | 21 | The rendered result of 'example.sh' will be: 22 | 23 | # Script generated 2009 #:erb: ^generated <%= 2009 %> 24 | 25 | Notice in this case we rendered a comment. 26 | 27 | === Multiline Rendering 28 | 29 | Given a file named 'example.sh' containing: 30 | 31 | #:erb+1: <%= %w{z y x}.sort.join("\n") %> 32 | blah blah blah 33 | 34 | The rendered result of 'example.sh' will be: 35 | 36 | #:erb+3: <%= %w{z y x}.sort.join("\n") %> 37 | x 38 | y 39 | z 40 | 41 | === Block Rendering 42 | 43 | Given a file named 'example.sh' containing: 44 | 45 | #=begin :erb+0: 46 | <%= %w{a b c}.map{ |x| "#{x}!" }.join("\n") %> 47 | #=end 48 | 49 | The rendered result of 'example.sh' will be: 50 | 51 | #=begin :erb+3: 52 | <%= %w{a b c}.map{ |x| "#{x}!" }.join("\n") %> 53 | #=end 54 | a! 55 | b! 56 | c! 57 | 58 | -------------------------------------------------------------------------------- /demo/06_sgml.rdoc: -------------------------------------------------------------------------------- 1 | == XML/HTML 2 | 3 | === Sideline Example 4 | 5 | Given a file named 'example.xml' containing: 6 | 7 | 8 | 9 | 10 | 11 | 12 | The rendered result of 'example.xml' will be: 13 | 14 | 15 | 16 | 17 | 18 | 19 | === Multiline Rendering 20 | 21 | Given a file named 'example.xml' containing: 22 | 23 | 24 | 25 | 26 | blah blah blah 27 | 28 | 29 | 30 | The rendered result of 'example.xml' will be: 31 | 32 | 33 | 34 | 35 | x 36 | y 37 | z 38 | 39 | 40 | 41 | === Block Rendering 42 | 43 | Given a file named 'example.xml' containing: 44 | 45 | 46 | 49 | 50 | 51 | The rendered result of 'example.xml' will be: 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /demo/03_cpp.rdoc: -------------------------------------------------------------------------------- 1 | == C/C++ 2 | 3 | === Sideline Example 4 | 5 | Sideline example, where the erb comment is to the side of the 6 | text it will replace. Given a file named 'example.c' containing: 7 | 8 | version = "?"; // :erb: version = "<%= 1+1 %>"; 9 | 10 | The rendered result of 'example.c' will be: 11 | 12 | version = "2"; // :erb: version = "<%= 1+1 %>"; 13 | 14 | === Multiline Example 15 | 16 | Multi-line example, where the erb comment replaces multiple lines but 17 | is defined by a single line. Given a file named 'example.c' containing: 18 | 19 | void main() { 20 | //:erb+1: <%= %w{z(); y(); x();}.sort.join("\n").indent(2) %> 21 | will be replaced 22 | } 23 | 24 | The rendered result of 'example.c' will be: 25 | 26 | void main() { 27 | //:erb+3: <%= %w{z(); y(); x();}.sort.join("\n").indent(2) %> 28 | x(); 29 | y(); 30 | z(); 31 | } 32 | 33 | === Block Example 34 | 35 | Block example, where the ERB comment replaces multiple lines and is 36 | defined by a block comment. Given a file named 'example.c' containing: 37 | 38 | /* :erb+0: 39 | <%= %w{a b c}.map{ |e| "\#include <#{e}.h>" }.join("\n") %> 40 | */ 41 | 42 | The rendered result of 'example.c' will be: 43 | 44 | /* :erb+3: 45 | <%= %w{a b c}.map{ |e| "\#include <#{e}.h>" }.join("\n") %> 46 | */ 47 | #include 48 | #include 49 | #include 50 | 51 | -------------------------------------------------------------------------------- /HISTORY.rdoc: -------------------------------------------------------------------------------- 1 | = HISTORY 2 | 3 | == 0.4.0 / 2011-10-27 4 | 5 | This release improves upon the command options. It gets rid 6 | of --force and --skip and replaces them with --prompt, which 7 | allows the user to interactively render each file. This release 8 | also adds --exclude and --ignore options for finer file selection. 9 | 10 | Changes: 11 | 12 | * Remove --force and --skip options. 13 | * Add --prompt option. 14 | * Add --exclude and --ignore options. 15 | 16 | 17 | == 0.3.0 / 2011-10-23 18 | 19 | This release fixes two issues. First, it fixes the .gemspec file which 20 | prevented a fully proper build of the last release. Secondly, it fixes 21 | metadata access so it will work without `dotruby` gem. 22 | 23 | Changes: 24 | 25 | * Fix gemspec file typos. 26 | * Fix require rescue for dotruby. 27 | 28 | 29 | == 0.2.1 / 2011-08-23 30 | 31 | Failed to fix dependencies in previous release. 32 | 33 | Changes: 34 | 35 | * Remove POM from dependencies. 36 | 37 | 38 | == 0.2.0 / 2011-08-22 39 | 40 | The release drops use of POM altogether and adds support for multiple optional 41 | metadata resources in its place, including .ruby and .gemspecs, yaml files 42 | (ending in .yaml/.yml) and "metadir" metadata directories. 43 | 44 | Changes: 45 | 46 | * Support multiple metadata resources (via -r/--resource). 47 | * Block templates keep the same layout as given. 48 | * Project metadata is dynamically loaded using .ruby file. 49 | 50 | 51 | == 0.1.0 / 2011-02-22 52 | 53 | This is the initial release of Erbside. Erbside is a derivative of and 54 | successor to an earlier program called Till (a name I never quite liked). 55 | 56 | Changes: 57 | 58 | * Happy Birthday! 59 | 60 | -------------------------------------------------------------------------------- /NOTICE.rdoc: -------------------------------------------------------------------------------- 1 | = COPYRIGHT NOTICES 2 | 3 | == Erbside 4 | 5 | Copyright:: (c) 2009 Thomas Sawyer, Rubyworks 6 | License:: BSD-2-Clause 7 | Website:: http://rubyworks.github.com/erbside 8 | 9 | Copyright 2009 Thomas Sawyer. All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, are 12 | permitted provided that the following conditions are met: 13 | 14 | 1. Redistributions of source code must retain the above copyright notice, this list of 15 | conditions and the following disclaimer. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 18 | of conditions and the following disclaimer in the documentation and/or other materials 19 | provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 23 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 24 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | (http://spdx.org/licenses/BSD-2-Clause) 32 | 33 | -------------------------------------------------------------------------------- /work/defunct/css/struct.css: -------------------------------------------------------------------------------- 1 | /* STRUCTURE */ 2 | 3 | body {margin:0;padding:0;position:relative;} 4 | div {margin:0;padding:0;} 5 | h1 {margin:5px 0;} 6 | li {padding:3px 0;} 7 | pre {margin:10px 0;} 8 | pre code {padding:10px 10px;} 9 | img {border:none;} 10 | td {vertical-align:top;} 11 | 12 | /* #header .title .download .logo */ 13 | 14 | #header {position:relative; padding-right:200px;} 15 | 16 | .title {width:720px; margin:0 auto; padding:10px 0;} 17 | .title ul {padding-left: 20px;} 18 | 19 | .download {width:200px;height:120px;float:right;margin-top:30px;padding:10px;border:4px solid;-moz-border-radius:20px;border-radius:20px;} 20 | .logo {float:right;margin-top:10px;padding:10px;} 21 | 22 | /* #nav .menu */ 23 | 24 | #nav { position: fixed; padding: 20px; right: 0; top: 40px; width: 200px; 25 | border-top: 4px solid; border-left: 4px solid; border-bottom: 4px solid; 26 | -moz-border-radius-topleft: 20px; -webkit-border-top-left-radius: 20px; 27 | -moz-border-radius-bottomleft: 20px; -webkit-border-bottom-left-radius: 20px; 28 | } 29 | 30 | .menu { margin: 0 auto; text-align: left; } 31 | .menu ul { list-style-type: none; margin: 0px; padding: 0px; width: 100%; position: relative; } 32 | .menu ul li { margin: 15px 10px 15px 0; line-height: 20px; } 33 | .menu ul li a { border-top: 0 solid; } 34 | 35 | /* #main .doc */ 36 | 37 | #main { padding: 0px; padding-right: 200px; } 38 | 39 | .doc { width: 720px; margin: 0 auto; padding: 20px 0 10px 0; min-height: 890px; } 40 | .doc h2 { border-left: 0px solid; padding-left: 0; } 41 | .doc h2 img { margin: 0 0 0 0; } 42 | .doc h3 { border-bottom: 1px dotted; } 43 | 44 | /* #footer .copyright */ 45 | 46 | #footer { padding-right: 200px; border-top: 0px solid; margin-top: 10px; } 47 | 48 | .advert { margin: 30px 0 10px 0; text-align: center; } 49 | 50 | .copyright { width: 720px; margin: 0 auto; padding: 0 0 30px 0; } 51 | 52 | -------------------------------------------------------------------------------- /lib/erbside.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | require 'erbside/runner' 3 | 4 | # 5 | module MetadataMixin 6 | def metadata 7 | @_metadata ||= ( 8 | require 'yaml' 9 | YAML.load_file(File.dirname(__FILE__) + '/erbside.yml') 10 | ) 11 | end 12 | def const_missing(name) 13 | key = name.to_s.downcase 14 | metadata.key?(key) ? metadata[key] : super(name) 15 | end 16 | end 17 | extend MetadataMixin 18 | 19 | # Yea, this is old school. 20 | #VERSION="0.2.0" #:erb: VERSION="<%= version %>" 21 | 22 | # 23 | def self.cli(argv=ARGV) 24 | require 'optparse' 25 | require 'erbside/runner' 26 | 27 | options = {:resources=>[]} 28 | 29 | usage = OptionParser.new do |use| 30 | use.banner = 'Usage: erbside [OPTIONS] [FILE1 FILE2 ...]' 31 | 32 | #use.on('--delete', 'delete templates when finished') do 33 | # options[:delete] = true 34 | #end 35 | 36 | use.on('-r', '--resource FILE', 'get metadata from file') do |file| 37 | options[:resources] << file 38 | end 39 | 40 | use.on('-p', '--prompt', 'prompt for each write') do 41 | options[:prompt] = true 42 | end 43 | 44 | #use.on('-s', '--skip', 'automatically skip overwrites') do 45 | # options[:skip] = true 46 | #end 47 | 48 | use.on('-o', '--stdout', 'dump output to stdout instead of saving') do 49 | options[:output] = $stdout 50 | end 51 | 52 | use.on('-t', '--trial', '--dryrun', '--dry-run', 'run in trial mode (no disk writes)') do 53 | $TRIAL = true 54 | end 55 | 56 | use.on('--debug', 'run in debug mode') do 57 | $DEBUG = true 58 | end 59 | 60 | use.on_tail('-h', '--help', 'display this help information') do 61 | puts use 62 | exit 63 | end 64 | end 65 | 66 | usage.parse!(argv) 67 | 68 | files = argv 69 | 70 | runner = Erbside::Runner.new(files, options) 71 | 72 | runner.render 73 | end 74 | 75 | end 76 | -------------------------------------------------------------------------------- /work/defunct/index.html: -------------------------------------------------------------------------------- 1 |

Whole File Templating

2 | 3 |

Whole file templating takes a designated template, renders it according 4 | to a specified sequence of filters and then saves it to a designated output.

5 | 6 |

Erbside template files require an extension of .til or .erbside 7 | . Erbside templates use YAML front 8 | matter to specifiy there filter and output options. Here is an example README.til 9 | file.

10 | 11 |
12 | ---
13 | output: README.rdoc
14 | format: rdoc
15 | filter: erb
16 | ---
17 | 
18 | = <%= title %>
19 | 
20 | <%= title %> is such a wonderful project.
21 | 
22 | Copyright <%= released.strftime("%Y") %> <%= author %>
23 | 
24 | 25 |

If YAML front matter is NOT provided, then the template will be rendered via Erb to a 26 | file less the .til or .erbside extension. Eg. README.til would 27 | be processed by Erb to produce README.

28 | 29 |
37 | 38 | 39 | 42 | 43 |
  • Templates live where the files live (if you want). Damn that's Easy.
  • 44 |
  • Uses Tilt for deverse format support. Versitle and Easy.
  • 45 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = Erbside 2 | 3 | {Homepage}[http://rubyworks.github.com/erbside] | 4 | {Documentation}[http://rubydoc.info/gems/erbside/frames] | 5 | {Source Code}[http://github.com/rubyworks/erbside] | 6 | {Mailing List}[http://googlegroups.com/group/rubyworks-mailinglist] 7 | 8 | {}[http://travis-ci.org/rubyworks/erbside] 9 | 10 | 11 | == DESCRIPTION 12 | 13 | Erbside is a simple in-line project-oriented ERB-based template system. 14 | With Erbside it is very easy to do basic templating without the need 15 | for file duplication. 16 | 17 | Erbside also provides direct access to project metadata. It does this 18 | automatically via {DotRuby}[http://dotruby.github.com/dotruby], or it 19 | can be instructed to use other resources, including a project's gemspec. 20 | 21 | 22 | == FEATURES 23 | 24 | * Easy to use. 25 | * Uses ERB. Easy. 26 | * Uses .ruby and .gemspec. Easy. 27 | * The file is the template. Easy. 28 | * Did I mention it was easy? 29 | 30 | 31 | == SYNOPSIS 32 | 33 | In a Ruby script add an ERB comment. 34 | 35 | module YourLibrary 36 | VERSION = "1.0.0" #:erb: VERSION="<%= version %>" 37 | end 38 | 39 | Then run: 40 | 41 | $ erbside myscript.rb 42 | 43 | Unless you use the --force option, Erbside will ask you if 44 | want to overwrite the file. Type y and all of the #:erb: 45 | in-line templating will be filled in. 46 | 47 | To see what erbside would do without actually writing to the file, 48 | use the `-o/--stdout` option. 49 | 50 | $ erbside -o myscript.rb 51 | 52 | 53 | == INSTALL 54 | 55 | === Gem Install 56 | 57 | To install with RubyGems simply open a console and type: 58 | 59 | $ gem install erb 60 | 61 | === Site Install 62 | 63 | Local installation requires Setup.rb (gem install setup), 64 | then download the tarball package and type: 65 | 66 | $ tar -xvzf erb-1.0.0.tgz 67 | $ cd erb-1.0.0.tgz 68 | $ sudo setup.rb all 69 | 70 | Windows users use 'ruby setup.rb all'. 71 | 72 | 73 | == COPYRIGHTS 74 | 75 | Copyright (c) 2009 Thomas Sawyer, Rubyworks. All rights reserved. 76 | 77 | Erbside is made available according to the terms of the *FreeBSD* license. 78 | 79 | See NOTICE.rdoc for details. 80 | 81 | -------------------------------------------------------------------------------- /work/defunct/inline-old/type.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | # = Type Base Class 6 | # 7 | class Type 8 | 9 | # C L A S S - M E T H O D S 10 | 11 | # 12 | def self.map 13 | @map ||= ( 14 | Type.register.inject({}) do |hash, base| 15 | base.extensions.each do |ext| 16 | hash[ext] = base 17 | end 18 | hash 19 | end 20 | ) 21 | end 22 | 23 | def self.register 24 | @register ||= [] 25 | end 26 | 27 | def self.inherited(base) 28 | register << base 29 | end 30 | 31 | def self.extensions ; raise ; end 32 | 33 | 34 | ## A T T R I B U T E S 35 | 36 | #attr :string 37 | #attr :indent 38 | #attr :front 39 | #attr :mark 40 | #attr :pad 41 | #attr :till 42 | #attr :count 43 | #attr :body 44 | #attr :post 45 | 46 | # Initialize a new type match. 47 | #def initialize(opts) 48 | # @line = opts[:line] 49 | # @indent = opts[:indent] 50 | # @front = opts[:front] 51 | # @mark = opts[:mark] 52 | # @pad = opts[:pad] 53 | # @till = opts[:till] 54 | # @count = opts[:count].to_i 55 | # @body = opts[:body].strip 56 | # @post = opts[:post] 57 | #end 58 | 59 | ## Add a tail line. 60 | #def <<(line) 61 | # @tail << line 62 | #end 63 | 64 | # 65 | #def to_s(result, cnt=nil) 66 | # if cnt 67 | # mark = marker.sub(/\+\d+/, "+#{cnt}") 68 | # "#{indent}#{front}#{mark}#{tail}\n" + result + "\n" # TODO: there should be no front 69 | # elsif carrot? 70 | # b = tail.index('^') + 1 71 | # e = tail.index(/[<{]/) || - 1 72 | # m = tail[b...e] 73 | # i = front.index(m) 74 | # result = front[0...i] + result.sub('^','') 75 | # "#{indent}#{result}#{marker}#{tail}\n" 76 | # else 77 | # "#{indent}#{result}#{marker}#{tail}\n" 78 | # end 79 | #end 80 | 81 | # Is a carrot matcher? 82 | def self.carrot?(render) 83 | /^\s*\^/.match(render) 84 | end 85 | 86 | end#class Type 87 | 88 | end#class Inline 89 | 90 | end#module Till 91 | 92 | -------------------------------------------------------------------------------- /work/defunct/inline-old/js.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | module Inline 3 | 4 | require 'till/inline/type' 5 | 6 | # 7 | class Javascript < Parser 8 | 9 | EXTENSIONS = %w{ .js } 10 | 11 | LINE_BACK = /^(\s*)(.*?)(\s*\/\/\s*\:till)(\+\d*)?(\:)(.*?\S.*?)$/ 12 | 13 | LINE_BLOCK = /^(\ *)(.*?)(\ *\/\/\ *\:till(\+\d*)?(\:)(\s*\n))((?m:\/\/.*?\n)*)(\/\/[ \t]*:end:)/ 14 | 15 | BLOCK = /^(.*?)\/\*(\s*\:till(\+\d*)?\:)(?m:.*?)\*\// 16 | 17 | def extensions 18 | EXTENSIONS 19 | end 20 | 21 | def parse(text) 22 | text = parse_line_backs(text) 23 | text = parse_line_blocks(text) 24 | text = parse_blocks(text) 25 | end 26 | 27 | def parse_lines_backs(text) 28 | text.gsub(LINE_BACK) do |m| 29 | indent = $1 30 | front = $2 31 | remark = $3 + $4.to_s + $5 + $6 32 | render = $6.strip 33 | count = $4 34 | #offset = 1 35 | result = render_template(render) 36 | format(indent, front, remark, result, count) 37 | end 38 | end 39 | 40 | def parse_line_blocks(text) 41 | text.gsub(LINE_BLOCK) do |m| 42 | indent = $1 43 | front = $2 44 | remark = $3 + $4.to_s + $5 +$6 45 | render = $7.strip.gsub(/^\s*\/\//, '') 46 | count = $3 47 | result = render_template(render) 48 | format(indent, front, remark, result, count) 49 | end 50 | end 51 | 52 | def parse_blocks(text) 53 | text.gsub(BLOCK) do |m| 54 | indent = $1 55 | front = nil 56 | remark = $2 + $3.to_s + $4 + $5 57 | render = $5.strip 58 | count = $3 59 | result = render_template(render) 60 | format(indent, front, remark, result, count) 61 | end 62 | end 63 | 64 | # 65 | def format(indent, front, remark, render, multi=nil) 66 | size = render.count("\n") 67 | if multi || size > 0 68 | indent + remark.sub(/:till(\+\d+)?:/, ":till+#{size}:") + "\n" + render 69 | else 70 | if render =~ /^\s*\^/ 71 | b = render.index('^') + 1 72 | e = render.index(/[<{]/) || - 1 73 | m = render[b...e] 74 | i = front.index(m) 75 | render = front[0...i] + render.sub('^','') 76 | end 77 | "\n" + indent + render + remark.sub(/:till(\+\d+)?:/, ":till:") + "\n" 78 | end 79 | end 80 | 81 | end#class Javascript 82 | 83 | end#module Inline 84 | end#module Till 85 | 86 | -------------------------------------------------------------------------------- /lib/erbside/inline/sgml.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | require 'erbside/inline' 4 | 5 | # XML and HTML 6 | class SGML < Inline 7 | 8 | EXTENSIONS = %w{ .html .xml } 9 | 10 | # 11 | def self.extensions 12 | EXTENSIONS 13 | end 14 | 15 | # 16 | def remarker 17 | '' 28 | end 29 | 30 | # 31 | def line_match 32 | rem = Regexp.escape(remarker) 33 | /^(\ *)(.*?)(\ *)(#{rem})(\ *)(:#{TAG})()?(:)(.*?\S.*?)(-->)$/ 34 | end 35 | 36 | # 37 | def block_match 38 | b = Regexp.escape(remarker_block_begin) 39 | e = Regexp.escape(remarker_block_end) 40 | %r{^(\s*)(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*)((?m:.*?))(\s#{e})} 41 | end 42 | 43 | # 44 | def block_parts(match_data) 45 | { :indent => match_data[1], 46 | :pad => match_data[3], 47 | :count => match_data[5], 48 | :space => match_data[7], 49 | :template => match_data[8], 50 | :tail => match_data[9] 51 | } 52 | end 53 | 54 | =begin 55 | # 56 | def render_result 57 | text = content 58 | text = render_backs(text) 59 | text = render_blocks(text) 60 | end 61 | 62 | # 63 | BACKS = /^(\ *)(.*?\S.*?)(\ *)()$/ 64 | 65 | # 66 | def render_backs(text) 67 | index = 0 68 | result = '' 69 | 70 | text.scan(BACKS) do |m| 71 | md = $~ 72 | 73 | indent = md[1] 74 | front = md[2] 75 | remark = [ md[3], md[4], md[5], md[6], md[7], md[8] ].join('') 76 | tmplt = md[7].strip 77 | count = nil 78 | 79 | render = render_template(tmplt) 80 | 81 | result << text[index...md.begin(0)] 82 | result << format_back(indent, front, remark, tmplt, render) 83 | 84 | #index = md.end(0) 85 | i = md.end(0) + 1 86 | count.to_i.times{ i = text[i..-1].index("\n") + i + 1 } 87 | index = i 88 | end 89 | 90 | result << text[index..-1] 91 | result 92 | end 93 | 94 | # 95 | BLOCKS = /^(\ *)()/m 96 | 97 | # 98 | def render_blocks(text) 99 | index = 0 100 | result = '' 101 | 102 | text.scan(BLOCKS) do |m| 103 | md = $~ 104 | 105 | indent = md[1] 106 | #front = nil 107 | remark = [ md[1], md[2], md[3], md[4], md[5], md[6], md[7], md[8] ].join('') 108 | tmplt = md[7].strip 109 | count = md[5] 110 | 111 | render = render_template(tmplt) 112 | 113 | result << text[index...md.begin(0)] 114 | result << format_block(indent, remark, tmplt, render) 115 | 116 | #index = md.end(0) 117 | i = md.end(0) + 1 118 | count.to_i.times{ i = text[i..-1].index("\n") + i + 1 } 119 | index = i 120 | end 121 | 122 | result << text[index..-1] 123 | result 124 | end 125 | 126 | # 127 | def format_back(indent, front, remark, tmplt, render) 128 | size = render.count("\n") 129 | if size > 0 130 | format_block(indent, remark, tmplt, front + render) 131 | else 132 | if tmplt =~ /^\s*\^/ 133 | b = tmplt.index('^') + 1 134 | e = tmplt.index(/[<{]/) || - 1 135 | m = tmplt[b...e] 136 | i = front.index(m) 137 | render = front[0...i] + render.sub('^','') 138 | end 139 | indent + render + remark.sub(/:till(\+\d+)?:/, ":till:") + "\n" 140 | end 141 | end 142 | 143 | # 144 | def format_block(indent, remark, tmplt, render) 145 | size = render.count("\n") 146 | indent + remark.sub(/:till(\+\d+)?:/, ":till+#{size+1}:") + "\n" + render +"\n" 147 | end 148 | =end 149 | 150 | end 151 | 152 | end 153 | 154 | -------------------------------------------------------------------------------- /work/defunct/inline-old/ruby.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | class Inline 4 | 5 | require 'till/inline/type' 6 | 7 | # = Ruby Script Matcher 8 | # 9 | # TODO: Add =begin ... =end matching 10 | 11 | class Ruby < Type 12 | 13 | EXTENSIONS = %w{ .rb } 14 | 15 | #PATTERNS = [ 16 | # /^(.*?)\#([ \t]*\:till(\+\d*)?\:)(.*?\S.*?)$/, 17 | # /^(.*?)\#([ \t]*\:till(\+\d*)?\:)[ \t]*\n(?m:.*?)\#[ \t]*\:end\:/, 18 | # /^=begin\s*\:till\:(.*?)^=end/m 19 | #] 20 | 21 | def self.extensions ; EXTENSIONS ; end 22 | 23 | def self.start?(line) 24 | /\#\s*\:till(\+\d*)?\:/ =~ line 25 | end 26 | 27 | def self.parse(lines, index) 28 | line = lines[index] 29 | 30 | case line 31 | when /^(\s*)(.*?)(\s*\#\s*\:till)(\+\d*)?(\:)(.*?\S.*?)$/ 32 | indent = $1 33 | front = $2 34 | remark = $3 + $4.to_s + $5 + $6 35 | render = $6.strip 36 | count = $4 37 | offset = 1 38 | 39 | [indent, front, remark, render, count, offset] 40 | 41 | when /^(\s*)(\#\s*\:till)(\+\d*)?(\:)(\s*)$/ 42 | indent = $1 43 | front = nil 44 | remark = $2 + $3.to_s + $4 + $5 45 | render = $5.strip 46 | count = $3 47 | 48 | i, s = index + 1, nil 49 | until s or i == lines.size 50 | remain = lines[i] 51 | s = stop?(remain) 52 | i += 1 53 | end 54 | 55 | remark = remark + lines[index+1...i].join("\n") 56 | render = render + lines[index+1...i].join("\n") 57 | 58 | [indent, front, remark, render, count, i] 59 | end 60 | end 61 | 62 | # 63 | def self.stop?(line) 64 | if md = /^(\s*)(\#\s*:end:)/.match(line) 65 | [md, true] 66 | elsif md = /^(\s*)[^#]/.match(line) 67 | [md, false] 68 | end 69 | end 70 | 71 | # 72 | def self.format(indent, front, remark, render, multi=nil) 73 | size = render.count("\n") 74 | if multi || size > 0 75 | indent + remark.sub(/:till(\+\d+)?:/, ":till+#{size}:") + "\n" + render 76 | else 77 | if render =~ /^\s*\^/ 78 | b = render.index('^') + 1 79 | e = render.index(/[<{]/) || - 1 80 | m = render[b...e] 81 | i = front.index(m) 82 | render = front[0...i] + render.sub('^','') 83 | end 84 | "\n" + indent + render + remark.sub(/:till(\+\d+)?:/, ":till:") + "\n" 85 | end 86 | end 87 | 88 | end#class Ruby 89 | 90 | end#class Inline 91 | 92 | end#module Till 93 | 94 | 95 | 96 | =begin 97 | # 98 | class Javascript < Type 99 | EXTENSIONS = %w{ .js } 100 | PATTERNS = [ 101 | /^(.*?)\/\/([ \t]*\:till(\+\d*)?\:)(.*?\S.*?)$/, 102 | /^(.*?)\/\/([ \t]*\:till(\+\d*)?\:)[ \t]*\n(?m:.*?)\/\/[ \t]*\:end\:/, 103 | /^(.*?)\/\*(\s*\:till(\+\d*)?\:)(?m:.*?)\*\// 104 | ] 105 | 106 | def self.extensions ; EXTENSIONS ; end 107 | def self.patterns ; PATTERNS ; end 108 | end 109 | 110 | 111 | # 112 | class Cpp < Type 113 | EXTENSIONS = %w{ .c .cpp } 114 | PATTERNS = [ 115 | /^(.*?)\/\/([ \t]*\:till(\+\d*)?\:)(.*?\S.*?)$/, 116 | /^(.*?)\/\/([ \t]*\:till(\+\d*)?\:)[ \t]*\n(?m:.*?)\/\/[ \t]*\:end\:/, 117 | /^(.*?)\/\*(\s*\:till(\+\d*)?\:)(?m:.*?)\*\// 118 | ] 119 | 120 | def self.extensions ; EXTENSIONS ; end 121 | def self.patterns ; PATTERNS ; end 122 | end 123 | 124 | 125 | # 126 | class SGML < Type 127 | EXTENSIONS = %w{ .html } 128 | PATTERNS = [ 129 | /^(.*?)/ 130 | ] 131 | 132 | def self.extensions ; EXTENSIONS ; end 133 | def self.patterns ; PATTERNS ; end 134 | end 135 | 136 | # 137 | class CSS < Type 138 | EXTENSIONS = %w{ .css } 139 | PATTERNS = [ 140 | /^(.*?)\/\*(\s*\:till(\+\d*)?\:)(?m:.*?)\*\// 141 | ] 142 | 143 | def self.extensions ; EXTENSIONS ; end 144 | def self.patterns ; PATTERNS ; end 145 | end 146 | =end 147 | 148 | -------------------------------------------------------------------------------- /.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'yaml' 4 | 5 | Gem::Specification.new do |gemspec| 6 | 7 | manifest = Dir.glob('manifest{,.txt}', File::FNM_CASEFOLD).first 8 | 9 | scm = case 10 | when File.directory?('.git') 11 | :git 12 | end 13 | 14 | files = case 15 | when manifest 16 | File.readlines(manifest). 17 | map{ |line| line.strip }. 18 | reject{ |line| line.empty? || line[0,1] == '#' } 19 | when scm == :git 20 | `git ls-files -z`.split("\0") 21 | else 22 | Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ? 23 | end.select{ |path| File.file?(path) } 24 | 25 | patterns = { 26 | :bin_files => 'bin/*', 27 | :lib_files => 'lib/{**/}*.rb', 28 | :ext_files => 'ext/{**/}extconf.rb', 29 | :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}', 30 | :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}' 31 | } 32 | 33 | glob_files = lambda { |pattern| 34 | Dir.glob(pattern).select { |path| 35 | File.file?(path) && files.include?(path) 36 | } 37 | } 38 | 39 | #files = glob_files[patterns[:files]] 40 | 41 | executables = glob_files[patterns[:bin_files]].map do |path| 42 | File.basename(path) 43 | end 44 | 45 | extensions = glob_files[patterns[:ext_files]].map do |path| 46 | File.basename(path) 47 | end 48 | 49 | metadata = YAML.load_file('.ruby') 50 | 51 | # build-out the gemspec 52 | 53 | case metadata['revision'] 54 | when 0 55 | gemspec.name = metadata['name'] 56 | gemspec.version = metadata['version'] 57 | gemspec.summary = metadata['summary'] 58 | gemspec.description = metadata['description'] 59 | 60 | metadata['authors'].each do |author| 61 | gemspec.authors << author['name'] 62 | 63 | if author.has_key?('email') 64 | if gemspec.email 65 | gemspec.email << author['email'] 66 | else 67 | gemspec.email = [author['email']] 68 | end 69 | end 70 | end 71 | 72 | gemspec.licenses = metadata['licenses'] 73 | 74 | metadata['requirements'].each do |req| 75 | name = req['name'] 76 | version = req['version'] 77 | groups = req['groups'] || [] 78 | 79 | case version 80 | when /^(.*?)\+$/ 81 | version = ">= #{$1}" 82 | when /^(.*?)\-$/ 83 | version = "< #{$1}" 84 | when /^(.*?)\~$/ 85 | version = "~> #{$1}" 86 | end 87 | 88 | if groups.empty? or groups.include?('runtime') 89 | # populate runtime dependencies 90 | if gemspec.respond_to?(:add_runtime_dependency) 91 | gemspec.add_runtime_dependency(name,*version) 92 | else 93 | gemspec.add_dependency(name,*version) 94 | end 95 | else 96 | # populate development dependencies 97 | if gemspec.respond_to?(:add_development_dependency) 98 | gemspec.add_development_dependency(name,*version) 99 | else 100 | gemspec.add_dependency(name,*version) 101 | end 102 | end 103 | end 104 | 105 | # convert external dependencies into a requirements 106 | if metadata['external_dependencies'] 107 | ##gemspec.requirements = [] unless metadata['external_dependencies'].empty? 108 | metadata['external_dependencies'].each do |req| 109 | gemspec.requirements << req.to_s 110 | end 111 | end 112 | 113 | # determine homepage from resources 114 | homepage = metadata['resources'].find{ |key, url| key =~ /^home/ } 115 | gemspec.homepage = homepage.last if homepage 116 | 117 | gemspec.require_paths = metadata['load_path'] || ['lib'] 118 | gemspec.post_install_message = metadata['install_message'] 119 | 120 | # RubyGems specific metadata 121 | gemspec.files = files 122 | gemspec.extensions = extensions 123 | gemspec.executables = executables 124 | 125 | if Gem::VERSION < '1.7.' 126 | gemspec.default_executable = gemspec.executables.first 127 | end 128 | 129 | gemspec.test_files = glob_files[patterns[:test_files]] 130 | 131 | unless gemspec.files.include?('.document') 132 | gemspec.extra_rdoc_files = glob_files[patterns[:doc_files]] 133 | end 134 | end 135 | end 136 | -------------------------------------------------------------------------------- /lib/erbside/runner.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | # The runner class doe the work of rendering and saving 4 | # targeted files. 5 | # 6 | class Runner 7 | 8 | require 'erbside/inline' 9 | require 'erbside/metadata' 10 | 11 | require 'facets/kernel/ask' 12 | require 'facets/string/tabto' 13 | 14 | 15 | # A T T R I B U T E S 16 | 17 | # Files to render. 18 | attr_accessor :files 19 | 20 | # Exclude from files. 21 | attr_accessor :exclude 22 | 23 | # Exclude files by matching against basename. 24 | attr_accessor :ignore 25 | 26 | # Ask before write. 27 | attr_accessor :prompt 28 | 29 | # The +output+ can be any object that responds to #<<. 30 | attr_accessor :output 31 | 32 | # Files from which to gather metadata. 33 | attr_accessor :resources 34 | 35 | 36 | # I N I T I A L I Z E 37 | 38 | # 39 | def initialize(files, options) 40 | @files = files || "**/*#{ext_glob}" 41 | 42 | @exclude = options[:exclude] 43 | @ignore = options[:ignore] 44 | @prompt = options[:prompt] 45 | @output = options[:output] 46 | @resources = options[:resource] || options[:resources] 47 | 48 | @trial = options[:trial] || $TRIAL 49 | @debug = options[:debug] || $DEBUG 50 | end 51 | 52 | # 53 | #def metadata 54 | # @metadata ||= Metadata.new(*resources) 55 | #end 56 | 57 | # 58 | def prompt? ; @prompt ; end 59 | 60 | # 61 | def debug? ; @debug ; end 62 | 63 | # 64 | def trial? ; @trial ; end 65 | 66 | # 67 | def dryrun? ; @trial ; end 68 | 69 | # 70 | def render 71 | $stderr.puts('[DRYRUN]') if trial? 72 | target_files.each do |file| 73 | render_file(file) 74 | end 75 | end 76 | 77 | private 78 | 79 | # Search through a file for inline templates, render and output. 80 | def render_file(file) 81 | parser = Inline.factory(file) 82 | 83 | if !parser 84 | puts " unrecognized #{file}" if $DEBUG || $TRIAL 85 | return 86 | end 87 | 88 | template = parser.new(file, *resources) 89 | 90 | #if template.exist? #&& skip? 91 | # puts " #{template.relative_output} skipped" 92 | #else 93 | result = template.render 94 | if output 95 | output << (result + "\n") 96 | else 97 | save(template, result) 98 | end 99 | #end 100 | end 101 | 102 | # 103 | def save(template, result) 104 | name = template.relative_output 105 | save = false 106 | 107 | if trial? 108 | puts " #{name}" 109 | else 110 | if template.exist? 111 | if !template.changed? 112 | puts " unchanged #{name}" 113 | elsif prompt? 114 | save = prompt_user(template) 115 | else 116 | save = true 117 | end 118 | else 119 | save = true 120 | end 121 | end 122 | 123 | if save 124 | template.save 125 | puts " written #{name}" 126 | end 127 | end 128 | 129 | # 130 | def target_files 131 | targets = collect_files(files) 132 | targets -= collect_files(exclude) if exclude 133 | targets.reject!{ |t| [ignore].flatten.compact.any?{ |m| File.fnmatch?(m, t) } } 134 | targets 135 | end 136 | 137 | # 138 | def collect_files(files) 139 | filelist = [] 140 | [files].flatten.each do |glob| 141 | Dir.glob(glob).each do |file| 142 | if File.directory?(file) 143 | filelist.concat(collect_directory_files(file)) 144 | else 145 | filelist << file 146 | end 147 | end 148 | end 149 | end 150 | 151 | # 152 | def collect_directory_files(dir) 153 | Dir[File.join(dir,"**/*#{ext_glob}")] 154 | end 155 | 156 | # 157 | def ext_glob 158 | '{' + Inline.extension_list.join(',') + '}' 159 | end 160 | 161 | # 162 | def prompt_user(template) 163 | save = false 164 | name = template.relative_output 165 | 166 | case ask(" overwrite `#{name}'? [y/N/v/q] ").downcase 167 | when 'y', 'yes', 'ye' 168 | save = true 169 | when 'v', 'view', 'vi', 'vie' 170 | puts File.read(template.file) 171 | save = prompt_user(template) 172 | when 'q', 'quit' 173 | abort 174 | end 175 | return save 176 | end 177 | 178 | end 179 | 180 | end 181 | -------------------------------------------------------------------------------- /lib/erbside/metadata.rb: -------------------------------------------------------------------------------- 1 | begin; require 'dotruby'; rescue LoadError; end 2 | 3 | module Erbside 4 | 5 | # Metadata belongs to the project being scaffold. 6 | # 7 | class Metadata 8 | 9 | # Canonical metadata file. 10 | CANONICAL_FILENAME = '.ruby' 11 | 12 | # Root directory is indicated by the presence of a +meta/+ directory, 13 | # or +.meta/+ hidden directory. 14 | ROOT_INDICATORS = [ "{#{CANONICAL_FILENAME},meta/,.meta/}" ] 15 | 16 | # Project root pathname. 17 | attr :root 18 | 19 | # Data resources. 20 | attr :resources 21 | 22 | # Construct new Metadata object. 23 | def initialize(resources, options={}) 24 | @root = self.class.root(options[:root]) || Dir.pwd 25 | @data = [] 26 | 27 | @resources = [resources].flatten.compact 28 | @resources << '.ruby' if canonical? 29 | 30 | @resources.each do |source| 31 | case File.basename(source) 32 | when CANONICAL_FILENAME 33 | if canonical? 34 | if defined?(::DotRuby) 35 | @data << DotRuby::Spec.find(root) #(CANONICAL_FILENAME) 36 | else 37 | @data << YAML.load_file(canonical_file) 38 | end 39 | end 40 | when /\.gemspec$/ 41 | require 'erbside/gemspec' 42 | @data << ::Gem::Specification.load(source) 43 | when /\.ya?ml$/ 44 | @data << YAML.load_file(source) 45 | else 46 | if File.directory?(source) 47 | @data << load_metadir(source) 48 | else 49 | # now what ? 50 | end 51 | end 52 | end 53 | 54 | @cache = {} 55 | end 56 | 57 | # If method is missing, check the POM and metadata cache. 58 | def method_missing(name, *args) 59 | return super unless args.empty? 60 | self[name] 61 | end 62 | 63 | # Lookup metadata entry. 64 | def [](name) 65 | name, value = name.to_s, nil 66 | return @cache[name] if @cache.key?(name) 67 | begin 68 | @data.find{ |d| value = d[name] } 69 | rescue 70 | end 71 | @cache[name] = value 72 | end 73 | 74 | # Provide metadata to hash. Some (stencil) template systems 75 | # need the data in hash form. 76 | def to_h 77 | @data.reverse.inject({}){ |h,d| h.merge(d.to_h) } 78 | end 79 | 80 | private 81 | 82 | def canonical_file 83 | File.join(root, CANONICAL_FILENAME) 84 | end 85 | 86 | # 87 | def canonical? 88 | File.exist?(canonical_file) 89 | end 90 | 91 | # Load metadata cache. This serves as the fallback for the POM. 92 | def load_metadir(dir=nil) 93 | data = {} 94 | Dir[File.join(dir || metadir, '*')].each do |file| 95 | next unless File.file?(file) 96 | 97 | case File.extname(file) 98 | when '.yaml' 99 | val = YAML.load(File.new(file)) 100 | data.merge!(val) 101 | when '' 102 | val = File.read(file).strip 103 | val = YAML.load(val) if val =~ /\A---/ 104 | data[File.basename(file)] = val 105 | else 106 | # ignore 107 | end 108 | end 109 | data 110 | end 111 | 112 | # What is project root's meta directory? 113 | def metadir 114 | @metadir ||= Dir[File.join(root, '{meta,.meta}/')].first || 'meta/' 115 | end 116 | 117 | # 118 | #def load_value(name) 119 | # file = File.join(metadir, name) 120 | # file = Dir[file].first 121 | # if file && File.file?(file) 122 | # #return erb(file).strip 123 | # return File.read(file).strip 124 | # end 125 | #end 126 | 127 | # Locate the project's root directory. This is determined 128 | # by ascending up the directory tree from the current position 129 | # until the ROOT_INDICATORS is matched. Returns +nil+ if not found. 130 | def self.root(local=Dir.pwd) 131 | local ||= Dir.pwd 132 | Dir.chdir(local) do 133 | dir = nil 134 | ROOT_INDICATORS.find do |i| 135 | dir = locate_root_at(i) 136 | end 137 | dir ? Pathname.new(File.dirname(dir)) : nil 138 | end 139 | end 140 | 141 | # 142 | def self.locate_root_at(indicator) 143 | root = nil 144 | dir = Dir.pwd 145 | while !root && dir != '/' 146 | find = File.join(dir, indicator) 147 | root = Dir.glob(find, File::FNM_CASEFOLD).first 148 | #break if root 149 | dir = File.dirname(dir) 150 | end 151 | root ? Pathname.new(root) : nil 152 | end 153 | 154 | end 155 | 156 | end 157 | -------------------------------------------------------------------------------- /work/defunct/inline.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | # = Inline Templating 4 | # 5 | class Inline 6 | 7 | # R E Q U I R E M E N T S 8 | 9 | require 'erb' 10 | require 'tilt' 11 | require 'till/context' 12 | 13 | 14 | # C O N S T A N T S 15 | 16 | # Supported templating systems. 17 | STENCILS = %w{ .erb .liquid .mustache } 18 | 19 | 20 | # A T T R I B U T E S 21 | 22 | # The file to receive inline templating. 23 | attr :file 24 | 25 | # The extname of the file. 26 | attr :extension 27 | 28 | # Location of the file. 29 | attr :location 30 | 31 | # The rendered result. 32 | attr :result 33 | 34 | # Rendering context/scope. 35 | attr :context 36 | 37 | # Extension name of stenciling template system 38 | # to use. This determines with templating system to use, 39 | # such as .erb, .liquid, etc. This defaults to '.erb', 40 | # but can be changed in the file with: 41 | # 42 | # # :till.stencil: 43 | # 44 | attr :stencil 45 | 46 | 47 | # I N I T I A L I Z E 48 | 49 | # 50 | def initialize(file) 51 | @file = file 52 | @extension = File.extname(file) 53 | @location = File.dirname(File.expand_path(file)) 54 | 55 | self.stencil = '.erb' 56 | 57 | @context = Context.new(@location) 58 | end 59 | 60 | # 61 | def stencil=(ext) 62 | ext = (ext[0,1] == '.' ? ext : ".#{ext}") 63 | raise "unsupported stencil type -- #{ext}" unless STENCILS.include?(ext) 64 | @stencil = ext 65 | end 66 | 67 | # 68 | def root 69 | context.metadata.root 70 | end 71 | 72 | # 73 | def render 74 | render_inline(file) 75 | end 76 | 77 | # 78 | def render_inline(file) 79 | #name = file.sub(Dir.pwd+'/', '') 80 | save = false 81 | text = '' 82 | lines = File.readlines(file) 83 | i = 0 84 | while i < lines.size 85 | line = lines[i] 86 | if md = /^\s*#\s*:till.stencil:(.*?)/.match(line) 87 | self.type = md[1].strip 88 | text << line 89 | elsif md = /^(\s*)#(\s*):till\+(\d*):/.match(line) 90 | temp = md.post_match 91 | code = md.post_match 92 | line = lines[i+=1] 93 | while i < lines.size && line =~ /^\s*^#/ 94 | temp << line 95 | code << line 96 | line = lines[i+=1] 97 | end 98 | res = render_template(code.gsub(/^\s*#*/,'').strip) 99 | text << md[1] + "#" + md[2] + ":till+#{res.split("\n").size}:" 100 | text << temp 101 | text << res 102 | text << "\n" 103 | save = true 104 | i += md[3].to_i 105 | elsif md = /^(\s*).*?(\s*#\s*:till:)/.match(line) 106 | pm = md.post_match.strip 107 | if pm[0,1] == '^' 108 | pm = pm[1..-1].strip 109 | fm = pm[0...(pm.index('<')||-1)] 110 | ri = line.index(fm) 111 | if ri 112 | text << line[0...ri] + render_template(pm) + md[2] + md.post_match 113 | else 114 | puts "waning: skipped line #{i} no match for #{fm}" 115 | text << line 116 | end 117 | else 118 | text << md[1] + render_template(pm) + md[2] + md.post_match 119 | end 120 | save = true 121 | i += 1 122 | else 123 | text << line 124 | i += 1 125 | end 126 | end 127 | 128 | @result = text 129 | end 130 | 131 | # 132 | 133 | def render_template(text) 134 | template = Tilt[stencil] 135 | unless template 136 | warn "unknown template type #{stencil}" 137 | template = Tilt::ERBTemplate 138 | end 139 | render_tilt(template.new{ text }) 140 | end 141 | 142 | # 143 | 144 | def render_tilt(template) 145 | Dir.chdir(location) do 146 | template.render(@context) 147 | end 148 | end 149 | 150 | # 151 | 152 | def relative_output(dir=nil) 153 | dir = dir || Dir.pwd 154 | output.sub(dir+'/', '') 155 | end 156 | 157 | # 158 | 159 | def exist? 160 | File.exist?(output) 161 | end 162 | 163 | # Has the file changed? 164 | 165 | def changed? 166 | if exist? 167 | File.read(output) != result 168 | else 169 | true 170 | end 171 | end 172 | 173 | # Save result to file. 174 | 175 | def save 176 | File.open(output, 'w'){ |f| f << result } 177 | end 178 | 179 | # Output file (same as the input file). 180 | 181 | def output 182 | file 183 | end 184 | 185 | # 186 | 187 | #def erb(text, file=nil) 188 | # if file 189 | # dir = File.dirname(file) 190 | # Dir.chdir(dir) do 191 | # context.erb(text) 192 | # end 193 | # else 194 | # context.erb(text) 195 | # end 196 | #end 197 | 198 | end 199 | 200 | end 201 | 202 | 203 | -------------------------------------------------------------------------------- /work/defunct/tiller.rb: -------------------------------------------------------------------------------- 1 | require 'till/metadata' 2 | require 'facets/kernel/ask' 3 | require 'facets/string/tabto' 4 | require 'erb' 5 | 6 | module Till 7 | 8 | # The Tiller class is used to generate files from 9 | # embebbded ERB template files. 10 | # 11 | class Tiller 12 | 13 | attr_accessor :files 14 | 15 | attr_accessor :force 16 | 17 | attr_accessor :skip 18 | 19 | #attr_accessor :delete 20 | 21 | # 22 | def initialize(files, options) 23 | files = files || Dir['**/*.til'] 24 | files = files.map do |file| 25 | if File.directory?(file) 26 | collect_usable_files(file) 27 | else 28 | file 29 | end 30 | end.flatten 31 | @files = files 32 | @force = options[:force] 33 | @skip = options[:skip] 34 | #@delete = options[:delete] 35 | end 36 | 37 | def collect_usable_files(dir) 38 | Dir[File.join(dir,'**/*.{till,til,rb}')] 39 | end 40 | 41 | def delete? ; @delete ; end 42 | def force? ; @force ; end 43 | def skip? ; @skip ; end 44 | 45 | def debug? ; $DEBUG ; end 46 | def trial? ; $TRIAL ; end 47 | 48 | # 49 | #def tillfiles 50 | # @tillfiles ||= Dir[File.join(@output, '**/*.till')].select{ |f| File.file?(f) } 51 | #end 52 | 53 | # 54 | #def rubyfiles 55 | # @rubyfiles ||= Dir[File.join(@output, '**/*.rb')].select{ |f| File.file?(f) } 56 | #end 57 | 58 | def till 59 | files.each{ |file| 60 | raise "unsupport file type -- #{file}" unless File.extname =~ /^\.(rb|til|till)$/ 61 | end 62 | 63 | files.each do |file| 64 | case File.extname(file) 65 | when '.till', '.til' 66 | till_template(file) 67 | when '.rb' 68 | till_inline(file) 69 | end 70 | end 71 | end 72 | 73 | # Search for till templates (*.till) and render. 74 | # 75 | def till_template(file) 76 | result = erb(File.read(file)) 77 | fname = file.chomp(File.extname(file)) 78 | write(fname, result) 79 | #rm(file) if delete? # TODO 80 | end 81 | 82 | # Search through Ruby files for inline till templates. 83 | def till_inline(file) 84 | name = file.sub(Dir.pwd+'/', '') 85 | save = false 86 | text = '' 87 | lines = File.readlines(file) 88 | i = 0 89 | while i < lines.size 90 | line = lines[i] 91 | if md = /^(\s*)#(\s*):till\+(\d*):/.match(line) 92 | temp = md.post_match 93 | code = md.post_match 94 | line = lines[i+=1] 95 | while i < lines.size && line =~ /^\s*^#/ 96 | temp << line 97 | code << line 98 | line = lines[i+=1] 99 | end 100 | res = erb(code.gsub(/^\s*#*/,'').strip, file) 101 | text << md[1] + "#" + md[2] + ":till+#{res.split("\n").size}:" 102 | text << temp 103 | text << res 104 | text << "\n" 105 | save = true 106 | i += md[3].to_i 107 | elsif md = /^(\s*).*?(\s*#\s*:till:)/.match(line) 108 | pm = md.post_match.strip 109 | if pm[0,1] == '^' 110 | pm = pm[1..-1].strip 111 | fm = pm[0...(pm.index('<')||-1)] 112 | ri = line.index(fm) 113 | if ri 114 | text << line[0...ri] + erb(pm, file) + md[2] + md.post_match 115 | else 116 | puts "waning: skipped line #{i} no match for #{fm}" 117 | text << line 118 | end 119 | else 120 | text << md[1] + erb(pm, file) + md[2] + md.post_match 121 | end 122 | save = true 123 | i += 1 124 | else 125 | text << line 126 | i += 1 127 | end 128 | end 129 | 130 | if save 131 | write(file, text) 132 | end 133 | end 134 | 135 | # 136 | def write(fname, text) 137 | name = fname.sub(Dir.pwd+'/', '') 138 | if trial? 139 | puts " #{name}" 140 | else 141 | if File.exist?(fname) 142 | if skip? # TODO: skip before running erb ? 143 | puts " skipped #{name}" 144 | return 145 | elsif File.read(fname) == text 146 | puts " unchanged #{name}" 147 | return 148 | elsif !force? 149 | case ask(" overwrite #{name}? ") 150 | when 'y', 'yes' 151 | else 152 | return 153 | end 154 | end 155 | end 156 | File.open(fname, 'w'){ |f| f << text } 157 | puts " written #{name}" 158 | end 159 | end 160 | 161 | # 162 | def context 163 | @conext ||= Erb.new() #TODO: @output ? 164 | end 165 | 166 | def erb(text, file=nil) 167 | if file 168 | dir = File.dirname(file) 169 | Dir.chdir(dir) do 170 | context.erb(text) 171 | end 172 | else 173 | context.erb(text) 174 | end 175 | end 176 | 177 | # Tiller's erb context 178 | # 179 | class Erb 180 | 181 | def initialize(dir=nil) 182 | @metadata = Metadata.new(dir) 183 | end 184 | 185 | def method_missing(s) 186 | @metadata.send(s) 187 | end 188 | 189 | # Processes through erb. 190 | def erb(text) 191 | erb = ERB.new(text) 192 | erb.result(binding) 193 | end 194 | 195 | end#class Context 196 | 197 | end#class Tiller 198 | 199 | end 200 | 201 | -------------------------------------------------------------------------------- /work/defunct/whole.rb: -------------------------------------------------------------------------------- 1 | module Till 2 | 3 | # = Whole Template 4 | # 5 | class Whole 6 | 7 | # R E Q U I R E M E N T S 8 | 9 | # TODO: Load engines only if used? 10 | 11 | begin ; require 'rubygems' ; rescue LoadError ; end # why? 12 | begin ; require 'erb' ; rescue LoadError ; end 13 | begin ; require 'redcloth' ; rescue LoadError ; end 14 | begin ; require 'bluecloth' ; rescue LoadError ; end 15 | begin ; require 'rdiscount' ; rescue LoadError ; end 16 | 17 | begin 18 | require 'liquid' 19 | #Liquid::Template.register_filter(TemplateFilters) 20 | rescue LoadError 21 | end 22 | 23 | begin 24 | require 'haml' 25 | #Haml::Template.options[:format] = :html5 26 | rescue LoadError 27 | end 28 | 29 | begin 30 | require 'rdoc/markup/simple_markup' 31 | require 'rdoc/markup/simple_markup/to_html' 32 | rescue LoadError 33 | end 34 | 35 | require 'tilt' 36 | 37 | require 'till/context' 38 | 39 | 40 | # A T T R I B U T E S 41 | 42 | # File pathname of the template file. 43 | attr :file 44 | 45 | # Directory location of the template +file+. 46 | attr :location 47 | 48 | # Format of the template (in terms of extension names). 49 | attr :format 50 | 51 | # Where to save the rendered result (defaults to +file+ w/o it's extension). 52 | # This is also often referred to as the *target*. 53 | attr :output 54 | 55 | # List of redering filters to processes file through (defaults to +extension+ plus +erb+). 56 | attr :filters 57 | 58 | # Stores the rendered result, after #render is called. 59 | attr :result 60 | 61 | # Body of file. 62 | attr :content 63 | 64 | # Context/scope of template rendering. 65 | attr :context 66 | 67 | 68 | # I N I T I A L I Z E 69 | 70 | # 71 | def initialize(file) 72 | @file = file 73 | 74 | case ext = File.extname(file) 75 | when '.till', '.til' 76 | fname = file.chomp(ext) 77 | else 78 | fname = file 79 | end 80 | 81 | #@format = File.extname(fname) 82 | @location = File.dirname(File.expand_path(file)) 83 | 84 | text = File.read(file).rstrip 85 | 86 | # front matter indicator 87 | if text =~ /\A---/ 88 | text = text.sub(/---.*?\n/, '') 89 | meta, body = *text.split(/^---/) 90 | else 91 | meta = nil 92 | body = text 93 | end 94 | 95 | @content = body 96 | 97 | fm = meta ? YAML.load(meta) : {} 98 | 99 | self.filters = fm['filter'] || ['erb'] 100 | 101 | self.format = fm['format'] || File.extname(fname) 102 | 103 | if fm['output'] 104 | self.output = fm['output'] 105 | else 106 | self.output = fname #.chomp(extension) #+ DEFAULT_CONVERSIONS[filters.last] 107 | end 108 | 109 | 110 | 111 | #@context = Context.new(@location) # prime context/scope 112 | end 113 | 114 | # 115 | 116 | def output=(path) 117 | if path[0,1] == '/' 118 | path = File.join(root, path[1..-1]) 119 | else 120 | path = File.join(location, path) 121 | end 122 | @output = File.expand_path(path) 123 | end 124 | 125 | # 126 | 127 | def format=(ext) 128 | ext = ext.to_s 129 | ext = (ext[0,1] == '.' ? ext : ".#{ext}") 130 | case ext 131 | when '.md' 132 | ext = '.markdown' 133 | when '.tt' 134 | ext = '.textile' 135 | end 136 | @format = ext 137 | end 138 | 139 | # 140 | 141 | def filters=(list) 142 | @filters = [list].flatten.compact.map{ |f| f.sub(/^\./,'') } 143 | end 144 | 145 | # 146 | 147 | def relative_output(dir=nil) 148 | dir = dir || Dir.pwd 149 | output.sub(dir+'/', '') 150 | end 151 | 152 | # Does the output file exist? 153 | 154 | def exist? 155 | File.exist?(output) 156 | end 157 | 158 | # 159 | 160 | def context 161 | @context ||= Context.new(location) 162 | end 163 | 164 | # TODO: maybe bring root discovery up a level or two ? 165 | 166 | def root 167 | context.metadata.root 168 | end 169 | 170 | # Render a whole template. 171 | 172 | def render 173 | context = Context.new(location) # prime context/scope 174 | result = content 175 | 176 | filters.each do |filter| 177 | if filter == 'html' # TODO: +next+ if html format and html filter ? 178 | engine = Tilt[format] 179 | else 180 | engine = Tilt[filter] 181 | end 182 | raise "unknown filter #{filter}" unless engine 183 | result = Dir.chdir(location) do 184 | engine.new{result}.render(context) 185 | end 186 | end 187 | @result = result 188 | end 189 | 190 | # Is the current rendering different then the output file's content? 191 | # This will call #render if it hasn't been called yet. 192 | 193 | def changed? 194 | render unless result 195 | if exist? 196 | File.read(output) != result 197 | else 198 | true 199 | end 200 | end 201 | 202 | # Save the rendering to the output file. 203 | # This will call #render if it hasn't been called yet. 204 | 205 | def save 206 | render unless result 207 | if File.exist?(output) 208 | mode = File.stat(output).mode 209 | File.chmod(mode | 0000220, output) 210 | File.open(output, 'w'){ |f| f << result } 211 | File.chmod(mode, output) 212 | else 213 | File.open(output, 'w'){ |f| f << result } 214 | File.chmod(0440, output) # change to read-only mode 215 | end 216 | end 217 | 218 | end 219 | 220 | end 221 | 222 | -------------------------------------------------------------------------------- /lib/erbside/inline.rb: -------------------------------------------------------------------------------- 1 | module Erbside 2 | 3 | # Base class for all the inline parsers. 4 | # 5 | # TODO: Split this into two classes, one for inline and one for blocks. 6 | class Inline 7 | 8 | # C L A S S - M E T H O D S 9 | 10 | # 11 | def self.factory(file) 12 | map[File.extname(file)] 13 | end 14 | 15 | # 16 | def self.map 17 | @map ||= ( 18 | register.inject({}) do |hash, base| 19 | base.extensions.each do |ext| 20 | hash[ext] = base 21 | end 22 | hash 23 | end 24 | ) 25 | end 26 | 27 | def self.register 28 | @register ||= [] 29 | end 30 | 31 | def self.inherited(base) 32 | register << base 33 | end 34 | 35 | # 36 | def self.extensions 37 | raise NotImplementedError 38 | end 39 | 40 | # 41 | def self.extension_list 42 | register.map{ |x| x.extensions }.flatten 43 | end 44 | 45 | # R E Q U I R E M E N T S 46 | 47 | require 'pathname' 48 | require 'erb' 49 | 50 | require 'erbside/context' 51 | require 'erbside/inline/bash' 52 | require 'erbside/inline/cpp' 53 | require 'erbside/inline/css' 54 | require 'erbside/inline/sgml' 55 | require 'erbside/inline/js' 56 | require 'erbside/inline/ruby' 57 | 58 | 59 | # C O N S T A N T S 60 | 61 | # 62 | TAG = 'erb' 63 | 64 | 65 | # A T T R I B U T E S 66 | 67 | # 68 | attr :file 69 | 70 | # 71 | attr :type 72 | 73 | # 74 | attr :context 75 | 76 | # The rendered result. 77 | attr :result 78 | 79 | 80 | # I N I T I A L I Z E 81 | 82 | # 83 | def initialize(file, *resources) 84 | @file = Pathname.new(file) 85 | @type = @file.extname 86 | 87 | @context = Context.new(@file, resources) 88 | end 89 | 90 | # 91 | def content 92 | @content ||= File.read(file) 93 | end 94 | 95 | # 96 | def render 97 | @result = render_result 98 | end 99 | 100 | # 101 | def render_template(text) 102 | #Dir.chdir(file.parent) do 103 | context.render(text) 104 | #end 105 | end 106 | 107 | # 108 | def relative_output(dir=nil) 109 | dir = dir || Dir.pwd 110 | output.sub(dir+'/', '') 111 | end 112 | 113 | # 114 | def exist? 115 | File.exist?(output) 116 | end 117 | 118 | # Has the file changed? 119 | def changed? 120 | if exist? 121 | File.read(output) != result 122 | else 123 | true 124 | end 125 | end 126 | 127 | # Save result to file. 128 | def save 129 | File.open(output, 'w'){ |f| f << result } 130 | end 131 | 132 | # Output file (same as the input file). 133 | def output 134 | file 135 | end 136 | 137 | # 138 | def render_result 139 | text = content 140 | text = render_sides(text) 141 | text = render_blocks(text) 142 | end 143 | 144 | # 145 | def remarker 146 | raise NotImplementedError 147 | end 148 | 149 | # 150 | def remarker_multiline 151 | raise NotImplementedError 152 | end 153 | 154 | # 155 | def line_match 156 | rem = Regexp.escape(remarker) 157 | /^(\ *)(.*?)(\ *)(#{rem})(\ *)(:#{TAG})(\+\d*)?(:)(.*?\S.*?)$/ 158 | end 159 | 160 | # 161 | def render_sides(text) 162 | index = 0 163 | result = '' 164 | 165 | text.scan(line_match) do |m| 166 | md = $~ 167 | 168 | indent = md[1] 169 | front = md[2] 170 | #remark = [ md[3], md[4], md[5], md[6], md[7], md[8], md[9] ].join('') 171 | remark = md[3..-1].join('') 172 | tmplt = md[9].strip 173 | count = md[7].to_i 174 | 175 | render = render_template(tmplt) 176 | 177 | result << text[index...md.begin(0)] 178 | result << format_side(indent, front, remark, tmplt, render, !count.zero?) 179 | 180 | #index = md.end(0) 181 | i = md.end(0) + 1 182 | count.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 } 183 | index = i 184 | end 185 | 186 | result << text[index..-1].to_s 187 | result 188 | end 189 | 190 | # 191 | def format_side(indent, front, remark, tmplt, render, multi=nil) 192 | size = render.count("\n") 193 | if multi || size > 0 194 | indent + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}+#{size+1}:") + "\n" + render + "\n" 195 | else 196 | if tmplt =~ /^\s*\^/ 197 | b = tmplt.index('^') + 1 198 | e = tmplt.index(/[<{]/) || - 1 199 | m = tmplt[b...e] 200 | i = front.index(m) 201 | render = front[0...i] + render.sub('^','') 202 | end 203 | indent + render + remark.sub(/:#{TAG}(\+\d+)?:/, ":#{TAG}:") + "\n" 204 | end 205 | end 206 | 207 | # 208 | def block_match 209 | b = Regexp.escape(remarker_block_begin) 210 | e = Regexp.escape(remarker_block_end) 211 | %r{^()(#{b})(\s*)(:#{TAG})(\+\d*)?(\:)(\s*\n)((?m:.*?))(\n#{e})} 212 | end 213 | 214 | # 215 | def block_parts(match_data) 216 | { :indent => match_data[1], 217 | :pad => match_data[3], 218 | :count => match_data[5], 219 | :space => match_data[7], 220 | :template => match_data[8], 221 | :tail => match_data[9] 222 | } 223 | end 224 | 225 | # 226 | def render_blocks(text) 227 | index = 0 228 | result = '' 229 | 230 | text.scan(block_match) do |m| 231 | md = $~ 232 | 233 | #remark = md[0] 234 | 235 | parts = block_parts(md) 236 | 237 | indent = parts[:indent] 238 | pad = parts[:pad] 239 | count = parts[:count] 240 | tmplt = parts[:template] 241 | 242 | render = render_template(tmplt) 243 | 244 | result << text[index...md.begin(0)] 245 | result << format_block(parts, render) 246 | 247 | i = md.end(0) + 1 248 | count.to_i.times{ i = text[i..-1].index(/(\n|\Z)/) + i + 1 } 249 | index = i 250 | end 251 | 252 | result << text[index..-1].to_s 253 | result 254 | end 255 | 256 | # 257 | def format_block(parts, render) 258 | indent, pad, space, template, tail = parts.values_at(:indent, :pad, :space, :template, :tail) 259 | 260 | size = render.count("\n") + 1 261 | 262 | b = remarker_block_begin 263 | e = remarker_block_end 264 | 265 | #if template.count("\n") > 0 266 | "#{indent}#{b}#{pad}:#{TAG}+#{size}:#{space}#{template}#{tail}\n#{render}\n" 267 | #else 268 | # "#{indent}#{b}#{pad}:#{TAG}+#{size}: #{template} #{e}\n#{render}\n" 269 | #end 270 | end 271 | 272 | end 273 | 274 | end 275 | 276 | --------------------------------------------------------------------------------

    Because Erbside uses Tilt, 30 | a number of filtering options are available. There are three types of filters: formatters, 31 | stencils and miscellaneous. Formatters handle layout and depend on the format of the 32 | given document. A good example of such a filter is html which converts the given format, 33 | eg. markdown, to html. A stencil filter, on the other hand, handles dynamic content, interpolating 34 | variable substituations. erb, liquid and mustache are all 35 | examples of supported stencils. Miscellaneous filters handle odd-and-end transforms, for instance 36 | a custom filter might be used to mask curse words.