xbel 0.2.3 → 0.2.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.2.4
@@ -35,6 +35,10 @@ module Nokogiri::Decorators::XBEL
35
35
  end
36
36
  attr_reader :info
37
37
 
38
+ def attributes=(attributes)
39
+ attributes.each { |key, value| send "#{ key }=", value }
40
+ end
41
+
38
42
  # Returns description of node.
39
43
  def desc
40
44
  if node = at('./desc') then node.content end
@@ -77,7 +81,12 @@ module Nokogiri::Decorators::XBEL
77
81
  end
78
82
  # Sets addition date.
79
83
  def added=(value)
80
- set_attribute 'added', value.to_s
84
+ set_attribute 'added', case value
85
+ when Time; value.strftime '%Y-%m-%d'
86
+ when String; value
87
+ else
88
+ raise ArgumentError
89
+ end
81
90
  end
82
91
 
83
92
  # Returns nil.
@@ -34,31 +34,31 @@ module Nokogiri::Decorators::XBEL
34
34
  super
35
35
  end
36
36
 
37
- def build(type, attributes = {}, &block)
38
- child = Nokogiri::XML::Node.new(type.to_s, document)
39
- assign_to child, attributes, &block
37
+ def build(type, attributes = {})
38
+ node = Nokogiri::XML::Node.new(type.to_s, document)
39
+ node.attributes = attributes
40
40
 
41
- add_child child
41
+ yield node if block_given?
42
+
43
+ node
42
44
  end
43
45
 
44
46
  # Builds a bookmark with given attributes and add it.
45
- def build_bookmark(title, href, attributes = {}, &block)
46
- build :bookmark,
47
- attributes.merge(:title => title, :href => href),
48
- &block
47
+ def add_bookmark(title, href, attributes = {}, &block)
48
+ attributes = attributes.merge :title => title, :href => href
49
+ add_child build(:bookmark, attributes, &block)
49
50
  end
50
51
  # Builds a folder with given attributes and add it.
51
- def build_folder(title, attributes = {}, &block)
52
- build :folder,
53
- attributes.merge(:title => title),
54
- &block
52
+ def add_folder(title, attributes = {}, &block)
53
+ attributes = attributes.merge :title => title
54
+ add_child build(:folder, attributes, &block)
55
55
  end
56
56
  # Builds an alias with given attributes and add it.
57
- def build_alias(ref)
58
- child = Nokogiri::XML::Node.new('alias', document)
59
- child.ref = (Entry === ref) ? ref.id : ref.to_s
57
+ def add_alias(ref)
58
+ node = Nokogiri::XML::Node.new 'alias', document
59
+ node.ref = (Entry === ref) ? ref.id : ref.to_s
60
60
 
61
- add_child child
61
+ add_child node
62
62
  end
63
63
  # Builds a saperator with given attributes and add it.
64
64
  def add_separator
@@ -67,18 +67,21 @@ module Nokogiri::Decorators::XBEL
67
67
 
68
68
  protected
69
69
 
70
- def assign_to(node, attributes) #:nodoc:
71
- attributes[:id] ||= "#{ id }." << xpath('./bookmark | ./folder').
70
+ def generate_id
71
+ "#{ id }#{ document.div_id_er }" << xpath('./bookmark | ./folder').
72
72
  inject(0) { |next_id, child|
73
73
  succ_num_id = child.id[/(\d+)$/, 1].to_i.succ
74
74
  succ_num_id > next_id ? succ_num_id : next_id
75
75
  }.to_s
76
+ end
76
77
 
77
- attributes.each do |key, value|
78
- node.send "#{ key }=", value
78
+ def add_child(node)
79
+ if Entry === node
80
+ node.id ||= generate_id
81
+ node.added = Time.now
79
82
  end
80
83
 
81
- yield node if block_given?
84
+ super
82
85
  end
83
86
 
84
87
  end
data/lib/xbel.rb CHANGED
@@ -5,11 +5,22 @@ require 'nokogiri/decorators/xbel'
5
5
 
6
6
  class XBEL < Nokogiri::XML::Document
7
7
  extend Forwardable
8
- def_delegators :root, :title, :title=, :desc, :desc=
8
+ def_delegators :root,
9
+ :title, :title=,
10
+ :desc, :desc=,
11
+ :id, :id=
12
+
13
+ attr_accessor :div_id_er
14
+
15
+ TEMPLATE = %Q'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"><xbel version="1.0" id="0"></xbel>'
16
+ DIV_ID_ER = '_'
9
17
 
10
18
  # Returns an instance of XBEL.
11
- def self.new(major = 1, minor = 0)
12
- parse %Q'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"><xbel version="%i.%i"></xbel>' % [major, minor]
19
+ def self.new(attributes = {})
20
+ xbel = parse TEMPLATE
21
+ xbel.attributes = attributes
22
+
23
+ xbel
13
24
  end
14
25
 
15
26
  # Reads file at <tt>path</tt> into <tt>parse</tt>.
@@ -24,6 +35,8 @@ class XBEL < Nokogiri::XML::Document
24
35
  super
25
36
  decorators(Nokogiri::XML::Node) << Nokogiri::Decorators::XBEL
26
37
  decorate!
38
+
39
+ @div_id_er = DIV_ID_ER
27
40
  end
28
41
 
29
42
  # Returns node with given <tt>id</tt>.
@@ -31,6 +44,13 @@ class XBEL < Nokogiri::XML::Document
31
44
  root.at("//*[@id='#{ id }']")
32
45
  end
33
46
 
47
+ def attributes=(attributes)
48
+ version = attributes.delete(:version) and self.version = version
49
+ div_id_er = attributes.delete(:div_id_er) and self.div_id_er = div_id_er
50
+
51
+ root.attributes = attributes
52
+ end
53
+
34
54
  # Returns an array of version numbers.
35
55
  def version
36
56
  root.attribute('version').value.split('.').map { |n| n.to_i }
data/test/test_xbel.rb CHANGED
@@ -1,142 +1,172 @@
1
1
  require 'helper'
2
2
 
3
- context 'New XBEL' do
4
-
5
- asserts 'version' do
6
- XBEL.new.version
7
- end.equals [1, 0]
8
- asserts 'user defined version' do
9
- XBEL.new(2, 2).version
10
- end.equals [2, 2]
11
- asserts 'set version' do
12
- xbel = XBEL.new
13
- xbel.version = 1, 1
14
-
15
- xbel.version
16
- end.equals [1, 1]
17
- should 'be empty' do
18
- XBEL.new.root.content.empty?
19
- end
20
-
21
- end
22
-
23
3
  context 'XBEL' do
24
-
25
- setup do
26
- root = Pathname.new File.dirname(__FILE__)
27
- XBEL.open root.join('wikipedia.xbel')
4
+ setup { XBEL }
5
+
6
+ context 'build with defaults' do
7
+ setup { topic.new }
8
+
9
+ asserts 'version' do
10
+ topic.version
11
+ end.equals [1, 0]
12
+ asserts 'version set' do
13
+ topic.version = 1, 1
14
+ topic.version
15
+ end.equals [1, 1]
16
+ should 'be empty' do
17
+ topic.root.content.empty?
18
+ end
19
+ should 'have an id divider' do
20
+ String === topic.div_id_er and
21
+ topic.div_id_er.length > 0
22
+ end
23
+ end
24
+ context 'built with attributes' do
25
+ setup { topic.new :version => [2, 2], :div_id_er => '/', :id => 'custom' }
26
+
27
+ asserts 'user defined version' do
28
+ topic.version
29
+ end.equals [2, 2]
30
+ asserts 'div_id_er' do
31
+ topic.div_id_er
32
+ end.equals '/'
33
+ asserts 'id' do
34
+ topic.id
35
+ end.equals 'custom'
36
+
37
+ asserts 'id of added folder' do
38
+ topic.root.add_folder('foo').id
39
+ end.equals 'custom/0'
28
40
  end
29
41
 
30
- asserts('version') { topic.version }.equals [1, 0]
42
+ context 'loaded from wikipedia.xbel' do
43
+ setup do
44
+ root = Pathname.new File.dirname(__FILE__)
45
+ topic.open root.join('wikipedia.xbel')
46
+ end
31
47
 
32
- asserts('title') { topic.title }.equals 'Lesezeichen!'
33
- should('delegate title accessor to root') do
34
- topic.title = 'Bookmarks!'
48
+ asserts('version') { topic.version }.equals [1, 0]
35
49
 
36
- topic.title == topic.root.title and
37
- topic.title == 'Bookmarks!'
38
- end
50
+ asserts('title') { topic.title }.equals 'Lesezeichen!'
51
+ should('delegate title accessor to root') do
52
+ topic.title = 'Bookmarks!'
39
53
 
40
- context 'Alias' do
41
- setup { topic.root.aliases.first }
42
- should('be an alias') { topic.alias? }
43
-
44
- should('have a reference') do
45
- topic.ref and
46
- topic.ref == topic.reference
54
+ topic.title == topic.root.title and
55
+ topic.title == 'Bookmarks!'
47
56
  end
48
- end
49
57
 
50
- context 'Folder' do
51
- setup { topic[:f0] }
52
- should('be a folder') { topic.folder? }
58
+ context 'Alias' do
59
+ setup { topic.root.aliases.first }
60
+ should('be an alias') { topic.alias? }
53
61
 
