neapolitan 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.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