sxp 0.0.14 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -1
- data/README +8 -8
- data/VERSION +1 -1
- data/lib/sxp.rb +16 -2
- data/lib/sxp/generator.rb +111 -52
- data/lib/sxp/reader.rb +10 -5
- data/lib/sxp/reader/sparql.rb +2 -7
- data/lib/sxp/version.rb +2 -4
- metadata +62 -76
data/AUTHORS
CHANGED
@@ -1 +1 @@
|
|
1
|
-
* Arto Bendiken <arto
|
1
|
+
* Arto Bendiken <arto@bendiken.net>
|
data/README
CHANGED
@@ -1,21 +1,18 @@
|
|
1
|
-
SXP.rb: S-Expressions for Ruby
|
2
|
-
==============================
|
1
|
+
#SXP.rb: S-Expressions for Ruby
|
3
2
|
|
4
3
|
This is a Ruby implementation of a universal [S-expression][] parser.
|
5
4
|
|
6
5
|
* <http://sxp.rubyforge.org/>
|
7
6
|
* <http://github.com/bendiken/sxp-ruby>
|
8
7
|
|
9
|
-
Features
|
10
|
-
--------
|
8
|
+
##Features
|
11
9
|
|
12
10
|
* Parses S-expressions in universal, [Scheme][], [Common Lisp][], or
|
13
11
|
[SPARQL][] syntax.
|
14
12
|
* Adds a `#to_sxp` method to Ruby objects.
|
15
13
|
* Compatible with Ruby 1.8.7+, Ruby 1.9.x, and JRuby 1.4/1.5.
|
16
14
|
|
17
|
-
Examples
|
18
|
-
--------
|
15
|
+
##Examples
|
19
16
|
|
20
17
|
require 'sxp'
|
21
18
|
|
@@ -49,8 +46,11 @@ Examples
|
|
49
46
|
|
50
47
|
SXP::Reader::SPARQL.read %q((base <http://ar.to/>)) #=> [:base, RDF::URI('http://ar.to/')]
|
51
48
|
|
52
|
-
|
53
|
-
|
49
|
+
### Writing an SXP with formatting
|
50
|
+
|
51
|
+
SXP::Generator.print([:and, true, false]) #=> (and #t #f)
|
52
|
+
|
53
|
+
##Documentation
|
54
54
|
|
55
55
|
* <http://sxp.rubyforge.org/>
|
56
56
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/sxp.rb
CHANGED
@@ -39,8 +39,13 @@ module SXP
|
|
39
39
|
##
|
40
40
|
# Reads all S-expressions from the given input files.
|
41
41
|
#
|
42
|
-
# @
|
43
|
-
#
|
42
|
+
# @overload read_files(*filenames)
|
43
|
+
# @param [Enumerable<String>] filenames
|
44
|
+
#
|
45
|
+
# @overload read_files(*filenames, options)
|
46
|
+
# @param [Enumerable<String>] filenames
|
47
|
+
# @param [Hash{Symbol => Object}] options
|
48
|
+
#
|
44
49
|
# @return [Enumerable<Object>]
|
45
50
|
def self.read_files(*filenames)
|
46
51
|
Reader::Scheme.read_files(*filenames)
|
@@ -75,6 +80,15 @@ module SXP
|
|
75
80
|
def self.read(input, options = {})
|
76
81
|
Reader::Scheme.read(input, options)
|
77
82
|
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Write an internal S-Expression as a formatted SXP
|
86
|
+
#
|
87
|
+
# @param[Array<Object>] sxp
|
88
|
+
# @param[#write] output
|
89
|
+
def self.write(sxp, output = STDOUT)
|
90
|
+
Generator.write(output, sxp)
|
91
|
+
end
|
78
92
|
|
79
93
|
class << self
|
80
94
|
alias_method :parse, :read
|
data/lib/sxp/generator.rb
CHANGED
@@ -1,16 +1,102 @@
|
|
1
1
|
module SXP
|
2
2
|
##
|
3
3
|
# An S-expression generator.
|
4
|
+
#
|
5
|
+
# Takes an object and pretty-prints it using reasonable indentation rules
|
4
6
|
class Generator
|
5
7
|
##
|
8
|
+
# A basic block containing constituent
|
9
|
+
# objects, either blocks or strings.
|
10
|
+
class Block
|
11
|
+
BLOCK_MIN_LENGTH = 40
|
12
|
+
|
13
|
+
# @attr [Integer] amount of indent applied to this block
|
14
|
+
attr_reader :indent
|
15
|
+
|
16
|
+
##
|
17
|
+
# @param [Object] obj
|
18
|
+
def initialize(obj, indent)
|
19
|
+
@indent = indent
|
20
|
+
@elements = []
|
21
|
+
if obj.is_a?(Array)
|
22
|
+
obj.compact.each {|o| @elements << Block.new(o, indent + 1)}
|
23
|
+
else
|
24
|
+
@elements = obj
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Agregate length over each element accounting for spaces
|
30
|
+
#
|
31
|
+
# @return [Integer]
|
32
|
+
# If indent is not not nil, returns zero
|
33
|
+
def length
|
34
|
+
if @elements.is_a?(Array)
|
35
|
+
@elements.map(&:length).inject(:+).to_i + @elements.length - 1
|
36
|
+
else
|
37
|
+
@elements.to_sxp.length
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Turn block into a string in S-expression form
|
43
|
+
# This should only be called on a block when
|
44
|
+
# no indentation is to be applied
|
45
|
+
# @return [String]
|
46
|
+
def to_sxp
|
47
|
+
@elements.to_sxp
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Determins if this block is an SXP, or not
|
52
|
+
# @return [Boolean]
|
53
|
+
def sxp?
|
54
|
+
@elements.is_a?(Array)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Output block applying indent recursively
|
59
|
+
# @param [#write] io
|
60
|
+
def write(io)
|
61
|
+
# Output individual block elements on separate lines
|
62
|
+
if sxp? && length > BLOCK_MIN_LENGTH
|
63
|
+
io.write(do_indent + '(')
|
64
|
+
first, *elems = @elements
|
65
|
+
unless first.sxp?
|
66
|
+
# It's atomic, write out after paren
|
67
|
+
io.puts(first.to_sxp)
|
68
|
+
else
|
69
|
+
io.write("\n")
|
70
|
+
elems.unshift(first)
|
71
|
+
end
|
72
|
+
elems.each do |e|
|
73
|
+
e.write(io)
|
74
|
+
end
|
75
|
+
io.puts(do_indent + ")\n")
|
76
|
+
else
|
77
|
+
io.puts(do_indent + @elements.to_sxp)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def do_indent(offset = 0); ' ' * (indent + offset); end
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Format S-expressions to a String
|
87
|
+
#
|
6
88
|
# @param [Array] sxps
|
7
89
|
# @return [Object]
|
8
90
|
def self.string(*sxps)
|
9
91
|
require 'stringio' unless defined?(StringIO)
|
10
|
-
|
92
|
+
buf = StringIO.new
|
93
|
+
write(buf, *sxps)
|
94
|
+
buf.string
|
11
95
|
end
|
12
96
|
|
13
97
|
##
|
98
|
+
# Format S-expressions to STDOUT
|
99
|
+
#
|
14
100
|
# @param [Array] sxps
|
15
101
|
# @return [Object]
|
16
102
|
def self.print(*sxps)
|
@@ -18,73 +104,46 @@ module SXP
|
|
18
104
|
end
|
19
105
|
|
20
106
|
##
|
107
|
+
# Write formatted S-expressions to an IO like object
|
108
|
+
#
|
21
109
|
# @param [Object] out
|
22
110
|
# @param [Array] sxps
|
23
111
|
# @return [Object]
|
24
112
|
def self.write(out, *sxps)
|
25
113
|
generator = self.new(out)
|
26
114
|
sxps.each do |sxp|
|
27
|
-
generator.
|
115
|
+
generator.render(sxp)
|
28
116
|
end
|
29
117
|
generator
|
30
118
|
end
|
31
119
|
|
32
120
|
##
|
33
|
-
#
|
121
|
+
# Initialize output with a stack of IO buffers
|
122
|
+
#
|
123
|
+
# @param [#write] buffer
|
34
124
|
def initialize(buffer)
|
35
|
-
@output =
|
36
|
-
@indent = 0
|
37
|
-
end
|
38
|
-
|
39
|
-
protected
|
40
|
-
|
41
|
-
##
|
42
|
-
# @param [String] text
|
43
|
-
# @param [Hash{Symbol => Object}] options
|
44
|
-
# @return [void]
|
45
|
-
def emit(text, options = {})
|
46
|
-
if out = @output.last
|
47
|
-
out.print(' ' * (indent * 2)) if options[:indent]
|
48
|
-
out.print(text)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
##
|
53
|
-
# @yield
|
54
|
-
# @return [String]
|
55
|
-
def captured(&block)
|
56
|
-
require 'stringio' unless defined?(StringIO)
|
57
|
-
begin
|
58
|
-
@output.push(buffer = StringIO.new)
|
59
|
-
block.call
|
60
|
-
ensure
|
61
|
-
@output.pop
|
62
|
-
end
|
63
|
-
buffer.string
|
125
|
+
@output = buffer
|
64
126
|
end
|
65
127
|
|
66
128
|
##
|
67
|
-
#
|
68
|
-
#
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
129
|
+
# Render an element.
|
130
|
+
# For Array, this recursively renders each constituent into blocks.
|
131
|
+
# If the agregate length of a block is less than MIN_BLOCK characters,
|
132
|
+
# combine each constituent block into a single line.
|
133
|
+
#
|
134
|
+
# Rendering does not perform final formatting, but returns a recursive
|
135
|
+
# array of blocks which are each ultimattely formattted onto their
|
136
|
+
# own line with leading whitespace.
|
137
|
+
#
|
138
|
+
# @param [Object] sexp
|
139
|
+
# @return [Block]
|
140
|
+
def render(sexp)
|
141
|
+
block = Block.new(sexp, 0)
|
142
|
+
if block.length > 40
|
143
|
+
block.write(@output)
|
144
|
+
else
|
145
|
+
@output.puts(block.to_sxp)
|
75
146
|
end
|
76
147
|
end
|
77
|
-
|
78
|
-
##
|
79
|
-
# @return [void]
|
80
|
-
def increase_indent!
|
81
|
-
@indent += 1
|
82
|
-
end
|
83
|
-
|
84
|
-
##
|
85
|
-
# @return [void]
|
86
|
-
def decrease_indent!
|
87
|
-
@indent -= 1
|
88
|
-
end
|
89
148
|
end # Generator
|
90
149
|
end # SXP
|
data/lib/sxp/reader.rb
CHANGED
@@ -22,16 +22,21 @@ module SXP
|
|
22
22
|
# @return [Enumerable<Object>]
|
23
23
|
def self.read_url(url, options = {})
|
24
24
|
require 'open-uri'
|
25
|
-
open(url.to_s, 'rb', nil, options) { |io| read_all(io, options) }
|
25
|
+
open(url.to_s, 'rb', nil, options) { |io| read_all(io, options).first }
|
26
26
|
end
|
27
27
|
|
28
28
|
##
|
29
29
|
# Reads all S-expressions from the given input files.
|
30
30
|
#
|
31
|
-
# @
|
32
|
-
#
|
31
|
+
# @overload read_files(*filenames)
|
32
|
+
# @param [Enumerable<String>] filenames
|
33
|
+
#
|
34
|
+
# @overload read_files(*filenames, options)
|
35
|
+
# @param [Enumerable<String>] filenames
|
36
|
+
# @param [Hash{Symbol => Object}] options
|
37
|
+
#
|
33
38
|
# @return [Enumerable<Object>]
|
34
|
-
def
|
39
|
+
def read_files(*filenames)
|
35
40
|
options = filenames.last.is_a?(Hash) ? filenames.pop : {}
|
36
41
|
filenames.map { |filename| read_file(filename, options) }.inject { |sxps, sxp| sxps + sxp }
|
37
42
|
end
|
@@ -43,7 +48,7 @@ module SXP
|
|
43
48
|
# @param [Hash{Symbol => Object}] options
|
44
49
|
# @return [Enumerable<Object>]
|
45
50
|
def self.read_file(filename, options = {})
|
46
|
-
File.open(filename.to_s, 'rb') { |io| read_all(io, options) }
|
51
|
+
File.open(filename.to_s, 'rb') { |io| read_all(io, options).first }
|
47
52
|
end
|
48
53
|
|
49
54
|
##
|
data/lib/sxp/reader/sparql.rb
CHANGED
@@ -55,13 +55,8 @@ module SXP; class Reader
|
|
55
55
|
# @example Returning a URI prefix
|
56
56
|
# parser.prefix(:dc) #=> RDF::URI('http://purl.org/dc/terms/')
|
57
57
|
#
|
58
|
-
# @
|
59
|
-
#
|
60
|
-
# @param [RDF::URI, #to_s] uri
|
61
|
-
#
|
62
|
-
# @overload prefix(name)
|
63
|
-
# @param [Symbol, #to_s] name
|
64
|
-
#
|
58
|
+
# @param [Symbol, #to_s] name
|
59
|
+
# @param [RDF::URI, #to_s] uri
|
65
60
|
# @return [RDF::URI]
|
66
61
|
def prefix(name, uri = nil)
|
67
62
|
name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym)
|
data/lib/sxp/version.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module SXP
|
2
2
|
module VERSION
|
3
|
-
|
4
|
-
MINOR =
|
5
|
-
TINY = 14
|
6
|
-
EXTRA = nil
|
3
|
+
VERSION_FILE = File.expand_path("../../../VERSION", __FILE__)
|
4
|
+
MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chop.split(".")
|
7
5
|
|
8
6
|
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
|
9
7
|
|
metadata
CHANGED
@@ -1,79 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sxp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 14
|
9
|
-
version: 0.0.14
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Arto Bendiken
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-11-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: json
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 1
|
30
|
-
- 5
|
31
|
-
- 1
|
32
|
-
version: 1.5.1
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.4.6
|
33
22
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: yard
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
25
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
45
|
-
- 6
|
46
|
-
- 4
|
47
|
-
version: 0.6.4
|
48
|
-
type: :development
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.6
|
30
|
+
- !ruby/object:Gem::Dependency
|
51
31
|
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.12.0
|
38
|
+
type: :development
|
52
39
|
prerelease: false
|
53
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
41
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.12.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.8.3
|
63
54
|
type: :development
|
64
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.3
|
65
62
|
description: A pure-Ruby implementation of a universal S-expression parser.
|
66
|
-
email: arto
|
67
|
-
executables:
|
63
|
+
email: arto@bendiken.net
|
64
|
+
executables:
|
68
65
|
- sxp2rdf
|
69
66
|
- sxp2json
|
70
67
|
- sxp2xml
|
71
68
|
- sxp2yaml
|
72
69
|
extensions: []
|
73
|
-
|
74
70
|
extra_rdoc_files: []
|
75
|
-
|
76
|
-
files:
|
71
|
+
files:
|
77
72
|
- AUTHORS
|
78
73
|
- CREDITS
|
79
74
|
- README
|
@@ -96,39 +91,30 @@ files:
|
|
96
91
|
- bin/sxp2json
|
97
92
|
- bin/sxp2xml
|
98
93
|
- bin/sxp2yaml
|
99
|
-
has_rdoc: false
|
100
94
|
homepage: http://sxp.rubyforge.org/
|
101
|
-
licenses:
|
95
|
+
licenses:
|
102
96
|
- Public Domain
|
103
97
|
post_install_message:
|
104
98
|
rdoc_options: []
|
105
|
-
|
106
|
-
require_paths:
|
99
|
+
require_paths:
|
107
100
|
- lib
|
108
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
102
|
none: false
|
110
|
-
requirements:
|
111
|
-
- -
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
segments:
|
114
|
-
- 1
|
115
|
-
- 8
|
116
|
-
- 1
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
117
106
|
version: 1.8.1
|
118
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
108
|
none: false
|
120
|
-
requirements:
|
121
|
-
- -
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
|
124
|
-
- 0
|
125
|
-
version: "0"
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
126
113
|
requirements: []
|
127
|
-
|
128
114
|
rubyforge_project: sxp
|
129
|
-
rubygems_version: 1.
|
115
|
+
rubygems_version: 1.8.24
|
130
116
|
signing_key:
|
131
117
|
specification_version: 3
|
132
118
|
summary: A pure-Ruby implementation of a universal S-expression parser.
|
133
119
|
test_files: []
|
134
|
-
|
120
|
+
has_rdoc: false
|