jarrett-quarto 0.3.0 → 0.3.1

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/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = 'quarto'
5
+ gemspec.summary = 'generates HTML or any other format from XML'
6
+ gemspec.email = 'jarrett@uchicago.edu'
7
+ gemspec.homepage = 'http://github.com/jarrett/quarto'
8
+ gemspec.description = 'Quarto is a Ruby framework for generating collections of documents from XML. It steps in where XSLT just won\'t cut it. ' +
9
+ 'Potential applications include web sites and e-books. It\'s built on top of ERB and REXML.'
10
+ gemspec.authors = ['Jarrett Colby']
11
+ gemspec.files = FileList['[A-Z]*', '{bin,lib,test}/**/*']
12
+ gemspec.executables = 'quarto'
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.1
@@ -0,0 +1,152 @@
1
+ module Quarto
2
+ # ElementWrapper subclasses can define parent and child elements, resulting
3
+ # in handy accessor methods. For example:
4
+ #
5
+ # class Company < ElementWrapper
6
+ # children :employees
7
+ # end
8
+ #
9
+ # class Employee < ElementWrapper
10
+ # parent :company
11
+ # element_attr 'name'
12
+ # end
13
+ #
14
+ # # in generate.rb:
15
+ # company = Company.find :first
16
+ # company.employees.each do |employee|
17
+ # puts employee.name
18
+ # end
19
+
20
+ module ElementWrapperChildren
21
+ def self.included(base) # :nodoc:
22
+ base.extend(ClassMethods)
23
+ base.class_eval do
24
+ alias_method :method_missing_without_children, :method_missing
25
+ alias_method :method_missing, :method_missing_with_children
26
+
27
+ alias_method :respond_to_without_children?, :respond_to?
28
+ alias_method :respond_to?, :respond_to_with_children?
29
+ end
30
+ end
31
+
32
+ def method_missing_with_children(meth, *args) # :nodoc:
33
+ if self.class.has_children_named?(meth)
34
+ children_proxy(meth)
35
+ elsif self.class.has_parent_named?(meth)
36
+ wrapped_parent
37
+ else
38
+ method_missing_without_children(meth, *args)
39
+ end
40
+ end
41
+
42
+ def respond_to_with_children?(meth, include_private = false) # :nodoc:
43
+ if self.class.has_children_named?(meth) or self.class.has_parent_named?(meth)
44
+ true
45
+ else
46
+ respond_to_without_children?(meth, include_private)
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ def children_proxy(collection_el_name) # :nodoc:
53
+ @children_proxies ||= {}
54
+ @children_proxies[collection_el_name.to_s] ||= Children.new(self, collection_el_name.to_s.singularize)
55
+ end
56
+
57
+ def wrapped_parent # :nodoc:
58
+ parent_el_name = self.class.read_inheritable_attribute(:parent)
59
+ parent_class_name = parent_el_name.classify
60
+ Kernel.const_get(parent_class_name).new(@element.parent.parent) # Go up two levels, since each child is expected to be inside a collection element
61
+ end
62
+
63
+ module ClassMethods # :nodoc:
64
+ # :singleton-method:
65
+ # Define children. +el_name+ must be the singular form. In the XML, all children must be
66
+ # wrapped in a collection element whose name is the plural form.
67
+ #
68
+ # Example:
69
+ #
70
+ # <company>
71
+ # <employees>
72
+ # <employee>
73
+ # </employee>
74
+ # </employees>
75
+ # </company>
76
+ #
77
+ # class Company < ElementWrapper
78
+ # children :employees
79
+ # end
80
+ def children(el_name)
81
+ write_inheritable_array(:children, [el_name.to_s])
82
+ end
83
+
84
+ def has_children_named?(collection_el_name) # :nodoc:
85
+ return false if read_inheritable_attribute(:children).nil?
86
+ read_inheritable_attribute(:children).include?(collection_el_name.to_s)
87
+ end
88
+
89
+ def has_parent_named?(parent_el_name) # :nodoc:
90
+ read_inheritable_attribute(:parent) == parent_el_name.to_s
91
+ end
92
+
93
+ # :singleton-method:
94
+ # Defines the element's parent. Example:
95
+ # Example:
96
+ #
97
+ # <company>
98
+ # <employees>
99
+ # <employee>
100
+ # </employee>
101
+ # </employees>
102
+ # </company>
103
+ #
104
+ # class Employee < ElementWrapper
105
+ # parent :company
106
+ # end
107
+ def parent(el_name)
108
+ write_inheritable_attribute(:parent, el_name.to_s)
109
+ end
110
+ end
111
+ end
112
+
113
+ class Children
114
+ include Enumerable
115
+
116
+ # Returns the REXML::Element for the children collection.
117
+ attr_reader :collection_element
118
+
119
+ # Iterate over all children.
120
+ def each
121
+ to_a.each { |child| yield child }
122
+ end
123
+
124
+ # Returns true if there are no children.
125
+ def empty?
126
+ to_a.empty?
127
+ end
128
+
129
+ def initialize(wrapped_parent, el_name, options = {}) # :nodoc:
130
+ @wrapped_parent = wrapped_parent
131
+ @el_name = el_name.to_s
132
+ @collection_element = @wrapped_parent.element.elements[options[:collection_el_name] || @el_name.pluralize]
133
+ @wrapper_class = options[:wrapper_class] || Kernel.const_get(@el_name.classify)
134
+ end
135
+
136
+ # Returns the number of children.
137
+ def length
138
+ to_a.length
139
+ end
140
+
141
+ # Returns an array of all children. Each is an instance of ElementWrapper. If +xpath+ is provided, the results will be filtered. +xpath+ is relative to the parent element
142
+ def to_a(xpath = nil)
143
+ @all ||= @collection_element.elements.to_a(xpath || @el_name).collect do |el|
144
+ @wrapper_class.new(el)
145
+ end
146
+ end
147
+
148
+ alias_method :size, :length
149
+ end
150
+ end
151
+
152
+ Quarto::ElementWrapper.send(:include, Quarto::ElementWrapperChildren)
@@ -0,0 +1,10 @@
1
+ module Quarto
2
+ @config = {}
3
+
4
+ def self.config(configs_to_merge = nil) # :nodoc:
5
+ if configs_to_merge.is_a?(Hash)
6
+ @config.merge!(configs_to_merge)
7
+ end
8
+ @config
9
+ end
10
+ end
@@ -0,0 +1,156 @@
1
+ module Quarto
2
+ # Abstract base class for your models. Put your ElementWrapper subclasses inside the "models"
3
+ # directory within your project. All files in that directory will be automatically required.
4
+ #
5
+ # Each ElementWrapper subclass corresponds to exactly one XML element.
6
+ # You can specify the model's element name by calling element_name=, but
7
+ # generally, you just let ElementWrapper use the default, which is the subclass
8
+ # name in snake_case.
9
+ #
10
+ # Instance attributes corresponding to the XML attributes
11
+ #
12
+ # For example, suppose you have an XML document like this:
13
+ #
14
+ # <programmers>
15
+ # <programmer skill="genius">
16
+ # <name>Linus Torvalds</name>
17
+ # <programmer>
18
+ # </programmers>
19
+ #
20
+ # You could then subclass ElementWrapper like this:
21
+ #
22
+ # class Programmer < ElementWrapper
23
+ # element_name = 'programmer'
24
+ # element_attrs 'name'
25
+ # end
26
+ #
27
+ # You could then do something like this in your generate.rb file:
28
+ #
29
+ # programmer = Programmer.find :first
30
+ # puts programmer.name
31
+ # puts programmer.skill
32
+ #
33
+ # Also see the documentation for Quarto::Children
34
+
35
+ class ElementWrapper
36
+ include InheritableAttributes
37
+
38
+ # Returns true if both instances come from the same node in the source XML document.
39
+ def ==(other_wrapped_element)
40
+ other_wrapped_element.is_a?(Quarto::ElementWrapper) and @element == other_wrapped_element.element
41
+ end
42
+
43
+ # Returns the currently-loaded REXML::Document.
44
+ def self.xml_doc
45
+ Quarto.xml_doc
46
+ end
47
+
48
+ # Returns the REXML::Element from which the instance was created.
49
+ attr_reader :element
50
+
51
+ # Creates read-only attributes from the given strings. When a model is instantiated from an XML node,
52
+ # ElementWrapper will try to populate these attributes using the node's child elements.
53
+ #
54
+ # For example, if your "employee" element has a child element called "name," you can use:
55
+ #
56
+ # element_attrs 'name'
57
+ #
58
+ # ...which will then expose a #name method for every instance of your class. Also see the usage example in the class description.
59
+ #
60
+ # Remember, XML attributes will automatically have corresponding ElementWrapper attributes. You only need to tell
61
+ # ElementWrapper which child elements to use.
62
+ def self.element_attrs(*element_names)
63
+ write_inheritable_array :element_attrs, element_names.collect { |en| en.to_sym}
64
+ end
65
+
66
+ # Returns the XML element name.
67
+ def self.element_name
68
+ @element_name
69
+ end
70
+
71
+ # Overrides the XML element name. The default is the class name in snake_case.
72
+ def self.element_name=(el_name)
73
+ @element_name = el_name
74
+ end
75
+
76
+ # Searches the XML document and returns instances of the class. The first parameter must be either :first, :last, or :all.
77
+ # If it's :first or :last, the method returns a single instance or nil. If it's :all, the method returns an array (which may be empty).
78
+ #
79
+ # Options:
80
+ #
81
+ # * <tt>:xpath</tt> - An XPath expression to limit the search. If this option is not given, the default XPath is "//element_name"
82
+ def self.find(quantifier, options = {})
83
+ raise ArgumentError, "Quantifier must be :all, :first, or :last, but got #{quantifier.inspect}" unless [:all, :first, :last].include?(quantifier)
84
+ raise ArgumentError, "Options must be a Hash, but got #{options.inspect}" unless options.is_a?(Hash)
85
+ if options.has_key?(:xpath)
86
+ xpath = options[:xpath]
87
+ else
88
+ xpath = "//#{@element_name}"
89
+ # TODO: add support for :root and :conditions (XPath predicates)
90
+ end
91
+ all = xml_doc.elements.to_a(xpath).collect do |el|
92
+ new(el)
93
+ end
94
+ case quantifier
95
+ when :all
96
+ all
97
+ when :first
98
+ all.first
99
+ when :last
100
+ all.last
101
+ end
102
+ end
103
+
104
+ def self.inherited(subclass) # :nodoc:
105
+ subclass.element_name = subclass.to_s.underscore
106
+ end
107
+
108
+ def initialize(el) # :nodoc:
109
+ unless el.is_a?(REXML::Element)
110
+ raise ArgumentError, "Quarto::ElementWrapper.new must be passed a REXML::Element, but got #{el.inspect}"
111
+ end
112
+ @element = el
113
+ @attributes = {}
114
+ @element.attributes.each do |a_name, value|
115
+ @attributes[a_name.to_sym] = typecast_text(value)
116
+ end
117
+ self.class.read_inheritable_attribute(:element_attrs).each do |el_name|
118
+ raise ArgumentError, "Expected <#{@element.name}> to contain <#{el_name}>" if @element.elements[el_name.to_s].nil?
119
+ @attributes[el_name.to_sym] = typecast_text(@element.elements[el_name.to_s].text)
120
+ end
121
+ end
122
+
123
+ def method_missing(meth, *args, &block) # :nodoc:
124
+ if @attributes.has_key?(meth.to_sym)
125
+ @attributes[meth.to_sym]
126
+ elsif @element.respond_to?(meth)
127
+ @element.send(meth, *args, &block)
128
+ else
129
+ super
130
+ end
131
+ end
132
+
133
+ def respond_to?(meth, include_private = false) # :nodoc:
134
+ if @element.respond_to?(meth, include_private) or @attributes.has_key?(meth.to_sym)
135
+ true
136
+ else
137
+ super
138
+ end
139
+ end
140
+
141
+ protected
142
+
143
+ # When an ElementWrapper is instantiated from an XML node, all values start out as strings. This method typecasts those values.
144
+ def typecast_text(t)
145
+ if t.nil? or (t.is_a?(String) and t.empty?)
146
+ nil
147
+ elsif t =~ /^-?[0-9]+$/
148
+ t.to_i
149
+ elsif t =~ /^-?[0-9]*\.[0-9]+$/
150
+ t.to_f
151
+ else
152
+ t
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,160 @@
1
+ module Quarto
2
+ # Generates the project according to the directives in the block.
3
+ # A block must be supplied. The block will be evaluated within the context of
4
+ # a Quarto::Generator object.
5
+ #
6
+ # If the optional +project_path+ is given, the directives in the block willl
7
+ # be process for the project residing +project_path+. Otherwise, the current
8
+ # working directory will be used.
9
+ #
10
+ # This method is typically called from <tt>generate.rb</tt>. There's probably
11
+ # no reason for you to call it from any other context.
12
+ def self.generate(project_path = nil, &block)
13
+ unless block_given?
14
+ raise ArgumentError, 'Quarto.generate must be given a block'
15
+ end
16
+ # caller[0] returns the trace for the context that called generate. So, if generate.rb is invoked directly, Quarto will still work.
17
+ trace = caller()
18
+ unless trace.empty?
19
+ calling_file = trace[0].split(':')[-2]
20
+ if File.basename(calling_file) == 'generate.rb'
21
+ project_path = project_path || File.expand_path(File.dirname(calling_file))
22
+ end
23
+ end
24
+ unless project_path.is_a?(String) and !project_path.empty?
25
+ raise ArgumentError, 'project_path is required when Quarto.generate is called from any file other than generate.rb'
26
+ end
27
+ Dir.glob(project_path + '/models/*.rb').each do |model_file|
28
+ require model_file
29
+ end
30
+ generator = Quarto::Generator.new(project_path)
31
+ generator.generate(&block)
32
+ generator
33
+ end
34
+
35
+ # Generates the project at the specified path using its generate.rb.
36
+ def self.generate_from_project_path(project_path)
37
+ raise ArgumentError, "Expected string, but got #{project_path.inspect}" unless project_path.is_a?(String) and !project_path.empty?
38
+ load(project_path + '/generate.rb')
39
+ end
40
+
41
+ # This class responds to all the directives that are available for use within
42
+ # a generate.rb file.
43
+ class Generator
44
+ include UrlHelper
45
+
46
+ # Sets the name of the default layout file in the layouts directory. If
47
+ # default_layout isn't specified, the default layout is the first file matching <tt>default.*</tt>.
48
+ attr_accessor :default_layout
49
+
50
+ # Generate the project according to the directives given in the block.
51
+ def generate(&block)
52
+ raise ArgumentError, 'generate must be called with a block' unless block_given?
53
+ if !File.exists? @output_path
54
+ Dir.mkdir @output_path
55
+ end
56
+ instance_eval(&block)
57
+ end
58
+
59
+ def generate_file_path # :nodoc:
60
+ @project_path + '/generate.rb'
61
+ end
62
+
63
+ # Options:
64
+ # * <tt>:console_output</tt> - Boolean. If true, the generator will print what it's currently doing.
65
+ # * <tt>:console</tt> - By default, console messages will be printed to stdout. You can override this
66
+ # by passing in an object that responds to <tt>puts</tt>.
67
+ def initialize(project_path, options = {})
68
+ raise ArgumentError, "Expected string, but got #{project_path.inspect}" unless project_path.is_a?(String) and !project_path.empty?
69
+ raise ArgumentError, "Project path #{project_path} doesn't exist" unless File.exists?(project_path)
70
+ @project_path = project_path
71
+ @output_path = project_path + '/output'
72
+ @options = {:console_output => true, :console => Kernel}.merge(options)
73
+ @console = @options[:console]
74
+ end
75
+
76
+ attr_reader :output_path # :nodoc:
77
+
78
+ protected
79
+
80
+ # Set a configuration for Quarto to use during generation, e.g. <tt>:site_root</tt>
81
+ def config(key, value)
82
+ Quarto.config[key] = value
83
+ end
84
+
85
+ # Render the given +template+, and save the output in +filename+ under +directory+.
86
+ # +locals+ is a hash where they keys are the names of local variables in the template
87
+ #
88
+ # Options:
89
+ # * <tt>:layout</tt> - Render inside the specified layout. Must be the name of
90
+ # a file in the layouts directory, e.g. <tt>my_layout.html.erb</tt>. If not given,
91
+ # the <tt>default_layout</tt> will be used.
92
+ #
93
+ # Example:
94
+ # employees.each do |employee|
95
+ # render 'employee.html.erb', 'employees', urlize(employee.name) + '.html', :employee => employee
96
+ # end
97
+ #
98
+ # That example will create a number of files with names like "John-Smith.html"
99
+ # in the "employees" directory
100
+ def render(template, directory, filename, locals, options = {})
101
+ if @options[:console_output]
102
+ if directory.is_a?(String) and !directory.empty?
103
+ @console.puts "Writing from template #{template} to output/#{directory}/#{filename}"
104
+ else
105
+ @console.puts "Writing from template #{template} to output/#{filename}"
106
+ end
107
+ end
108
+
109
+ if directory.nil? or directory.empty?
110
+ path = "#{@output_path}/#{filename}"
111
+ else
112
+ subdir = "#{@output_path}/#{directory}"
113
+ if !File.exists? subdir
114
+ Dir.mkdir subdir
115
+ end
116
+ path = "#{subdir}/#{filename}"
117
+ end
118
+
119
+ File.open(path, 'w') do |file|
120
+ file.print render_to_s(template, locals, options)
121
+ end
122
+ end
123
+
124
+ # Renders +template+ to a string. Sets local variables within the template to the values given
125
+ # in +locals+.
126
+ def render_to_s(template, locals, options = {})
127
+ page_template_path = "#{@project_path}/pages/#{template}"
128
+ page_template = ERB.new(File.read(page_template_path))
129
+ page_content = Rendering.render(page_template, locals)
130
+
131
+ if options.has_key?(:layout)
132
+ layout = options[:layout]
133
+ elsif (@default_layout and File.exists?("#{@project_path}/layouts/#{@default_layout}"))
134
+ layout = @default_layout
135
+ elsif @default_layout = Dir.glob("#{@project_path}/layouts/default.*.erb")[0]
136
+ @default_layout = File.basename(@default_layout)
137
+ layout = @default_layout
138
+ else
139
+ layout = nil
140
+ end
141
+
142
+ if layout
143
+ layout_template_path = "#{@project_path}/layouts/#{layout}"
144
+ layout_template = ERB.new(File.read(layout_template_path))
145
+ Rendering.render(layout_template, locals) do
146
+ page_content
147
+ end
148
+ else
149
+ page_content
150
+ end
151
+ end
152
+
153
+ # Specifies which XML file to use. Must be the name of a file in the xml directory, e.g. <tt>companies.xml</tt>.
154
+ # This method absolutely must be called within <tt>generate.rb</tt>. Otherwise, Quarto won't know what XML
155
+ # to use as its source.
156
+ def use_xml(xml_filename)
157
+ Quarto.xml_source = File.open("#{@project_path}/xml/#{xml_filename}")
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,31 @@
1
+ # Thanks to ActiveSupport for this stuff
2
+
3
+ module Quarto
4
+ module InheritableAttributes # :nodoc: all
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def read_inheritable_attribute(key)
11
+ @inheritable_attributes ||= {}
12
+ @inheritable_attributes[key]
13
+ end
14
+
15
+ def write_inheritable_array(key, elements)
16
+ write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
17
+ write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
18
+ end
19
+
20
+ def write_inheritable_attribute(key, value)
21
+ @inheritable_attributes ||= {}
22
+ @inheritable_attributes[key] = value
23
+ end
24
+
25
+ def write_inheritable_hash(key, hash)
26
+ write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
27
+ write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ module Quarto
2
+ PROJECT_SUBFOLDERS = [
3
+ 'layouts',
4
+ 'models',
5
+ 'output',
6
+ 'pages',
7
+ 'xml'
8
+ ]
9
+
10
+ STARTER_GENERATE_FILE = %q(
11
+ Quarto.generate do
12
+ # Your code here
13
+ # e.g.:
14
+ # render 'companies.html.erb', '', 'companies.html', :companies => Company.find(:all)
15
+ end
16
+ )
17
+ # Initialize a new Quarto project at the specified path. Creates a generate.rb file and the necessary subfolders.
18
+ def self.init_project(project_path)
19
+ raise ArgumentError, "Expected string, but got #{project_path.inspect}" unless project_path.is_a?(String) and !project_path.empty?
20
+ project_path = File.expand_path(project_path)
21
+ unless File.exists?(project_path)
22
+ Dir.mkdir project_path
23
+ end
24
+ PROJECT_SUBFOLDERS.each do |subfolder|
25
+ subfolder = project_path + '/' + subfolder
26
+ unless File.exists?(subfolder)
27
+ Dir.mkdir subfolder
28
+ end
29
+ end
30
+ generate_file = project_path + '/generate.rb'
31
+ unless File.exists?(generate_file)
32
+ File.open(generate_file, 'w') do |file|
33
+ file.print(STARTER_GENERATE_FILE)
34
+ end
35
+ end
36
+ true
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ module Quarto
2
+ class Rendering # :nodoc: all
3
+ include UrlHelper
4
+
5
+ def initialize(__erb_template, __locals)
6
+ __b = binding
7
+ __locals.each_key do |var_name|
8
+ # In the context of this method (rather than of this block),
9
+ # define the local variables
10
+ eval "#{var_name} = __locals[:#{var_name}]", __b
11
+ end
12
+
13
+ @result = __erb_template.result(__b)
14
+ end
15
+
16
+ def self.render(erb_template, locals, &block)
17
+ new(erb_template, locals, &block).result
18
+ end
19
+
20
+ attr_reader :result
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'cgi'
2
+
3
+ module Quarto
4
+ module UrlHelper
5
+ # Generates an absolute URL, using the <tt>:site_root</tt> config value. (To change <tt>:site_root</tt>,
6
+ # put something like this in <tt>generate.rb</tt>:
7
+ # config(:site_root, 'http://your_domain.com/whatever')
8
+ def abs_url(str)
9
+ "#{Quarto.config[:site_root]}#{str}"
10
+ end
11
+
12
+ # Replaces spaces with dashes and deletes special characters.
13
+ def urlize(str)
14
+ str.to_s.gsub(/[^ a-zA-Z0-9_-]/, '').tr(' ', '-')
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module Quarto
2
+ def self.xml_source=(source) # :nodoc:
3
+ raise ArgumentError, "Expected File but got #{source.inspect}" unless source.is_a?(File)
4
+ @xml_doc = REXML::Document.new(source)
5
+ end
6
+
7
+ def self.xml_doc # :nodoc:
8
+ @xml_doc
9
+ end
10
+ end
data/lib/quarto.rb ADDED
@@ -0,0 +1,16 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'rexml/document'
5
+ require 'erb'
6
+ require 'active_support/inflector'
7
+
8
+ require 'quarto/config'
9
+ require 'quarto/xml_doc'
10
+ require 'quarto/inheritable_attributes'
11
+ require 'quarto/url_helper'
12
+ require 'quarto/element_wrapper'
13
+ require 'quarto/children'
14
+ require 'quarto/rendering'
15
+ require 'quarto/generator'
16
+ require 'quarto/init_project'
data/quarto.gemspec ADDED
@@ -0,0 +1,62 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{quarto}
5
+ s.version = "0.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jarrett Colby"]
9
+ s.date = %q{2009-06-05}
10
+ s.default_executable = %q{quarto}
11
+ s.description = %q{Quarto is a Ruby framework for generating collections of documents from XML. It steps in where XSLT just won't cut it. Potential applications include web sites and e-books. It's built on top of ERB and REXML.}
12
+ s.email = %q{jarrett@uchicago.edu}
13
+ s.executables = ["quarto"]
14
+ s.extra_rdoc_files = [
15
+ "README"
16
+ ]
17
+ s.files = [
18
+ "README",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "bin/quarto",
22
+ "lib/quarto.rb",
23
+ "lib/quarto/children.rb",
24
+ "lib/quarto/config.rb",
25
+ "lib/quarto/element_wrapper.rb",
26
+ "lib/quarto/generator.rb",
27
+ "lib/quarto/inheritable_attributes.rb",
28
+ "lib/quarto/init_project.rb",
29
+ "lib/quarto/rendering.rb",
30
+ "lib/quarto/url_helper.rb",
31
+ "lib/quarto/xml_doc.rb",
32
+ "quarto.gemspec"
33
+ ]
34
+ s.has_rdoc = true
35
+ s.homepage = %q{http://github.com/jarrett/quarto}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.1}
39
+ s.summary = %q{generates HTML or any other format from XML}
40
+ s.test_files = [
41
+ "spec/children_spec.rb",
42
+ "spec/element_wrapper_spec.rb",
43
+ "spec/generator_spec.rb",
44
+ "spec/init_project_spec.rb",
45
+ "spec/matchers/file_matchers.rb",
46
+ "spec/sample_project/generate.rb",
47
+ "spec/sample_project/models/company.rb",
48
+ "spec/sample_project/models/employee.rb",
49
+ "spec/spec_helper.rb",
50
+ "spec/url_helper_spec.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 2
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ else
59
+ end
60
+ else
61
+ end
62
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jarrett-quarto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarrett Colby
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-04 00:00:00 -07:00
12
+ date: 2009-06-05 00:00:00 -07:00
13
13
  default_executable: quarto
14
14
  dependencies: []
15
15
 
@@ -23,6 +23,20 @@ extra_rdoc_files:
23
23
  - README
24
24
  files:
25
25
  - README
26
+ - Rakefile
27
+ - VERSION
28
+ - bin/quarto
29
+ - lib/quarto.rb
30
+ - lib/quarto/children.rb
31
+ - lib/quarto/config.rb
32
+ - lib/quarto/element_wrapper.rb
33
+ - lib/quarto/generator.rb
34
+ - lib/quarto/inheritable_attributes.rb
35
+ - lib/quarto/init_project.rb
36
+ - lib/quarto/rendering.rb
37
+ - lib/quarto/url_helper.rb
38
+ - lib/quarto/xml_doc.rb
39
+ - quarto.gemspec
26
40
  has_rdoc: true
27
41
  homepage: http://github.com/jarrett/quarto
28
42
  post_install_message: