eterps-publishing-grf 0.1.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Erik Terpstra
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = publishing-grf
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Erik Terpstra. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "publishing-grf"
8
+ gem.summary = %Q{TODO}
9
+ gem.email = "erik@ruby-lang.nl"
10
+ gem.homepage = "http://github.com/eterps/publishing-grf"
11
+ gem.authors = ["Erik Terpstra"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'spec/rake/spectask'
20
+ Spec::Rake::SpecTask.new(:spec) do |spec|
21
+ spec.libs << 'lib' << 'spec'
22
+ spec.spec_files = FileList['spec/**/*_spec.rb']
23
+ spec.spec_opts = ['-fs -c']
24
+ end
25
+
26
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.rcov = true
30
+ end
31
+
32
+
33
+ task :default => :spec
34
+
35
+ require 'rake/rdoctask'
36
+ Rake::RDocTask.new do |rdoc|
37
+ if File.exist?('VERSION.yml')
38
+ config = YAML.load(File.read('VERSION.yml'))
39
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
40
+ else
41
+ version = ""
42
+ end
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "publishing-grf #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
49
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,10 @@
1
+ $: << "#{File.dirname __FILE__}"
2
+
3
+ module Publishing
4
+ module GRF
5
+ def self.open(path); Publishing::GRF::Document.new(IO.read(path)) end
6
+ end
7
+ end
8
+
9
+ require 'grf/core'
10
+ require 'grf/reader'
@@ -0,0 +1,104 @@
1
+ require 'rubygems'
2
+ require 'facets/dictionary'
3
+
4
+ module Enumerable
5
+ def group_by(h = Hash)
6
+ r = h.new
7
+ each{|e| (r[yield(e)] ||= []) << e}
8
+ r
9
+ end
10
+ end
11
+
12
+ module Publishing
13
+ module GRF
14
+ module Node
15
+ def content; children.map{|n| n.content} end
16
+ end
17
+ end
18
+ end
19
+
20
+ class Publishing::GRF::Block
21
+ attr_reader :parent, :id, :parts, :fontsizes
22
+ attr_accessor :top, :right, :bottom, :left, :width, :height
23
+
24
+ def initialize(params = {})
25
+ @parent = params[:parent]
26
+ @id = params[:id]
27
+ @fontsizes = params[:fontsizes].to_s.split(/\s*,\s*/)
28
+ @parts = []
29
+ end
30
+
31
+ def top; @top or parts.min{|a, b| a.top <=> b.top }.top end
32
+ def left; @left or parts.min{|a, b| a.left <=> b.left}.left end
33
+ def bottom; @bottom or parts.max{|a, b| a.bottom <=> b.bottom}.bottom end
34
+ def right; @right or parts.max{|a, b| a.right <=> b.left}.right end
35
+ def width; @width or right - left end
36
+ def height; @height or bottom - top end
37
+
38
+ def fontsize; @fontsizes.first end
39
+ end
40
+
41
+ class Publishing::GRF::Element
42
+ attr_reader :parent, :id, :uri
43
+ attr_accessor :content
44
+
45
+ def initialize(params = {})
46
+ @parent = params[:parent]
47
+ @id = params[:id]
48
+ @uri = params[:uri]
49
+ end
50
+ end
51
+
52
+ class Publishing::GRF::Frame
53
+ include Publishing::GRF::Node
54
+
55
+ attr_reader :parent, :elements, :blocks, :number
56
+
57
+ def initialize(params = {})
58
+ @parent = params[:parent]
59
+ @number = params[:number]
60
+ @elements = []
61
+ @blocks = []
62
+ end
63
+
64
+ def images; @elements.select{|n| n.image?} end
65
+
66
+ alias :children :elements
67
+ end
68
+
69
+ class Publishing::GRF::Page
70
+ include Publishing::GRF::Node
71
+
72
+ attr_reader :frames, :id, :number, :section_name
73
+ attr_accessor :parent
74
+
75
+ def initialize(params = {})
76
+ @frames = []
77
+ @id = params[:id]
78
+ @number = params[:number]
79
+ @section_name = params[:section_name]
80
+ end
81
+
82
+ def elements; @frames.map{|n| n.elements}.flatten end
83
+
84
+ alias :children :frames
85
+ end
86
+
87
+ class Publishing::GRF::Document
88
+ include Publishing::GRF::Node
89
+
90
+ attr_reader :pages
91
+
92
+ def initialize(source = nil)
93
+ @pages = []
94
+ populate source if source
95
+ end
96
+
97
+ def elements; @pages.map{|n| n.elements}.flatten end
98
+
99
+ def sections
100
+ @pages.group_by(Dictionary){|n| n.section_name}
101
+ end
102
+
103
+ alias :children :pages
104
+ end
@@ -0,0 +1,75 @@
1
+ require 'cgi'
2
+ require 'rexml/document'
3
+ require 'rexml/streamlistener'
4
+
5
+ class Publishing::GRF::Reader
6
+ include REXML::StreamListener
7
+
8
+ attr_reader :pages
9
+
10
+ def initialize
11
+ @pages = []
12
+ end
13
+
14
+ def tag_start(name, attributes)
15
+ @in_element = false
16
+
17
+ if name == 'div'
18
+ if attributes['class'] == 'page'
19
+ @pages << Publishing::GRF::Page.new(
20
+ :id => attributes['data-page-id'],
21
+ :number => attributes['data-page-number'],
22
+ :section_name => CGI.unescapeHTML(attributes['data-section-name'])
23
+ )
24
+ elsif attributes['class'] == 'frame'
25
+ @pages.last.frames << Publishing::GRF::Frame.new(
26
+ :parent => @pages.last
27
+ )
28
+ elsif attributes['class'].split.include?('element')
29
+ @in_element = true
30
+ @pages.last.frames.last.elements << Publishing::GRF::Element.new(
31
+ :parent => @pages.last.frames.last,
32
+ :id => attributes['class'].sub(/\s*element\s*/, '')
33
+ )
34
+ elsif attributes['class'].split.include?('block')
35
+ @in_element = true
36
+ @pages.last.frames.last.blocks << Publishing::GRF::Block.new(
37
+ :parent => @pages.last.frames.last,
38
+ :id => attributes['class'].sub(/block\s*element\s*/, ''),
39
+ :fontsizes => attributes['data-fontsizes']
40
+ )
41
+ end
42
+ elsif name == 'img'
43
+ @pages.last.frames.last.elements << Publishing::GRF::Element.new(
44
+ :parent => @pages.last.frames.last,
45
+ :id => 'image',
46
+ :uri => attributes['src']
47
+ )
48
+ elsif %w[em b i span].include?(name)
49
+ @in_element = true
50
+ tag = attributes['class'] ? %{<#{name} class="#{attributes['class']}">} : "<#{name}>"
51
+ (@pages.last.frames.last.elements.last.content ||= '') << tag
52
+ end
53
+ end
54
+
55
+ def tag_end(name)
56
+ if %w[em b i span].include?(name)
57
+ @pages.last.frames.last.elements.last.content << "</#{name}>"
58
+ end
59
+ end
60
+
61
+ def text(str)
62
+ (@pages.last.frames.last.elements.last.content ||= '') << str.gsub("\n", ' ') if @in_element and str =~ /\S/
63
+ end
64
+ end
65
+
66
+ class Publishing::GRF::Document
67
+ private
68
+
69
+ def populate(source)
70
+ listener = Publishing::GRF::Reader.new
71
+ REXML::Parsers::StreamParser.new(source, listener).parse
72
+ @pages = listener.pages
73
+ @pages.each{|n| n.parent = self}
74
+ end
75
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{publishing-grf}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Erik Terpstra"]
9
+ s.date = %q{2009-06-16}
10
+ s.email = %q{erik@ruby-lang.nl}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/publishing/grf.rb",
23
+ "lib/publishing/grf/core.rb",
24
+ "lib/publishing/grf/reader.rb",
25
+ "publishing-grf.gemspec",
26
+ "spec/fixtures/sample.html",
27
+ "spec/publishing-grf_spec.rb",
28
+ "spec/spec_helper.rb"
29
+ ]
30
+ s.has_rdoc = true
31
+ s.homepage = %q{http://github.com/eterps/publishing-grf}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.1}
35
+ s.summary = %q{TODO}
36
+ s.test_files = [
37
+ "spec/spec_helper.rb",
38
+ "spec/publishing-grf_spec.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 2
44
+
45
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ else
47
+ end
48
+ else
49
+ end
50
+ end
@@ -0,0 +1,86 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <body>
4
+ <div class="page" data-page-number="1" data-page-id="1_1" data-section-name="Frontpage">
5
+ <div class="frame" data-reference="article1" data-source="nitf">
6
+ <div class="blocks">
7
+ <div data-x2="51.887" class="block element1" data-x="44.972" data-y="10.857" data-y2="13.972"/>
8
+ <div data-x2="49.105" class="block element2" data-x="44.972" data-y="16.759" data-y2="17.292"/>
9
+ <div data-x2="44.593" class="block element0" data-x="36.263" data-y="10.785" data-y2="17.195"/>
10
+ </div>
11
+ <div class="element hl1">This is headline 1.1</div>
12
+ <div class="element p">This is paragraph 1.1</div>
13
+ <div class="element bibliography">This is bibliography 1.1</div>
14
+ <img src="images/section1_page1_article1_1.jpg"/>
15
+ </div>
16
+ <div class="frame" data-reference="article2" data-source="nitf">
17
+ <div class="blocks">
18
+ <div data-x2="40.847" class="block element1" data-x="10.172" data-y="70.263" data-y2="72.458"/>
19
+ <div data-x2="25.639" class="block element3" data-x="10.172" data-y="73.562" data-y2="75.783"/>
20
+ <div data-x2="18.134" class="block element7" data-x="10.171" data-y="77.319" data-y2="81.602"/>
21
+ <div data-x2="26.861" class="block element2" data-x="18.871" data-y="77.316" data-y2="95.333"/>
22
+ <div data-x2="18.138" class="block element2" data-x="10.171" data-y="82.262" data-y2="96.432"/>
23
+ </div>
24
+ <div class="element hl1">This is headline 1.2</div>
25
+ <div class="element hl2">This is subheadline 1.2.1</div>
26
+ <div class="element hl2">This is subheadline 1.2.2</div>
27
+ <div class="element byline">By our correspondent <span class="person">Person 1.1</span></div>
28
+ <div class="element dateline">This is headline 1.2</div>
29
+ <div class="element p">This is paragraph 1.2.1</div>
30
+ <div class="element p">This is paragraph 1.2.2</div>
31
+ <div class="element p">This is paragraph 1.2.3</div>
32
+ <div class="element p">This is paragraph 1.2.4</div>
33
+ <div class="element p">This is paragraph 1.2.5</div>
34
+ <div class="element p">This is paragraph 1.2.6</div>
35
+ <div class="element p">This is paragraph 1.2.7</div>
36
+ <div class="element p">This is paragraph 1.2.8</div>
37
+ <div class="element media-caption">This is caption 1.2</div>
38
+ <div class="element bibliography">This is bibliography 1.2</div>
39
+ </div>
40
+ </div>
41
+ <div class="page" data-page-number="2" data-page-id="1_2" data-section-name="Page 2">
42
+ <div class="frame" data-reference="article3" data-source="nitf">
43
+ <div class="blocks">
44
+ <div data-x2="68.002" class="block element1" data-x="10.17" data-y="76.906" data-y2="78.88"/>
45
+ <div data-x2="17.92" class="block element7" data-x="10.171" data-y="80.128" data-y2="85.162"/>
46
+ <div data-x2="26.839" class="block element2" data-x="18.871" data-y="80.125" data-y2="96.494"/>
47
+ <div data-x2="35.539" class="block element2" data-x="27.572" data-y="80.125" data-y2="85.502"/>
48
+ <div data-x2="44.239" class="block element2" data-x="36.272" data-y="80.125" data-y2="96.494"/>
49
+ <div data-x2="18.138" class="block element2" data-x="10.171" data-y="86.171" data-y2="96.494"/>
50
+ <div data-x2="52.94" class="block element2" data-x="44.973" data-y="89.468" data-y2="96.494"/>
51
+ <div data-x2="61.64" class="block element2" data-x="53.672" data-y="89.468" data-y2="96.494"/>
52
+ <div data-x2="70.339" class="block element2" data-x="62.373" data-y="89.468" data-y2="94.845"/>
53
+ <div data-x2="35.539" class="block element2" data-x="27.572" data-y="92.766" data-y2="96.494"/>
54
+ <div data-x2="68.915" class="block element2" data-x="63.538" data-y="95.49" data-y2="96.517"/>
55
+ <div data-x2="52.626" class="block element8" data-x="44.973" data-y="87.27" data-y2="88.822"/>
56
+ <div data-x2="61.549" class="block element12" data-x="54.039" data-y="81.751" data-y2="86.625"/>
57
+ <div data-x2="69.154" class="block element12" data-x="62.373" data-y="81.751" data-y2="84.976"/>
58
+ <div data-x2="64.832" class="block element12" data-x="62.373" data-y="85.598" data-y2="86.075"/>
59
+ <div data-x2="61.253" class="block element12" data-x="54.039" data-y="87.247" data-y2="88.274"/>
60
+ <div data-x2="59.91" class="block element11" data-x="54.039" data-y="80.619" data-y2="81.3"/>
61
+ <div data-x2="52.924" class="block element0" data-x="44.961" data-y="80.078" data-y2="87.037"/>
62
+ <div data-x2="35.518" class="block element0" data-x="27.565" data-y="86.121" data-y2="91.87"/>
63
+ </div>
64
+ <div class="element hl1">This is headline 2.1</div>
65
+ <div class="element byline">By our editor <span class="person">Person 2.1</span></div>
66
+ <div class="element dateline">This is dateline 2.1</div>
67
+ <div class="element p">This is paragraph 2.1.1</div>
68
+ <div class="element p">This is paragraph 2.1.2</div>
69
+ <div class="element p">This is paragraph 2.1.3</div>
70
+ <div class="element p">This is paragraph 2.1.4</div>
71
+ <div class="element p">This is paragraph 2.1.5</div>
72
+ <div class="element p">This is paragraph 2.1.6</div>
73
+ <div class="element p">This is paragraph 2.1.7</div>
74
+ <div class="element p">This is paragraph 2.1.8</div>
75
+ <div class="element p">This is paragraph 2.1.9</div>
76
+ <div class="element p">This is paragraph 2.1.10</div>
77
+ <div class="element p">This is paragraph 2.1.11</div>
78
+ <div class="element p">This is paragraph 2.1.12</div>
79
+ <div class="element media-caption">This is caption 2.1</div>
80
+ <div class="element bibliography">This bibliography 2.1</div>
81
+ <img src="images/section1_page2_article1_1.jpg"/>
82
+ <img src="images/section1_page2_article1_2.jpg"/>
83
+ </div>
84
+ </div>
85
+ </body>
86
+ </html>
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'an opened GRF document', :shared => true do
4
+ before do
5
+ filename = "#{File.dirname __FILE__}/fixtures/sample.html"
6
+ @@document ||= Publishing::GRF.open(filename)
7
+ end
8
+ end
9
+
10
+ describe 'A document' do
11
+ it_should_behave_like 'an opened GRF document'
12
+ before{ @it = @@document }
13
+
14
+ it 'has pages' do
15
+ @it.pages.length > 0
16
+ end
17
+
18
+ it 'has sections' do
19
+ @it.sections.length > 0
20
+ end
21
+
22
+ it 'has elements' do
23
+ @it.elements.length > 0
24
+ end
25
+ end
26
+
27
+ describe 'A page' do
28
+ it_should_behave_like 'an opened GRF document'
29
+ before{ @it = @@document.pages.first }
30
+
31
+ it 'has frames' do
32
+ @it.frames.length.should > 0
33
+ end
34
+
35
+ it 'has elements' do
36
+ @it.elements.length > 0
37
+ end
38
+ end
39
+
40
+ describe 'A frame' do
41
+ it_should_behave_like 'an opened GRF document'
42
+ before{ @it = @@document.pages.first.frames.first }
43
+
44
+ it 'has elements' do
45
+ @it.elements.length.should > 0
46
+ end
47
+
48
+ it 'has blocks' do
49
+ @it.blocks.length.should > 0
50
+ end
51
+ end
52
+
53
+ describe 'An element' do
54
+ it_should_behave_like 'an opened GRF document'
55
+ before{ @page = @@document.pages.first; @it = @page.elements.first }
56
+ end
57
+
58
+ describe 'A block' do
59
+ it_should_behave_like 'an opened GRF document'
60
+ before{ @frame = @@document.pages.first.frames.first; @it = @frame.blocks.first }
61
+
62
+ it 'has fontsizes' do
63
+ @it.fontsizes.length.should >= 0
64
+ end
65
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'publishing/grf'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eterps-publishing-grf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Erik Terpstra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: erik@ruby-lang.nl
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/publishing/grf.rb
33
+ - lib/publishing/grf/core.rb
34
+ - lib/publishing/grf/reader.rb
35
+ - publishing-grf.gemspec
36
+ - spec/fixtures/sample.html
37
+ - spec/publishing-grf_spec.rb
38
+ - spec/spec_helper.rb
39
+ has_rdoc: true
40
+ homepage: http://github.com/eterps/publishing-grf
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.2.0
62
+ signing_key:
63
+ specification_version: 2
64
+ summary: TODO
65
+ test_files:
66
+ - spec/spec_helper.rb
67
+ - spec/publishing-grf_spec.rb