54
- asserts('title') { topic.title }.equals 'Wiki'
55
- asserts('entries names') do
56
- topic.entries.map { |e| e.name }.uniq.sort
57
- end.equals %w[ alias bookmark folder separator ]
58
- should('return bookmarks') do
59
- not topic.bookmarks.any? { |b| b.name != 'bookmark' }
60
- end
61
- should('return aliases') do
62
- not topic.aliases.any? { |b| b.name != 'alias' }
62
+ should('have a reference') do
63
+ topic.ref and
64
+ topic.ref == topic.reference
65
+ end
63
66
  end
64
- should('return folders') do
65
- not topic.folders.any? { |b| b.name != 'folder' }
67
+
68
+ context 'root' do
69
+ setup { topic.root }
70
+ context 'new Bookmark' do
71
+ setup do
72
+ topic.add_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
73
+ :description => 'Ruby API for XBEL based on Nokogiri.'
74
+ end
75
+ asserts('next id') { topic.id }.equals 'test_2'
76
+ end
66
77
  end
67
78
 
68
- context 'Bookmark' do
69
- setup { topic.bookmarks.first }
70
- should('be a bookmark') { topic.bookmark? }
79
+ context 'Folder' do
80
+ setup { topic[:test_1] }
81
+ should('be a folder') { topic.folder? }
71
82
 
72
- asserts('modified') { topic.modified }.kind_of Date
83
+ asserts('title') { topic.title }.equals 'Wiki'
84
+ asserts('entries names') do
85
+ topic.entries.map { |e| e.name }.uniq.sort
86
+ end.equals %w[ alias bookmark folder separator ]
87
+ should('return bookmarks') do
88
+ not topic.bookmarks.any? { |b| b.name != 'bookmark' }
89
+ end
90
+ should('return aliases') do
91
+ not topic.aliases.any? { |b| b.name != 'alias' }
92
+ end
93
+ should('return folders') do
94
+ not topic.folders.any? { |b| b.name != 'folder' }
95
+ end
73
96
 
74
- asserts('visited') { topic.visited }.kind_of Date
75
- asserts('visit') do
76
- topic.visit
77
- topic.visited
78
- end.equals Date.today
79
- end
80
- context 'new Bookmark' do
81
- setup do
82
- topic.build_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
83
- :description => 'Ruby API for XBEL based on Nokogiri.'
97
+ context 'Bookmark' do
98
+ setup { topic.bookmarks.first }
99
+ should('be a bookmark') { topic.bookmark? }
100
+
101
+ asserts('modified') { topic.modified }.kind_of Date
102
+
103
+ asserts('visited') { topic.visited }.kind_of Date
104
+ asserts('visit') do
105
+ topic.visit
106
+ topic.visited
107
+ end.equals Date.today
108
+ end
109
+ context 'new Bookmark' do
110
+ setup do
111
+ topic.add_bookmark "boof's xbel", 'http://www.github.com/boof/xbel',
112
+ :description => 'Ruby API for XBEL based on Nokogiri.'
113
+ end
114
+ should('be a bookmark') { topic.bookmark? }
115
+
116
+ asserts('added') { topic.added }.equals Date.today
117
+ asserts('title') { topic.title }.equals 'boof\'s xbel'
118
+ asserts('next id') { topic.id }.equals 'test_1_4'
119
+ asserts('href') { topic.href }.
120
+ equals 'http://www.github.com/boof/xbel'
121
+ asserts('description') { topic.description }.
122
+ equals 'Ruby API for XBEL based on Nokogiri.'
84
123
  end
85
- should('be a bookmark') { topic.bookmark? }
86
124
 
87
- asserts('added') { topic.added }.equals Date.today
88
- asserts('title') { topic.title }.equals 'boof\'s xbel'
89
- asserts('next id') { topic.id }.equals 'f0.2'
90
- asserts('href') { topic.href }.
91
- equals 'http://www.github.com/boof/xbel'
92
- asserts('description') { topic.description }.
93
- equals 'Ruby API for XBEL based on Nokogiri.'
94
- end
125
+ context 'new Folder' do
126
+ setup { topic.add_folder 'sub', :desc => 'desc' }
127
+ should('be a folder') { topic.folder? }
95
128
 
96
- context 'new Folder' do
97
- setup { topic.build_folder 'sub', :desc => 'desc' }
98
- should('be a folder') { topic.folder? }
129
+ asserts('added') { topic.added }.equals Date.today
130
+ asserts('title') { topic.title }.equals 'sub'
131
+ asserts('next id') { topic.id }.equals 'test_1_4'
132
+ asserts('desc') { topic.desc }.equals 'desc'
133
+ end
99
134
 
