factoid 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e01d537e7fcee79c2f5f1d17096672fda9c17ff
4
+ data.tar.gz: ccbf896597df8d4ee9c2adf618fcefec774f970f
5
+ SHA512:
6
+ metadata.gz: 97325418c38331595952ce5d20ba685951f97af709ed528ded4ceb7751e16d92bbff607d9905a316f990c17e6918058eafe8a6fac40265b5686aff2290528f67
7
+ data.tar.gz: c00e48f039b7d5e507f3335078d493206874f8a8bfc7d4500342fe10f9ad6ae4a0b94e930c3d166515602c2f7833b4d989b5cf2121f6efbbf1728608f3a2b383
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/COPYING ADDED
@@ -0,0 +1,121 @@
1
+ Creative Commons Legal Code
2
+
3
+ CC0 1.0 Universal
4
+
5
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12
+ HEREUNDER.
13
+
14
+ Statement of Purpose
15
+
16
+ The laws of most jurisdictions throughout the world automatically confer
17
+ exclusive Copyright and Related Rights (defined below) upon the creator
18
+ and subsequent owner(s) (each and all, an "owner") of an original work of
19
+ authorship and/or a database (each, a "Work").
20
+
21
+ Certain owners wish to permanently relinquish those rights to a Work for
22
+ the purpose of contributing to a commons of creative, cultural and
23
+ scientific works ("Commons") that the public can reliably and without fear
24
+ of later claims of infringement build upon, modify, incorporate in other
25
+ works, reuse and redistribute as freely as possible in any form whatsoever
26
+ and for any purposes, including without limitation commercial purposes.
27
+ These owners may contribute to the Commons to promote the ideal of a free
28
+ culture and the further production of creative, cultural and scientific
29
+ works, or to gain reputation or greater distribution for their Work in
30
+ part through the use and efforts of others.
31
+
32
+ For these and/or other purposes and motivations, and without any
33
+ expectation of additional consideration or compensation, the person
34
+ associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35
+ is an owner of Copyright and Related Rights in the Work, voluntarily
36
+ elects to apply CC0 to the Work and publicly distribute the Work under its
37
+ terms, with knowledge of his or her Copyright and Related Rights in the
38
+ Work and the meaning and intended legal effect of CC0 on those rights.
39
+
40
+ 1. Copyright and Related Rights. A Work made available under CC0 may be
41
+ protected by copyright and related or neighboring rights ("Copyright and
42
+ Related Rights"). Copyright and Related Rights include, but are not
43
+ limited to, the following:
44
+
45
+ i. the right to reproduce, adapt, distribute, perform, display,
46
+ communicate, and translate a Work;
47
+ ii. moral rights retained by the original author(s) and/or performer(s);
48
+ iii. publicity and privacy rights pertaining to a person's image or
49
+ likeness depicted in a Work;
50
+ iv. rights protecting against unfair competition in regards to a Work,
51
+ subject to the limitations in paragraph 4(a), below;
52
+ v. rights protecting the extraction, dissemination, use and reuse of data
53
+ in a Work;
54
+ vi. database rights (such as those arising under Directive 96/9/EC of the
55
+ European Parliament and of the Council of 11 March 1996 on the legal
56
+ protection of databases, and under any national implementation
57
+ thereof, including any amended or successor version of such
58
+ directive); and
59
+ vii. other similar, equivalent or corresponding rights throughout the
60
+ world based on applicable law or treaty, and any national
61
+ implementations thereof.
62
+
63
+ 2. Waiver. To the greatest extent permitted by, but not in contravention
64
+ of, applicable law, Affirmer hereby overtly, fully, permanently,
65
+ irrevocably and unconditionally waives, abandons, and surrenders all of
66
+ Affirmer's Copyright and Related Rights and associated claims and causes
67
+ of action, whether now known or unknown (including existing as well as
68
+ future claims and causes of action), in the Work (i) in all territories
69
+ worldwide, (ii) for the maximum duration provided by applicable law or
70
+ treaty (including future time extensions), (iii) in any current or future
71
+ medium and for any number of copies, and (iv) for any purpose whatsoever,
72
+ including without limitation commercial, advertising or promotional
73
+ purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74
+ member of the public at large and to the detriment of Affirmer's heirs and
75
+ successors, fully intending that such Waiver shall not be subject to
76
+ revocation, rescission, cancellation, termination, or any other legal or
77
+ equitable action to disrupt the quiet enjoyment of the Work by the public
78
+ as contemplated by Affirmer's express Statement of Purpose.
79
+
80
+ 3. Public License Fallback. Should any part of the Waiver for any reason
81
+ be judged legally invalid or ineffective under applicable law, then the
82
+ Waiver shall be preserved to the maximum extent permitted taking into
83
+ account Affirmer's express Statement of Purpose. In addition, to the
84
+ extent the Waiver is so judged Affirmer hereby grants to each affected
85
+ person a royalty-free, non transferable, non sublicensable, non exclusive,
86
+ irrevocable and unconditional license to exercise Affirmer's Copyright and
87
+ Related Rights in the Work (i) in all territories worldwide, (ii) for the
88
+ maximum duration provided by applicable law or treaty (including future
89
+ time extensions), (iii) in any current or future medium and for any number
90
+ of copies, and (iv) for any purpose whatsoever, including without
91
+ limitation commercial, advertising or promotional purposes (the
92
+ "License"). The License shall be deemed effective as of the date CC0 was
93
+ applied by Affirmer to the Work. Should any part of the License for any
94
+ reason be judged legally invalid or ineffective under applicable law, such
95
+ partial invalidity or ineffectiveness shall not invalidate the remainder
96
+ of the License, and in such case Affirmer hereby affirms that he or she
97
+ will not (i) exercise any of his or her remaining Copyright and Related
98
+ Rights in the Work or (ii) assert any associated claims and causes of
99
+ action with respect to the Work, in either case contrary to Affirmer's
100
+ express Statement of Purpose.
101
+
102
+ 4. Limitations and Disclaimers.
103
+
104
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
105
+ surrendered, licensed or otherwise affected by this document.
106
+ b. Affirmer offers the Work as-is and makes no representations or
107
+ warranties of any kind concerning the Work, express, implied,
108
+ statutory or otherwise, including without limitation warranties of
109
+ title, merchantability, fitness for a particular purpose, non
110
+ infringement, or the absence of latent or other defects, accuracy, or
111
+ the present or absence of errors, whether or not discoverable, all to
112
+ the greatest extent permissible under applicable law.
113
+ c. Affirmer disclaims responsibility for clearing rights of other persons
114
+ that may apply to the Work or any use thereof, including without
115
+ limitation any person's Copyright and Related Rights in the Work.
116
+ Further, Affirmer disclaims responsibility for obtaining any necessary
117
+ consents, permissions or other rights required for any use of the
118
+ Work.
119
+ d. Affirmer understands and acknowledges that Creative Commons is not a
120
+ party to this document and has no duty or obligation with respect to
121
+ this CC0 or use of the Work.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in factoid.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Gioele Barabucci
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,116 @@
1
+ factoid: read, manipulate and save factoids
2
+ ===========================================
3
+
4
+ `factoid` is a Ruby library to manipulate _factoids_ and _entitoids_
5
+ inside Ruby applications without touching the their XML representations.
6
+
7
+
8
+ What is a factoid?
9
+ ------------------
10
+
11
+ Factoids and Entitoids are representations of pieces of information
12
+ about a certain entity. These representations not only store the
13
+ information itself, but also keep track of provenance (who stated
14
+ something, where, when) and context (under which assumption is a
15
+ certain piece of information valid?). Using factoids one can store
16
+ and manage different values for the same property of an entity.
17
+
18
+ For example, instead of just storing that
19
+
20
+ > composer with ID 14 has property 'name' = 'Frédéric Chopin'
21
+
22
+ using factoids one can say
23
+
24
+ > there is a composer with ID 14
25
+
26
+ > Wikipedia says that composer#14 has
27
+ > * a property 'name',
28
+ > * with context 'language' = 'fra',
29
+ > * and value 'Frédéric Chopin'.
30
+
31
+ > Book with ISBN 9780007351824 says that composer#14 has
32
+ > * a property 'name',
33
+ > * with context 'language' = 'pol',
34
+ > * and value 'Fryderyk Chopin'.
35
+
36
+ The name of composer 14 is then both _Frédéric Chopin_ and _Fryderyk
37
+ Chopin_ depending on the context.
38
+
39
+ Factoids and entitoids are described more in depth at
40
+ <http://svario.it/factoid>.
41
+
42
+ The `factoid` gem makes it possible to load and save factoids, to search
43
+ and select factoids that match certain patterns and to access complex
44
+ information in a simple way.
45
+
46
+
47
+ Examples
48
+ --------
49
+
50
+ c14 = Factoid::Entitoid.from_xml('composer14.xml')
51
+
52
+ puts "Known names:"
53
+ puts
54
+ c.factoids('name').each do |fact|
55
+ puts " #{fact.value} in #{fact.context['language']}"
56
+ puts " (from #{fact.sources})"
57
+ puts
58
+ end
59
+
60
+ # Known names:
61
+ #
62
+ # Frédéric Chopin in fra
63
+ # (from http://en.wikipedia.org/wiki/Frédéric_Chopin)
64
+ # Fryderyk Chopin in pol
65
+ # (from urn:isbn:9780007351824)
66
+
67
+
68
+ Requirements
69
+ ------------
70
+
71
+ factoid is based on Nokogiri and uses Addressable to manage URIs.
72
+
73
+
74
+ Install
75
+ -------
76
+
77
+ Install the factoid gem using RubyGems
78
+
79
+ gem install factoid
80
+
81
+ or Bundler
82
+
83
+ # in Gemfile
84
+ gem 'factoid'
85
+
86
+ To use the factoid gem in your project, load it with
87
+
88
+ require 'factoid'
89
+
90
+
91
+ Author
92
+ ------
93
+
94
+ * Gioele Barabucci <http://svario.it/gioele> (initial author)
95
+
96
+
97
+ Development
98
+ -----------
99
+
100
+ Code
101
+ : <http://svario.it/factoid/ruby> (redirects to GitHub)
102
+
103
+ Report issues
104
+ : <http://svario.it/factoid/ruby/issues>
105
+
106
+ Documentation
107
+ : <http://svario.it/factoid/ruby/docs>
108
+
109
+
110
+ License
111
+ -------
112
+
113
+ This is free software released into the public domain (CC0 license).
114
+
115
+ See the `COPYING` file or <http://creativecommons.org/publicdomain/zero/1.0/>
116
+ for more details.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ require 'factoid/version'
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = "factoid"
11
+ spec.version = Factoid::VERSION
12
+ spec.authors = ["Gioele Barabucci"]
13
+ spec.email = ["gioele@svario.it"]
14
+ spec.summary = "factoid is a Ruby library to manipulate factoids " +
15
+ "entitoids inside Ruby applications without " +
16
+ "touching the their XML representations."
17
+ spec.homepage = 'http://svario.it/factoid/ruby'
18
+ spec.license = 'CC0'
19
+
20
+ spec.files = `git ls-files`.split($/)
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'nokogiri'
26
+ spec.add_dependency 'addressable'
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.3'
29
+ spec.add_development_dependency 'rake'
30
+ spec.add_development_dependency 'rspec'
31
+ end
@@ -0,0 +1,4 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+ require 'factoid/entitoid'
4
+ require 'factoid/factoid'
@@ -0,0 +1,55 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ module Factoid
5
+ class Entitoid
6
+ def initialize(uuid)
7
+ @uuid = uuid
8
+ @factoids = []
9
+ end
10
+
11
+ attr_reader :uuid
12
+
13
+ def add_factoid(factoid)
14
+ @factoids << factoid
15
+ end
16
+
17
+ def factoids(name, context = {})
18
+ if name == :all
19
+ return @factoids
20
+ end
21
+
22
+ matching = @factoids.select { |f| f.match?(name, context) }
23
+ return matching
24
+ end
25
+
26
+ def value(name, context = {})
27
+ f = factoids(name, context)
28
+
29
+ if f.empty?
30
+ raise "Cannot return value, no factoid matches name: '#{name}', context: #{context}"
31
+ end
32
+
33
+ if f.count > 1
34
+ raise "Cannot return value, too many factoids match name: '#{name}', context: #{context}"
35
+ end
36
+
37
+ return f.first.value
38
+ end
39
+
40
+ def eql?(other)
41
+ if other.equal?(self)
42
+ return true
43
+ end
44
+
45
+ if other.class != self.class
46
+ return false
47
+ end
48
+
49
+ f = factoids(:all)
50
+ other_f = other.factoids(:all)
51
+
52
+ return f.eql?(other_f)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,33 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ require 'addressable/uri'
5
+
6
+ require 'factoid/entitoid'
7
+
8
+ module Factoid
9
+ class EntitoidRef
10
+ def initialize(uri, base)
11
+ @uri = Addressable::URI.parse(uri)
12
+ @base = base
13
+ end
14
+
15
+ attr_reader :uri
16
+
17
+ def full_uri
18
+ return Addressable::URI.join(@base, @uri)
19
+ end
20
+
21
+ def deref
22
+ return Entitoid.from_xml(full_uri)
23
+ end
24
+
25
+ def eql?(other)
26
+ if other.class != self.class
27
+ return false
28
+ end
29
+
30
+ return other.full_uri == self.full_uri
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ module Factoid
5
+ class Factoid
6
+ def initialize(type, context, value_obj, sources, context_sources)
7
+ @type = type
8
+ @context = context
9
+ @value_obj = value_obj
10
+
11
+ @sources = sources
12
+ @context_sources = context_sources
13
+ end
14
+
15
+ attr_reader :type
16
+ attr_reader :value_obj
17
+ attr_reader :context
18
+
19
+ def sources
20
+ if !@sources.empty?
21
+ return @sources
22
+ end
23
+
24
+ uris = @context_sources.select { |s| s.default? }
25
+
26
+ return uris
27
+ end
28
+
29
+ def match?(type, context)
30
+ if @type != type # FIXME: check type hierarchy
31
+ return false
32
+ end
33
+
34
+ return context.to_a.all? { |k, v| @context[k.to_s] == v }
35
+ end
36
+
37
+ def value(interpret = true, follow = false)
38
+ return @value_obj.value(interpret, follow)
39
+ end
40
+
41
+ def eql?(other)
42
+ if other.equal?(self)
43
+ return true
44
+ end
45
+
46
+ if other.class != self.class
47
+ return false
48
+ end
49
+
50
+ same = other.type == self.type &&
51
+ other.value.eql?(self.value) &&
52
+ other.sources == self.sources
53
+
54
+ return same
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,50 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ require 'addressable/uri'
5
+
6
+ module Factoid
7
+ class Source
8
+ def initialize(uuid, uri, default, value)
9
+ @uuid = uuid
10
+ @uri = Addressable::URI.parse(uri)
11
+ @default = default
12
+ @value = value
13
+ end
14
+
15
+ attr_reader :uuid
16
+ attr_reader :uri
17
+ attr_reader :value
18
+
19
+ def default?
20
+ return @default
21
+ end
22
+
23
+ def ref?
24
+ # FIXME: separate SourceRef class
25
+ return !@uri.nil?
26
+ end
27
+
28
+ def ==(other)
29
+ if other.equal?(self)
30
+ return true
31
+ end
32
+
33
+ if other.is_a?(Source)
34
+ if other.ref?
35
+ return other.uri == self.uri
36
+ else
37
+ return other.value == self.value
38
+ end
39
+ end
40
+
41
+ if ref?
42
+ return Addressable::URI.parse(other) == @uri
43
+ else
44
+ return other == @value.to_s
45
+ end
46
+ end
47
+
48
+ # FIXME: move part of == to eql?; add tests
49
+ end
50
+ end
@@ -0,0 +1,85 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ module Factoid
5
+ class Value
6
+ def initialize(type, raw_value)
7
+ @type = type
8
+ @raw_value = raw_value
9
+ end
10
+
11
+ EMPTY = Value.new(nil, nil).freeze
12
+
13
+ def value(interpret, follow)
14
+ raw = nil
15
+
16
+ if @raw_value.elements.empty?
17
+ raw = @raw_value.text
18
+ else
19
+ raw = @raw_value
20
+ end
21
+
22
+ if !interpret
23
+ return raw
24
+ end
25
+
26
+ interpreter = Interpreters.find { |i| begin i.accept?(@type, raw); rescue; end; }
27
+ v = interpreter.interpret(@type, raw)
28
+
29
+ if !follow
30
+ return v
31
+ end
32
+
33
+ # FIXME: use Dereferenciators (like Interpreters)
34
+ if v.is_a? EntitoidRef
35
+ r = v.deref
36
+ else
37
+ r = v
38
+ end
39
+
40
+ return r
41
+ end
42
+
43
+ class XSDDateInterpreter
44
+ def self.accept?(type, value)
45
+ return type == 'xsd:date'
46
+ end
47
+
48
+ def self.interpret(type, value)
49
+ require 'time'
50
+ return Time.parse(value)
51
+ end
52
+ end
53
+
54
+ class EntitoidInterpreter
55
+ def self.accept?(type, value)
56
+ return !value.xpath('./f:*', NS).empty?
57
+ end
58
+
59
+ def self.interpret(type, value)
60
+ require 'factoid/xml'
61
+
62
+ # FIXME: allow also complete entitoids
63
+
64
+ elem = value.at('./f:*', NS)
65
+ return EntitoidRef.from_xml(elem)
66
+ end
67
+ end
68
+
69
+ class IndentityInterpreter
70
+ def self.accept?(type, value)
71
+ return true
72
+ end
73
+
74
+ def self.interpret(type, value)
75
+ return value
76
+ end
77
+ end
78
+
79
+ Interpreters = [
80
+ XSDDateInterpreter,
81
+ EntitoidInterpreter,
82
+ IndentityInterpreter,
83
+ ]
84
+ end
85
+ end
@@ -0,0 +1,6 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ module Factoid
5
+ VERSION = '0.1'
6
+ end
@@ -0,0 +1,91 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ require 'nokogiri'
5
+
6
+ require 'factoid/entitoid'
7
+ require 'factoid/entitoid_ref'
8
+ require 'factoid/factoid'
9
+ require 'factoid/source'
10
+ require 'factoid/value'
11
+
12
+ module Factoid
13
+ FACTOID_NS_URI = 'http://svario.it/factoid'
14
+
15
+ NS = {
16
+ 'f' => FACTOID_NS_URI,
17
+ 'xlink' => 'http://www.w3.org/1999/xlink',
18
+ 'xsd' => 'http://www.w3.org/2001/XMLSchema-datatypes',
19
+ }
20
+
21
+ def Entitoid.from_xml(filename)
22
+ x = Nokogiri::XML(open(filename))
23
+
24
+ uuid = x.root.attr('xml:id')
25
+ e = self.new(uuid)
26
+
27
+ context_sources = []
28
+ x.xpath('/*/f:sources/f:source').each do |s|
29
+ context_sources << Source.from_xml(s)
30
+ end
31
+
32
+ x.xpath('/*/f:*', NS).each do |f|
33
+ if f.name == 'sources'
34
+ next
35
+ end
36
+
37
+ e.add_factoid(Factoid.from_xml(f, context_sources))
38
+ end
39
+
40
+ return e
41
+ end
42
+
43
+ def EntitoidRef.from_xml(elem)
44
+ href = elem.attr('xlink:href')
45
+ base = elem.document.url
46
+
47
+ return EntitoidRef.new(href, base)
48
+ end
49
+
50
+ def Factoid.from_xml(elem, context_sources)
51
+ type = elem.name unless elem.name == 'factoid'
52
+ type ||= elem.attr('type')
53
+
54
+ context = {}
55
+ elem.xpath('./*[name(.) != "value"]').each do |e|
56
+ context[e.name] = e.text
57
+ end
58
+
59
+ value = Value.from_xml(elem)
60
+
61
+ raw_sources = elem.xpath('f:source', NS)
62
+ sources = raw_sources.map do |e|
63
+ Source.from_xml(e)
64
+ end
65
+
66
+ return Factoid.new(type, context, value, sources, context_sources)
67
+ end
68
+
69
+ def Source.from_xml(elem)
70
+ uuid = elem.attr('xml:id')
71
+
72
+ uri = elem.attr('xlink:href')
73
+
74
+ default = (elem.attr('default') == 'true')
75
+
76
+ #value = Value.from_xml(elem)
77
+ value = Value::EMPTY
78
+
79
+ return Source.new(uuid, uri, default, value)
80
+ end
81
+
82
+ def Value.from_xml(container_elem)
83
+ elem = container_elem.at('./f:value', NS)
84
+
85
+ type = elem.attr('type')
86
+ # TODO: special case for entitoids
87
+ # TODO: use type = :entitoid_ref instead of nil
88
+
89
+ return Value.new(type, elem)
90
+ end
91
+ end
@@ -0,0 +1,56 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ require 'spec_helpers'
5
+
6
+ require 'factoid/entitoid'
7
+ require 'factoid/xml'
8
+
9
+ describe Factoid::Entitoid do
10
+ before(:all) do
11
+ @e = Factoid::Entitoid.from_xml('spec/fixtures/chopin.xml')
12
+ end
13
+
14
+ it "can be loaded from XML" do
15
+ expect(@e).to be_a Factoid::Entitoid
16
+ expect(@e.uuid).to eql "chopin-23"
17
+ end
18
+
19
+ describe "#factoids" do
20
+ it "returns all the factoids" do
21
+ expect(@e.factoids(:all)).to have(8).items
22
+ end
23
+
24
+ it "returns all the factoids of type 'name'" do
25
+ expect(@e.factoids('name')).to have(4).items
26
+ end
27
+
28
+ it "returns all the factoids of type 'name' with a certain context" do
29
+ expect(@e.factoids('name', :language => 'fra')).to have(2).items
30
+ end
31
+ end
32
+
33
+ describe "#value" do
34
+ it "raises an exception if the request is ambiguous" do
35
+ expect { @e.value('birth-date') }.to raise_error
36
+ end
37
+
38
+ it "raises an exception if no factoid exists" do
39
+ expect { @e.value('unk-property') }.to raise_error
40
+ end
41
+ end
42
+
43
+ describe "#source" do
44
+ it "returns the stated source" do
45
+ f = @e.factoids('birth-date').first
46
+
47
+ expect(f.sources).to eq ["#bcert"]
48
+ end
49
+
50
+ it "returns the default source" do
51
+ f = @e.factoids('birth-date').last
52
+
53
+ expect(f.sources).to eq ["http://en.wikipedia.org/wiki/Frédéric_Chopin"]
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,66 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
4
+ require 'spec_helpers'
5
+
6
+ require 'nokogiri'
7
+
8
+ require 'factoid/entitoid'
9
+ require 'factoid/entitoid_ref'
10
+ require 'factoid/factoid'
11
+ require 'factoid/xml'
12
+
13
+ describe Factoid::Factoid do
14
+ before (:all) do
15
+ e = Factoid::Entitoid.from_xml('spec/fixtures/chopin.xml')
16
+ @name = e.factoids('name', 'language' => 'fra').first
17
+ @death_date = e.factoids('death-date').first
18
+ @birth_place = e.factoids('birth-place').first
19
+ end
20
+
21
+ describe "#value" do
22
+ context "with no arguments" do
23
+ it "returns a string" do
24
+ expect(@name.value).to eql "Frédéric Chopin"
25
+ end
26
+
27
+ it "returns a date" do
28
+ expect(@death_date.value).to eql Time.mktime(1849, 10, 17)
29
+ end
30
+
31
+ it "returns an entitoid ref" do
32
+ place_ref = Factoid::EntitoidRef.new('zelazowa-wola', 'spec/fixtures/chopin.xml')
33
+ expect(@birth_place.value).to eql place_ref
34
+ end
35
+ end
36
+
37
+ context "with no interpretation" do
38
+ it "returns a string" do
39
+ expect(@name.value(false)).to eql "Frédéric Chopin"
40
+ end
41
+
42
+ it "returns a string also for dates" do
43
+ expect(@death_date.value(false)).to eql "1849-10-17"
44
+ end
45
+
46
+ it "returns an XML element" do
47
+ expect(@birth_place.value(false)).to be_a Nokogiri::XML::Node
48
+ end
49
+ end
50
+
51
+ context "with follows" do
52
+ it "returns a string" do
53
+ expect(@name.value(true, true)).to eql "Frédéric Chopin"
54
+ end
55
+
56
+ it "returns a string also for dates" do
57
+ expect(@death_date.value(true, true)).to eql Time.mktime(1849, 10, 17)
58
+ end
59
+
60
+ it "returns an entitoid" do
61
+ zelazowa_wola = Factoid::Entitoid.from_xml('spec/fixtures/zelazowa-wola.xml')
62
+ expect(@birth_place.value(true, true)).to eql zelazowa_wola
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,49 @@
1
+ <f:entity type="composer" xml:id="chopin-23" xmlns:f='http://svario.it/factoid'
2
+ xmlns:xlink="http://www.w3.org/1999/xlink"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema-datatypes">
4
+ <f:sources>
5
+ <f:source xml:id="wp" xlink:href="http://en.wikipedia.org/wiki/Fr%C3%A9d%C3%A9ric_Chopin" default="true"/>
6
+ <f:source xml:id="bcert" xlink:href="urn:isbn:9780007351824"/>
7
+ </f:sources>
8
+
9
+ <f:factoid type="name">
10
+ <language>pol</language>
11
+ <f:value>Fryderyk Franciszek Chopin</f:value>
12
+ </f:factoid>
13
+
14
+ <f:factoid type="name">
15
+ <language>pol</language>
16
+ <f:value>Fryderyk Chopin</f:value>
17
+ </f:factoid>
18
+
19
+ <f:name>
20
+ <language>fra</language>
21
+ <f:value>Frédéric Chopin</f:value>
22
+ </f:name>
23
+
24
+ <f:name>
25
+ <language>fra</language>
26
+ <alphabet>Hang</alphabet>
27
+ <f:value>프레데리크 쇼팽</f:value>
28
+ </f:name>
29
+
30
+ <f:factoid type="birth-date">
31
+ <f:value type="xsd:date">1810-08-22</f:value>
32
+ <f:source xlink:href="#bcert"/>
33
+ </f:factoid>
34
+
35
+ <f:birth-date>
36
+ <f:value type="xsd:date">1810-03-01</f:value>
37
+ </f:birth-date>
38
+
39
+ <f:birth-place>
40
+ <f:value>
41
+ <f:place xlink:href="zelazowa-wola"/>
42
+ </f:value>
43
+ </f:birth-place>
44
+
45
+ <f:death-date>
46
+ <f:value type="xsd:date">1849-10-17</f:value>
47
+ </f:death-date>
48
+ </f:entity>
49
+ <!-- This is free software released into the public domain (CC0 license). -->
@@ -0,0 +1,19 @@
1
+ <f:entity type="place" xml:id="zelazowa-wola" xmlns:f='http://svario.it/factoid'
2
+ xmlns:xlink="http://www.w3.org/1999/xlink"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema-datatypes">
4
+ <f:sources>
5
+ <f:source xml:id="wp" xlink:href="http://en.wikipedia.org/wiki/Żelazowa_Wola" default="true"/>
6
+ </f:sources>
7
+
8
+ <f:name>
9
+ <language>pol</language>
10
+ <f:value>Żelazowa Wola</f:value>
11
+ </f:name>
12
+
13
+ <f:gmina>
14
+ <f:value>
15
+ <f:entity xlink:href="sochaczew"/>
16
+ </f:value>
17
+ </f:gmina>
18
+ </f:entity>
19
+ <!-- This is free software released into the public domain (CC0 license). -->
@@ -0,0 +1,19 @@
1
+ <f:entity type="place" xml:id="zelazowa-wola" xmlns:f='http://svario.it/factoid'
2
+ xmlns:xlink="http://www.w3.org/1999/xlink"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema-datatypes">
4
+ <f:sources>
5
+ <f:source xml:id="wp" xlink:href="http://en.wikipedia.org/wiki/Żelazowa_Wola" default="true"/>
6
+ </f:sources>
7
+
8
+ <f:name>
9
+ <language>pol</language>
10
+ <f:value>Żelazowa Wola</f:value>
11
+ </f:name>
12
+
13
+ <f:gmina>
14
+ <f:value>
15
+ <f:entity xlink:href="sochaczew"/>
16
+ </f:value>
17
+ </f:gmina>
18
+ </f:entity>
19
+ <!-- This is free software released into the public domain (CC0 license). -->
@@ -0,0 +1,3 @@
1
+ # This is free software released into the public domain (CC0 license).
2
+
3
+
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: factoid
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Gioele Barabucci
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - gioele@svario.it
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - COPYING
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - factoid.gemspec
97
+ - lib/factoid.rb
98
+ - lib/factoid/entitoid.rb
99
+ - lib/factoid/entitoid_ref.rb
100
+ - lib/factoid/factoid.rb
101
+ - lib/factoid/source.rb
102
+ - lib/factoid/value.rb
103
+ - lib/factoid/version.rb
104
+ - lib/factoid/xml.rb
105
+ - spec/factoid/entitoid_spec.rb
106
+ - spec/factoid/factoid_spec.rb
107
+ - spec/fixtures/chopin.xml
108
+ - spec/fixtures/zelazowa-wola
109
+ - spec/fixtures/zelazowa-wola.xml
110
+ - spec/spec_helpers.rb
111
+ homepage: http://svario.it/factoid/ruby
112
+ licenses:
113
+ - CC0
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.0.4
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: factoid is a Ruby library to manipulate factoids entitoids inside Ruby applications
135
+ without touching the their XML representations.
136
+ test_files:
137
+ - spec/factoid/entitoid_spec.rb
138
+ - spec/factoid/factoid_spec.rb
139
+ - spec/fixtures/chopin.xml
140
+ - spec/fixtures/zelazowa-wola
141
+ - spec/fixtures/zelazowa-wola.xml
142
+ - spec/spec_helpers.rb