neapolitan 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.ruby ADDED
@@ -0,0 +1,72 @@
1
+ ---
2
+ source:
3
+ - var
4
+ authors:
5
+ - name: trans
6
+ email: transfire@gmail.com
7
+ copyrights: []
8
+ replacements: []
9
+ alternatives: []
10
+ requirements:
11
+ - name: malt
12
+ version: 0.4.0+
13
+ - name: detroit
14
+ groups:
15
+ - build
16
+ development: true
17
+ - name: yard
18
+ groups:
19
+ - document
20
+ development: true
21
+ - name: qed
22
+ groups:
23
+ - test
24
+ development: true
25
+ - name: coderay
26
+ groups:
27
+ - optional
28
+ - test
29
+ development: true
30
+ - name: RedCloth
31
+ groups:
32
+ - optional
33
+ - test
34
+ development: true
35
+ - name: rdoc
36
+ groups:
37
+ - optional
38
+ - test
39
+ development: true
40
+ - name: liquid
41
+ groups:
42
+ - optional
43
+ - test
44
+ development: true
45
+ dependencies: []
46
+ conflicts: []
47
+ repositories:
48
+ - uri: git://github.com/rubyworks/neapolitan.git
49
+ scm: git
50
+ name: upstream
51
+ resources:
52
+ home: http://rubyworks.github.com/neapolitan
53
+ code: http://github.com/rubyworks/neapolitan
54
+ docs: http://rubydoc.info/gems/neapolitan/frames
55
+ wiki: http://wiki.github.com/rubyworks/neapolitan
56
+ extra: {}
57
+ load_path:
58
+ - lib
59
+ revision: 0
60
+ created: '2009-08-25'
61
+ summary: Kid in the Candy Store Templating
62
+ title: Neapolitan
63
+ version: 0.4.0
64
+ name: neapolitan
65
+ description: ! 'Neapolitan is a meta-templating engine. Like a candy store it allows
66
+ you to pick
67
+
68
+ and choose from a variety of rendering formats in the construction of a single
69
+
70
+ document. Selections include eruby, textile, markdown and many others.'
71
+ organization: rubyworks
72
+ date: '2011-11-30'
data/HISTORY.rdoc CHANGED
@@ -1,5 +1,21 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 0.4.0 / 2011-11-30
4
+
5
+ This release updates Neapolitan for use with the latest version
6
+ of Malt (v0.4.0). At the same, time the underlying API has been improved.
7
+ The API remains compatible with the previous version, with the exception
8
+ of one YAML front matter property --the `common` field has been renamed
9
+ to `finish`, to better indicate when it is applied during rendering.
10
+
11
+ Changes:
12
+
13
+ * Rename `common` metadata property to `finish`.
14
+ * Add #format block setter for applying complex format rules.
15
+ * Apply #select and #reject blocks during rendering instead of before.
16
+ * Update part rendering for compatibility with Malt 0.4+.
17
+
18
+
3
19
  == 0.3.0 / 2010-11-09
4
20
 
5
21
  This release entails a fairly major overhaul of the API. Primarily, the
@@ -25,7 +41,7 @@ Changes:
25
41
 
26
42
  == 0.1.0 / 2008-10-25
27
43
 
28
- Not an offical release. This is the first usable version of Chocolates.
44
+ Not an official release. This is the first usable version of Chocolates.
29
45
 
30
46
  Changes:
31
47
 
