serenity-odt 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,29 +1,22 @@
1
1
  Serenity is an embedded ruby for OpenOffice documents (.odt files). You provide an .odt template with ruby code inside a special markup and the data and Serenity generates the document. If you know erb all of this should sound familiar.
2
2
 
3
- Serenity is best demonstrated with a picture. The first picture shows the template with the ruby code, next image shows the generated document. The template, output and the sample script can be found in the showcase directory.
3
+ Important Changes
4
+ =================
4
5
 
5
- ![Serenity template](http://github.com/kremso/serenity/blob/master/showcase/imgs/serenity_template.png?raw=true)
6
-
7
- ![Generated document](http://github.com/kremso/serenity/blob/master/showcase/imgs/serenity_output.png?raw=true)
8
-
9
- Installation
10
- ============
6
+ As of version 0.2.0 serenity is using instance variables in the templates. In previous versions, your instance variables would be converted to local before passing to the template, so while in the code you had `@title = 'Serenity'`, you had to put `{%= title }` in the template to get serenity to work. This has now changed and you need to use instance variables in the templates: `{%= @title }`. Honestly, I don't know why I did it this way in the first place, considering that people are used to instance variables in templates from rails.
11
7
 
12
- gem install serenity-odt
8
+ Usage
9
+ ======
13
10
 
14
- Yeah, serenity is already taken on gemcutter.
11
+ Serenity is best demonstrated with an example. The first picture shows the template with the ruby code, next image shows the generated document. The template, output and the sample script can be found in the showcase directory.
15
12
 
16
- Creating templates
17
- ===================
13
+ ![Serenity template](http://github.com/kremso/serenity/blob/master/showcase/imgs/serenity_template.png?raw=true)
18
14
 
19
- Templates are created directly in OpenOffice. Ruby code is enclosed in special markup:
20
- * `{%= %}` is for ruby code which should be output to the final document. `to_s` is applied to anything found inside this markup
21
- * `{% %}` is for everything else — loops, ifs, ends and any other non-outputting code
15
+ The image above is a screenshot of showcase.odt from the [showcase](http://github.com/kremso/serenity/blob/master/showcase) directory. It's a regular OpenOffice document with ruby code embedded inside a special markup. That ruby code drives the document creation. You can use conditionals, loops, blocks — in fact, the whole ruby language and you can apply any OpenOffice formatting to the outputted variables or static text.
22
16
 
23
- Any special formatting should by applied directly on the markup. E.g. if you need to ouput the value of variable title in bold font, write `{%= title %}`, select in in OpenOffice and make it bold. See the showcase.odt for more examples.
17
+ The second line in the template is `{%= @title%}` what means: output the value of variable title. It's bold and big, in fact, it's has the 'Heading 1' style applied. That variable will be replaced in the generated document, but it will still be a 'Heading 1'.
24
18
 
25
- Generating documents
26
- ====================
19
+ You can now take that template, provide the data and generate the final document:
27
20
 
28
21
  require 'rubygems'
29
22
  require 'serenity'
@@ -51,10 +44,31 @@ Generating documents
51
44
  end
52
45
  end
53
46
 
54
- The key parts are `include Serenity::Generator` and render_odt. The data for the template must be provided as instance variables.
47
+ The key parts are `include Serenity::Generator` and `render_odt`. The data for the template must be provided as instance variables.
48
+
49
+ Following picture shows the generated document. It's a screenshot of the showcase_output.odt document from the [showcase](http://github.com/kremso/serenity/blob/master/showcase) directory.
50
+
51
+ ![Generated document](http://github.com/kremso/serenity/blob/master/showcase/imgs/serenity_output.png?raw=true)
52
+
53
+ Installation
54
+ ============
55
+
56
+ gem install serenity-odt
57
+
58
+ Yeah, serenity is already taken on gemcutter.
59
+
60
+ Creating templates
61
+ ===================
62
+
63
+ Templates are created directly in OpenOffice. Ruby code is enclosed in special markup:
64
+
65
+ + `{%= %}` is for ruby code which should be output to the final document. `to_s` is applied to anything found inside this markup
66
+ + `{% %}` is for everything else — loops, ifs, ends and any other non-outputting code
67
+
68
+ Any special formatting should by applied directly on the markup. E.g. if you need to ouput the value of variable title in bold font, write `{%= title %}`, select in in OpenOffice and make it bold. See the showcase.odt for more examples.
55
69
 
56
70
  Contact
57
71
  =======
58
72
 
59
- kramar[dot]tomas[at]gmail.com — I love the attention
73
+ kramar[dot]tomas[at]gmail.com
60
74
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ Spec::Rake::SpecTask.new("spec")
8
8
 
9
9
  spec = Gem::Specification.new do |s|
10
10
  s.name = %q{serenity-odt}
11
- s.version = "0.1.1"
11
+ s.version = "0.2.0"
12
12
 
13
13
  s.authors = ["Tomas Kramar"]
14
14
  s.description = <<-EOF
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,7 +1,6 @@
1
1
  class String
2
2
  def escape_xml
3
3
  mgsub!([[/&/, '&amp;'], [/</, '&lt;'], [/>/, '&gt;']])
4
- self
5
4
  end
6
5
 
7
6
  def mgsub!(key_value_pairs=[].freeze)
@@ -1,23 +1,12 @@
1
1
  module Serenity
2
2
  module Generator
3
3
  def render_odt template_path, output_path = output_name(template_path)
4
-
5
- local_variables = {}
6
- instance_variables.each { |name| local_variables[name] = instance_variable_get(name) }
7
-
8
- locals = instance_variables.map { |name| "#{ival_name_to_local(name)} = local_variables['#{name}'];" }.join
9
- eval locals
10
-
11
4
  template = Template.new template_path, output_path
12
5
  template.process binding
13
6
  end
14
7
 
15
8
  private
16
9
 
17
- def ival_name_to_local ival_name
18
- ival_name[1, ival_name.length]
19
- end
20
-
21
10
  def output_name input
22
11
  if input =~ /(.+)\.odt\Z/
23
12
  "#{$1}_output.odt"
@@ -22,6 +22,10 @@ module Serenity
22
22
  StringLine.new txt
23
23
  end
24
24
 
25
+ def self.literal txt
26
+ LiteralLine.new txt
27
+ end
28
+
25
29
  end
26
30
 
27
31
  class TextLine < Line
@@ -49,5 +53,12 @@ module Serenity
49
53
  " _buf << (" << escape_code(@text) << ").to_s.escape_xml;"
50
54
  end
51
55
  end
56
+
57
+ class LiteralLine < CodeLine
58
+ def to_buf
59
+ " _buf << (" << escape_code(@text) << ").to_s;"
60
+ end
61
+ end
62
+
52
63
  end
53
64
 
@@ -2,7 +2,7 @@ module Serenity
2
2
  class OdtEruby
3
3
  include Debug
4
4
 
5
- EMBEDDED_PATTERN = /\{%(=+)?(.*?)-?%\}/m
5
+ EMBEDDED_PATTERN = /\{%([=%]+)?(.*?)-?%\}/m
6
6
 
7
7
  def initialize template
8
8
  @src = convert template
@@ -61,10 +61,12 @@ module Serenity
61
61
  pos = m.end(0)
62
62
  src << Line.text(middle) unless middle.empty?
63
63
 
64
- if !indicator # <% %>
64
+ if !indicator # <% %>
65
65
  src << Line.code(code)
66
- else # <%= %>
66
+ elsif indicator == '=' # <%= %>
67
67
  src << Line.string(code)
68
+ elsif indicator == '%' # <%% %>
69
+ src << Line.literal(code)
68
70
  end
69
71
  end
70
72
 
@@ -11,16 +11,19 @@ module Serenity
11
11
  end
12
12
 
13
13
  def process context
14
+ tmpfiles = []
14
15
  Zip::ZipFile.open(@template) do |zipfile|
15
- content = zipfile.read('content.xml')
16
- odteruby = OdtEruby.new(XmlReader.new(content))
17
- out = odteruby.evaluate context
16
+ %w(content.xml styles.xml).each do |xml_file|
17
+ content = zipfile.read(xml_file)
18
+ odteruby = OdtEruby.new(XmlReader.new(content))
19
+ out = odteruby.evaluate(context)
18
20
 
19
- file = Tempfile.new("serenity")
20
- file << out
21
- file.close
21
+ tmpfiles << (file = Tempfile.new("serenity"))
22
+ file << out
23
+ file.close
22
24
 
23
- zipfile.replace('content.xml', file.path)
25
+ zipfile.replace(xml_file, file.path)
26
+ end
24
27
  end
25
28
  end
26
29
  end
@@ -8,7 +8,7 @@ module Serenity
8
8
 
9
9
  it 'should make context from instance variables and run the provided template' do
10
10
  class GeneratorClient
11
- include Generator
11
+ include Serenity::Generator
12
12
 
13
13
  def generate_odt
14
14
  @crew = ['Mal', 'Inara', 'Wash', 'Zoe']
@@ -13,7 +13,7 @@ module Serenity
13
13
  end
14
14
 
15
15
  def squeeze text
16
- text.inject('') { |memo, line| memo += line.strip } unless text.nil?
16
+ text.each_char.inject('') { |memo, line| memo += line.strip } unless text.nil?
17
17
  end
18
18
 
19
19
  def run_spec template, expected, context=@context
@@ -0,0 +1,20 @@
1
+ require "zip/zip"
2
+
3
+ module Serenity
4
+ Spec::Matchers.define :contain_in do |xml_file, expected|
5
+
6
+ match do |actual|
7
+ content = Zip::ZipFile.open(actual) { |zip_file| zip_file.read(xml_file) }
8
+ content =~ Regexp.new(".*#{Regexp.escape(expected)}.*")
9
+ end
10
+
11
+ failure_message_for_should do |actual|
12
+ "expected #{actual} to contain the text #{expected}"
13
+ end
14
+
15
+ failure_message_for_should_not do |actual|
16
+ "expected #{actual} to not contain the text #{expected}"
17
+ end
18
+
19
+ end
20
+ end
@@ -10,39 +10,47 @@ module Serenity
10
10
  end
11
11
 
12
12
  it "should process a document with simple variable substitution" do
13
- name = 'Malcolm Reynolds'
14
- title = 'captain'
13
+ @name = 'Malcolm Reynolds'
14
+ @title = 'captain'
15
15
 
16
16
  template = Template.new(fixture('variables.odt'), 'output_variables.odt')
17
17
  lambda {template.process binding}.should_not raise_error
18
18
  end
19
19
 
20
20
  it "should unroll a simple for loop" do
21
- crew = %w{'River', 'Jayne', 'Wash'}
21
+ @crew = %w{'River', 'Jayne', 'Wash'}
22
22
 
23
23
  template = Template.new(fixture('loop.odt'), 'output_loop.odt')
24
24
  lambda {template.process binding}.should_not raise_error
25
25
  end
26
26
 
27
27
  it "should unroll an advanced loop with tables" do
28
- ships = [Ship.new('Firefly', 'transport'), Ship.new('Colonial', 'battle')]
28
+ @ships = [Ship.new('Firefly', 'transport'), Ship.new('Colonial', 'battle')]
29
29
 
30
30
  template = Template.new(fixture('loop_table.odt'), 'output_loop_table.odt')
31
31
  lambda {template.process binding}.should_not raise_error
32
32
  end
33
33
 
34
34
  it "should process an advanced document" do
35
- persons = [Person.new('Malcolm', 'captain'), Person.new('River', 'psychic'), Person.new('Jay', 'gunslinger')]
35
+ @persons = [Person.new('Malcolm', 'captain'), Person.new('River', 'psychic'), Person.new('Jay', 'gunslinger')]
36
36
 
37
37
  template = Template.new(fixture('advanced.odt'), 'output_advanced.odt')
38
38
  lambda {template.process binding}.should_not raise_error
39
39
  end
40
40
 
41
41
  it "should loop and generate table rows" do
42
- ships = [Ship.new('Firefly', 'transport'), Ship.new('Colonial', 'battle')]
42
+ @ships = [Ship.new('Firefly', 'transport'), Ship.new('Colonial', 'battle')]
43
43
 
44
44
  template = Template.new(fixture('table_rows.odt'), 'output_table_rows.odt')
45
45
  lambda {template.process binding}.should_not raise_error
46
46
  end
47
+
48
+ it "should parse the header" do
49
+ @title = 'captain'
50
+
51
+ template = Template.new(fixture('header.odt'), 'output_header.odt')
52
+ template.process(binding)
53
+ 'output_header.odt'.should contain_in('styles.xml', 'captain')
54
+ end
47
55
  end
48
56
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serenity-odt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Tomas Kramar
@@ -9,29 +15,41 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-20 00:00:00 +01:00
18
+ date: 2010-09-23 00:00:00 +02:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rubyzip
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 57
30
+ segments:
31
+ - 0
32
+ - 9
33
+ - 1
23
34
  version: 0.9.1
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: rspec
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 13
46
+ segments:
47
+ - 1
48
+ - 2
49
+ - 9
33
50
  version: 1.2.9
34
- version:
51
+ type: :development
52
+ version_requirements: *id002
35
53
  description: " Embedded ruby for OpenOffice Text Document (.odt) files. You provide an .odt template\n with ruby code in a special markup and the data, and Serenity generates the document.\n Very similar to .erb files.\n"
36
54
  email: kramar.tomas@gmail.com
37
55
  executables: []
@@ -53,6 +71,20 @@ files:
53
71
  - README.md
54
72
  - Rakefile
55
73
  - LICENSE
74
+ - spec/escape_xml_spec.rb
75
+ - spec/generator_spec.rb
76
+ - spec/odteruby_spec.rb
77
+ - spec/spec_helper.rb
78
+ - spec/support/matchers/be_a_document.rb
79
+ - spec/support/matchers/contain_in.rb
80
+ - spec/template_spec.rb
81
+ - spec/xml_reader_spec.rb
82
+ - fixtures/advanced.odt
83
+ - fixtures/header.odt
84
+ - fixtures/loop.odt
85
+ - fixtures/loop_table.odt
86
+ - fixtures/table_rows.odt
87
+ - fixtures/variables.odt
56
88
  has_rdoc: true
57
89
  homepage:
58
90
  licenses: []
@@ -63,21 +95,27 @@ rdoc_options: []
63
95
  require_paths:
64
96
  - lib
65
97
  required_ruby_version: !ruby/object:Gem::Requirement
98
+ none: false
66
99
  requirements:
67
100
  - - ">="
68
101
  - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
69
105
  version: "0"
70
- version:
71
106
  required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
72
108
  requirements:
73
109
  - - ">="
74
110
  - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
75
114
  version: "0"
76
- version:
77
115
  requirements: []
78
116
 
79
117
  rubyforge_project:
80
- rubygems_version: 1.3.5
118
+ rubygems_version: 1.3.7
81
119
  signing_key:
82
120
  specification_version: 3
83
121
  summary: Embedded ruby for OpenOffice Text Document (.odt) files
@@ -87,9 +125,11 @@ test_files:
87
125
  - spec/odteruby_spec.rb
88
126
  - spec/spec_helper.rb
89
127
  - spec/support/matchers/be_a_document.rb
128
+ - spec/support/matchers/contain_in.rb
90
129
  - spec/template_spec.rb
91
130
  - spec/xml_reader_spec.rb
92
131
  - fixtures/advanced.odt
132
+ - fixtures/header.odt
93
133
  - fixtures/loop.odt
94
134
  - fixtures/loop_table.odt
95
135
  - fixtures/table_rows.odt