100
- asserts('added') { topic.added }.equals Date.today
101
- asserts('title') { topic.title }.equals 'sub'
102
- asserts('next id') { topic.id }.equals 'f0.2'
103
- asserts('desc') { topic.desc }.equals 'desc'
104
- end
135
+ context 'new Alias' do
136
+ setup { topic.add_alias topic }
137
+ should('be an alias') { topic.alias? }
105
138
 
106
- context 'new Alias' do
107
- setup { topic.build_alias topic }
108
- should('be an alias') { topic.alias? }
139
+ should('reference its folder') { topic.entry == topic.parent }
140
+ should('set reference by entry') do
141
+ topic.entry = topic.document[:test_1_3]
142
+ topic.ref == 'test_1_3'
143
+ end
144
+ end
109
145
 
110
- should('reference its folder') { topic.entry == topic.parent }
111
- should('set reference by entry') do
112
- topic.entry = topic.document[:b1]
113
- topic.ref == 'b1'
146
+ context 'Separator' do
147
+ setup { topic.entries.find { |e| e.name == 'separator' } }
148
+ asserts('to_s') { topic.to_s }.equals ' '
114
149
  end
115
- end
116
150
 
117
- context 'Separator' do
118
- setup { topic.entries.find { |e| e.name == 'separator' } }
119
- asserts('to_s') { topic.to_s }.equals ' '
120
151
  end
121
152
 
122
- end
153
+ context 'Bookmark b0' do
154
+ setup { topic[:test_1_1] }
155
+ should('be a bookmark') { topic.bookmark? }
123
156
 
124
- context 'Bookmark b0' do
125
- setup { topic[:b0] }
126
- should('be a bookmark') { topic.bookmark? }
127
-
128
- context 'Info' do
129
- setup { topic.info }
130
- should('be a hash') { Hash === topic }
157
+ context 'Info' do
158
+ setup { topic.info }
159
+ should('be a hash') { Hash === topic }
131
160
 
132
- context 'metadata for xbel' do
133
- setup { topic[:xbel] if topic }
134
- should('be a node') { Nokogiri::XML::Node === topic }
161
+ context 'metadata for xbel' do
162
+ setup { topic[:xbel] if topic }
163
+ should('be a node') { Nokogiri::XML::Node === topic }
135
164
 
136
- should('be have an alias') { not topic.at('./alias').nil? }
165
+ should('be have an alias') { not topic.at('./alias').nil? }
166
+ end
137
167
  end
138
- end
139
168
 
169
+ end
140
170
  end
141
171
 
142
172
  end
data/test/wikipedia.xbel CHANGED
@@ -2,27 +2,27 @@
2
2
  <!DOCTYPE xbel
3
3
  PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"
4
4
  "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">
5
- <xbel version="1.0">
5
+ <xbel version="1.0" id="test">
6
6
  <title>Lesezeichen!</title>
7
7
  <desc>Lernen von XBEL am Beispiel von zwei Lesezeichen und einer Verknüpfung</desc>
8
- <folder id="f0" added="2007-11-10">
8
+ <folder id="test_1" added="2007-11-10">
9
9
  <title>Wiki</title>
10
10
  <desc>Webseiten von Autoren-Gemeinschaften</desc>
11
- <bookmark href="http://wikimediafoundation.org/" id="b0" added="2007-11-11" modified="2007-11-14" visited="2007-11-14">
11
+ <bookmark href="http://wikimediafoundation.org/" id="test_1_1" added="2007-11-11" modified="2007-11-14" visited="2007-11-14">
12
12
  <info>
13
13
  <metadata owner="xbel">
14
- <alias ref="f0" />
14
+ <alias ref="test_1" />
15
15
  </metadata>
16
16
  </info>
17
17
  <title>Wikimedia Foundation</title>
18
18
  </bookmark>
19
- <alias ref="f0-1" />
19
+ <alias ref="test_1_1" />
20
20
  <separator />
21
- <bookmark href="http://de.wikipedia.org/" id="b1" added="2007-11-11" modified="2007-11-14" visited="2007-12-27">
21
+ <bookmark href="http://de.wikipedia.org/" id="test_1_2" added="2007-11-11" modified="2007-11-14" visited="2007-12-27">
22
22
  <title>Wikipedia</title>
23
23
  </bookmark>
24
- <folder id="f0-1"></folder>
24
+ <folder id="test_1_3"></folder>
25
25
  </folder>
26
26
  <separator />
27
- <alias ref="b1" />
27
+ <alias ref="test_1_2" />
28
28
  </xbel>
data/xbel.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{xbel}
8
- s.version = "0.2.3"
8
+ s.version = "0.2.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Florian A\303\237mann"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xbel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Florian A\xC3\x9Fmann"