data/LICENSE.txt ADDED
@@ -0,0 +1,29 @@
1
+ Neapolitan - Multi-Format Templates
2
+
3
+ Copyright 2010 Rubyworks. All rights reserved.
4
+
5
+ BSD-2-Cluase License
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ (http://rubyworks.github.com/neapolitan)
29
+
data/README.rdoc CHANGED
@@ -1,9 +1,11 @@
1
1
  = Neapolitan
2
2
 
3
- Copyright (c) 2010 Thomas Sawyer
3
+ {Homepage}[http://rubyworks.github.com/neapolitan] |
4
+ {Development}[http://github.com/rubyworks/neapolitan] |
5
+ {Report Issue}[http://github.com/rubyworks/neapolitan/issues] |
6
+ {Mailing List}[http://groups.google.com/group/rubyworks-mailinglist]
4
7
 
5
- * home: http://rubyworks.github.com/neapolitan
6
- * code: http://github.com/rubyworks/neapolitan
8
+ {<img src="http://travis-ci.org/rubyworks/neapolitan.png" />}[http://travis-ci.org/rubyworks/neapolitan]
7
9
 
8
10
 
9
11
  == DESCRIPTION
@@ -13,7 +15,7 @@ world. Why be limited to just one? Neapolitan gives
13
15
  you a whole box to pick from.
14
16
 
15
17
 
16
- == FEATURES/ISSUES
18
+ == FEATURES
17
19
 
18
20
  * All the variety of a Whitman's Sampler.
19
21
  * And all the ease of a Hershey's K.I.S.S.
@@ -22,7 +24,7 @@ you a whole box to pick from.
22
24
 
23
25
  == SYNOPSIS
24
26
 
25
- For now please see the Neapolitan website and online documentation.
27
+ For now, please see the Neapolitan website and online documentation.
26
28
 
27
29
 
28
30
  == HOW TO INSTALL
@@ -35,11 +37,11 @@ If you're old fashion and want to install to a site
35
37
  location, see Setup.rb (http://protuils.github.com/setup).
36
38
 
37
39
 
38
- == COPYRIGHT/LICENSE
40
+ == COPYRIGHTS
39
41
 
40
- Neapolitan, Copyright (c) 2010 Thomas Sawyer
42
+ Neapolitan, Copyright (c) 2010 Rubyworks
41
43
 
42
- Neapolitan is distributed under the terms of the Apache License v2.0.
44
+ Neapolitan is distributed under the terms of the *BSD-2-Clause* license.
43
45
 
44
46
  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
45
47
  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
@@ -0,0 +1,86 @@
1
+ = Overview
2
+
3
+ == Example Neapolitan Document
4
+
5
+ Here is an example Neapolitan template, 'vanilla.np':
6
+
7
+ output: vanilla.html
8
+
9
+ --- erb rdoc
10
+
11
+ = Yummy Vanilla
12
+
13
+ Hi <%= name %>,
14
+
15
+ I know you want some of that yummy stuff.
16
+
17
+ --- coderay.ruby
18
+
19
+ %{v a n i l l a}.each do |letter|
20
+ puts "Give me a #{letter}!"
21
+ end
22
+
23
+ puts "What's that spell?"
24
+
25
+ --- liquid html
26
+
27
+ <quote>
28
+ {{ yield }}
29
+ </quote>
30
+
31
+ --- textile
32
+
33
+ | | 2009 | 2010 |
34
+ | Has Vanilla? | No | Yes! |
35
+
36
+ As you can see. It's all _fun_ and _games_ here.
37
+
38
+ == Loading the Library
39
+
40
+ Require the library.
41
+
42
+ require 'neapolitan'
43
+
44
+ == Reading a Neapolitan File
45
+
46
+ To load our example template, we can either pass a +File+ object to the
47
+ +Template+ initializer.
48
+
49
+ path = "vanilla.np"
50
+
51
+ template = Neapolitan::Template.new(File.new(path))
52
+
53
+ Or we can use the shortcut +file+ method.
54
+
55
+ template = Neapolitan.file(path)
56
+
57
+ == Rendering Data Sources
58
+
59
+ Neapolitan uses Malt on the backend. Malt supports a three separate ways to pass
60
+ data into a template.
61
+
62
+ The most obvious data source is a Hash.
63
+
64
+ data = {:name=>"Tom"}
65
+
66
+ text = template.render(data).to_s
67
+
68
+ text.assert =~ /Hi Tom/
69
+
70
+ Templates can also be rendered given a Binding.
71
+
72
+ name = "Huck"
73
+
74
+ text = template.render(binding).to_s
75
+
76
+ text.assert =~ /Hi Huck/
77
+
78
+ Lastly, they can be rendered with the scope of any other type of Object,
79
+ including an instance of a Struct.
80
+
81
+ scope = Struct.new(:name).new("Becky")
82
+
83
+ text = template.render(scope).to_s
84
+
85
+ text.assert =~ /Hi Becky/
86
+
data/demo/02_faq.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ = FAQ
2
+
3
+ <b>How do I limit the section formats that can be used?</b>
4
+
5
+ There are two methods that can be used to limit the formats that
6
+ of a Neapolitan template, namely, #select and #reject.
7
+
8
+ After creating a Template object, use the #select and/or the #reject
9
+ methods to filter out any unwanted formats.
10
+
11
+ template = Neapolitan.file('example.np')
12
+
13
+ template.reject{ |format| %w{liquid}.include?(format) }
14
+
15
+ template.render(:name=>"Tom")
16
+
17
+ These methods can be used for more aggressive validation by raising
18
+ an error.
19
+
20
+ template = Neapolitan.file('example.np')
21
+
22
+ template.reject do |format|
23
+ raise TypeError if %w{liquid}.include?(format)
24
+ false
25
+ end
26
+
27
+ expect TypeError do
28
+ template.render(:name=>"Tome")
29
+ end
30
+
31
+ <b>Why should template formats be listed before markup format?</b>
32
+
33
+ Consider what happens if have a document section proccessed by RDoc
34
+ before applying templating such as ERB:
35
+
36
+ = Example
37
+
38
+ Hi, <%= name %>
39
+
40
+ The result never ends up utilizing ERB properly because RDoc transformed
41
+ the document into:
42
+
43
+ <h1>Example</h1>
44
+
45
+ Hi, &lt;%= name &gt;
46
+
47
+ Therefore you should always list the template format before markup formats.
48
+ Of course usually template formats are not used on section by section
49
+ basis in anycase, so this won't be an issue, but it's good to know just
50
+ in case.
51
+
@@ -0,0 +1,12 @@
1
+ directory = File.dirname(__FILE__)
2
+
3
+ $LOAD_PATH << directory + '/../lib'
4
+
5
+ require 'neapolitan'
6
+
7
+ FileUtils.install(Dir[directory + '/../fixtures/*'], '.')
8
+
9
+ When "Here is an example Neapolitan template, '(((.*?)))'" do |file, text|
10
+ File.open(file, 'w'){ |f| f << text }
11
+ end
12
+
@@ -0,0 +1,39 @@
1
+ <h1>Yummy Choclate </h1>
2
+ <p>
3
+ Hi Ginger,
4
+ </p>
5
+ <p>
6
+ I know you want some of that yummy stuff.
7
+ </p>
8
+
9
+ <div class="CodeRay">
10
+ <div class="code"><pre>
11
+ <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">%{</span><span style="">c h o c o l a t e</span><span style="color:#710">}</span></span>.each <span style="color:#080;font-weight:bold">do</span> |letter|
12
+ puts <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">&quot;</span><span style="">Give me a </span><span style="background:#ddd;color:black"><span style="background:#ddd;font-weight:bold;color:#666">#{</span>letter<span style="background:#ddd;font-weight:bold;color:#666">}</span></span><span style="">!</span><span style="color:#710">&quot;</span></span>
13
+ <span style="color:#080;font-weight:bold">end</span>
14
+
15
+ puts <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">&quot;</span><span style="">What's that spell?</span><span style="color:#710">&quot;</span></span>
16
+
17
+ </pre></div>
18
+ </div>
19
+
20
+
21
+ <quote>
22
+ What can I say?
23
+
24
+ </quote>
25
+
26
+
27
+ <table>
28
+ <tr>
29
+ <td> </td>
30
+ <td> 2009 </td>
31
+ <td> 2010 </td>
32
+ </tr>
33
+ <tr>
34
+ <td> Has Choclates? </td>
35
+ <td> No </td>
36
+ <td> Yes! </td>
37
+ </tr>
38
+ </table>
39
+ <p>As you can see. It's all <em>fun</em> and <em>games</em> here.</p>
@@ -0,0 +1,31 @@
1
+ extension: html
2
+
3
+ --- erb rdoc
4
+
5
+ = Yummy Choclate
6
+
7
+ Hi <%= name %>,
8
+
9
+ I know you want some of that yummy stuff.
10
+
11
+ --- coderay.ruby
12
+
13
+ %{c h o c o l a t e}.each do |letter|
14
+ puts "Give me a #{letter}!"
15
+ end
16
+
17
+ puts "What's that spell?"
18
+
19
+ --- liquid html
20
+
21
+ <quote>
22
+ {{ yield }}
23
+ </quote>
24
+
25
+ --- textile
26
+
27
+ | | 2009 | 2010 |
28
+ | Has Choclates? | No | Yes! |
29
+
30
+ As you can see. It's all _fun_ and _games_ here.
31
+
@@ -0,0 +1,5 @@
1
+ ---
2
+ name: Ginger
3
+ yield: |
4
+ What can I say?
5
+
@@ -0,0 +1,66 @@
1
+ module Neapolitan
2
+
3
+ # Command line interface.
4
+ def self.cli(*argv)
5
+ options = {}
6
+
7
+ option_parser(options).parse!(argv)
8
+
9
+ if src = options[:source]
10
+ data = YAML.load(File.new(src))
11
+ else
12
+ data = {} #@source ||= YAML.load(STDIN.read)
13
+ end
14
+
15
+ files = argv
16
+
17
+ begin
18
+ files.each do |file|
19
+ template = Template.new(File.new(file))
20
+ if options[:output]
21
+ #template.save(data)
22
+ else
23
+ puts template.render(data)
24
+ end
25
+ end
26
+ rescue => e
27
+ $DEBUG ? raise(e) : puts(e.message)
28
+ end
29
+ end
30
+
31
+ # TODO: Save to output ?
32
+
33
+ #
34
+ def self.option_parser(options)
35
+ require 'optparse'
36
+
37
+ OptionParser.new do |opt|
38
+ opt.banner = "neapolitan [file1 file2 ...]"
39
+ #opt.on("--output", "-o [PATH]", "save output to specified directory") do |path|
40
+ # options[:output] = path
41
+ #end
42
+ opt.on("--source", "-s [FILE]", "data souce (YAML file)") do |file|
43
+ options[:source] = file
44
+ end
45
+ opt.on("--tilt", "use Tilt for rendering instead of Malt") do
46
+ options[:tilt] = true
47
+ end
48
+ opt.on("--trace", "show extra operational information") do
49
+ $TRACE = true
50
+ end
51
+ opt.on("--dryrun", "-n", "don't actually write to disk") do
52
+ $DRYRUN = true
53
+ end
54
+ opt.on("--debug", "run in debug mode") do
55
+ $DEBUG = true
56
+ $VERBOSE = true
57
+ end
58
+ opt.on_tail("--help", "display this help message") do
59
+ puts opt
60
+ exit
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,2 @@
1
+ require 'facets/hash/rekey'
2
+
@@ -0,0 +1,123 @@
1
+ module Neapolitan
2
+
3
+ # Controls rendering to a variety of back-end templating
4
+ # and markup systems via Malt.
5
+ #
6
+ class Factory
7
+ #
8
+ attr :types
9
+
10
+ # @param [Hash] options
11
+ #
12
+ # @option options [Array] :types
13
+ #
14
+ def initialize(options={})
15
+ @types = options[:types]
16
+ @system = options[:system] || :malt
17
+ end
18
+
19
+ #
20
+ def render(text, format, scope, locals, &content)
21
+ case format
22
+ when /^coderay/
23
+ coderay(text, format)
24
+ when /^syntax/
25
+ syntax(text, format)
26
+ when /^rubypants/
27
+ rubypants(text, format)
28
+ else
29
+ if @system == :tilt
30
+ render_via_tilt(text, format, scope, locals, &content)
31
+ else
32
+ render_via_malt(text, format, scope, locals, &content)
33
+ end
34
+ end
35
+ end
36
+
37
+ # Render via Malt.
38
+ def render_via_malt(text, format, scope, locals, &content)
39
+ doc = malt.text(text, :type=>format.to_sym)
40
+ doc.render(scope, locals, &content)
41
+ end
42
+
43
+ # Render via Tilt.
44
+ def render_via_tilt(text, format, scope, locals, &content)
45
+ if engine = Tilt[format]
46
+ #case data
47
+ #when Hash
48
+ # scope = Object.new
49
+ # table = data
50
+ #when Binding
51
+ # scope = data.eval('self')
52
+ # table = {}
53
+ #else # object scope
54
+ # scope = data
55
+ # table = {}
56
+ #end
57
+ engine.new{text}.render(scope, locals, &content)
58
+ else
59
+ text
60
+ end
61
+ end
62
+
63
+ # Get cached instance of Malt controller.
64
+ #
65
+ # @return [Malt::Machine] mutli-format renderer
66
+ def malt
67
+ @malt ||= (
68
+ if types && !types.empty?
69
+ Malt::Machine.new(:types=>types)
70
+ else
71
+ Malt::Machine.new
72
+ end
73
+ )
74
+ end
75
+
76
+ # Apply `coderay` syntax highlighting. This is a psuedo-format.
77
+ def coderay(input, format)
78
+ require 'coderay'
79
+ format = format.split('.')[1] || :ruby #:plaintext
80
+ tokens = CodeRay.scan(input, format.to_sym) #:ruby
81
+ tokens.div()
82
+ end
83
+
84
+ # Apply `syntax` syntax highlighting. This is a psuedo-format.
85
+ def syntax(input, format)
86
+ require 'syntax/convertors/html'
87
+ format = format.split('.')[1] || 'ruby' #:plaintext
88
+ lines = true
89
+ conv = Syntax::Convertors::HTML.for_syntax(format)
90
+ conv.convert(input,lines)
91
+ end
92
+
93
+ #
94
+ def rubypants(input_html, format)
95
+ require 'rubypants'
96
+ format, flag = format.split('.')
97
+ flag = (flag || 2).to_i
98
+ pants = RubyPants.new(input_html, flag)
99
+ pantts.to_html
100
+ end
101
+
102
+ #
103
+ #def render_stencil(stencil, text, attributes)
104
+ # case stencil
105
+ # when 'rhtml'
106
+ # erb(text, attributes)
107
+ # when 'liquid'
108
+ # liquid(text, attributes)
109
+ # else
110
+ # text
111
+ # end
112
+ #end
113
+
114
+ public
115
+
116
+ #
117
+ def self.render(text, format, data, &content)
118
+ new.render(text, format, data, &content)
119
+ end
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,89 @@
1
+ module Neapolitan
2
+
3
+ # A part is a section of a template. Templates can be segmented into
4
+ # parts using the '--- FORMAT' notation.
5
+ class Part
6
+
7
+ # Parse text body and create new part.
8
+ def self.parse(template, body)
9
+ index = body.index("\n")
10
+ format = body[0...index].strip
11
+ text = body[index+1..-1].strip
12
+
13
+ new(template, text, format)
14
+ end
15
+
16
+ # The template to which the part belongs.
17
+ attr :template
18
+
19
+ # Body of text as given in the part.
20
+ attr :text
21
+
22
+ # Setup new Part instance.
23
+ #
24
+ # @param [String] text
25
+ # The parts body.
26
+ #
27
+ # @param [Array] formats
28
+ # The template formats to apply to the body text.
29
+ #
30
+ def initialize(template, text, format)
31
+ @template = template
32
+ @text = text
33
+ @format = format
34
+ end
35
+
36
+ # Rendering format as given in the template document.
37
+ def format
38
+ @format
39
+ end
40
+
41
+ # Part specific format split into array.
42
+ def specific
43
+ @_specific ||= split_format(format)
44
+ end
45
+
46
+ # Template default format split into array.
47
+ def default
48
+ @_default ||= split_format(template.default)
49
+ end
50
+
51
+ # Template default format split into array.
52
+ def stencil
53
+ @_stencil ||= split_format(template.stencil)
54
+ end
55
+
56
+ # Template default format split into array.
57
+ def finish
58
+ @_finish ||= split_format(template.finish)
59
+ end
60
+
61
+ #
62
+ def formatting(&custom)
63
+ if custom
64
+ custom.call(self)
65
+ else
66
+ if specific.empty?
67
+ stencil + default + finish
68
+ else
69
+ stencil + specific + finish
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ #
77
+ def split_format(format)
78
+ case format
79
+ when nil
80
+ []
81
+ when Array
82
+ format
83
+ else
84
+ format.to_str.split(/\s+/)
85
+ end
86
+ end
87
+ end
88
+
89
+ end