Skip to content

Commit 5950aa3

Browse files
committed
Finish 2.0.0
2 parents 5652c7f + 4efcf92 commit 5950aa3

File tree

8 files changed

+51
-12
lines changed

8 files changed

+51
-12
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ S-Expressions derive from LISP, and include some basic datatypes common to all v
2525
<dt>Symbols</dt>
2626
<dd>Of the form <code>with-hyphen ?@!$ a\ symbol\ with\ spaces</code></dd>
2727
<dt>Strings</dt>
28-
<dd>Of the form <code>"Hello, world!"</code><br/>
28+
<dd>Of the form <code>"Hello, world!"</code> or <code>'Hello, world!'</code><br/>
2929
Strings may include the following special characters:
3030
<ul>
3131
<li><code>\b</code> &mdash; Backspace</li>
@@ -36,6 +36,7 @@ S-Expressions derive from LISP, and include some basic datatypes common to all v
3636
<li><code>\u<i>xxxx</i></code> &mdash; 2-byte Unicode character escape</li>
3737
<li><code>\U<i>xxxxxxxx</i></code> &mdash; 4-byte Unicode character escape</li>
3838
<li><code>\"</code> &mdash; Double-quote character</li>
39+
<li><code>\'</code> &mdash; Single-quote character</li>
3940
<li><code>\\</code> &mdash; Backspace</li>
4041
</ul>
4142
Additionally, any other character may follow <code>\</code>, representing the character itself.
@@ -124,6 +125,7 @@ In addition to the standard datatypes, the SPARQL dialect supports the following
124125
<dd>Strings are interpreted as an RDF Literal with datatype <code>xsd:string</code>. It can be followed by <code>@<i>lang</i></code> to create a language-tagged string, or <code>^^<i>IRI</i></code> to create a datatyped-literal. Examples:
125126
<ul>
126127
<li><code>"a plain literal"</code></li>
128+
<li><code>'another plain literal'</code></li>
127129
<li><code>"a literal with a language"@en</code></li>
128130
<li><code>"a typed literal"^^&lt;http://example/></code></li>
129131
<li><code>"a typed literal with a PNAME"^^xsd:string</code></li>
@@ -252,6 +254,10 @@ as follows:
252254
* <https://github.com/dryruby/sxp.rb>
253255
* <https://rubygems.org/gems/sxp.rb>
254256

257+
## Change Log
258+
259+
See [Release Notes on GitHub](https://github.com/dryruby/sxp.rb/releases)
260+
255261
## Authors
256262

257263
* [Arto Bendiken](https://github.com/artob) - <https://ar.to/>
@@ -262,6 +268,7 @@ as follows:
262268
* [Ben Lavender](https://github.com/bhuga) - <https://bhuga.net/>
263269

264270
## Contributing
271+
265272
This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.
266273

267274
* Do your best to adhere to the existing coding conventions and idioms.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.0
1+
2.0.0

lib/sxp/extensions.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def to_sxp(**options)
5656
class String
5757
##
5858
# Returns the SXP representation of this object. Uses SPARQL-like escaping.
59+
# Uses any recorded quote style from an originally parsed string.
5960
#
6061
# @return [String]
6162
def to_sxp(**options)
@@ -69,14 +70,29 @@ def to_sxp(**options)
6970
when (0x0C) then '\f'
7071
when (0x0D) then '\r'
7172
when (0x0E..0x1F) then sprintf("\\u%04X", u.ord)
72-
when (0x22) then '\"'
73+
when (0x22) then as_dquote? ? '\"' : '"'
74+
when (0x27) then as_squote? ? "\'" : "'"
7375
when (0x5C) then '\\\\'
7476
when (0x7F) then sprintf("\\u%04X", u.ord)
7577
else u.chr
7678
end
7779
end
78-
'"' + buffer + '"'
80+
if as_dquote?
81+
'"' + buffer + '"'
82+
else
83+
"'" + buffer + "'"
84+
end
7985
end
86+
87+
# Record quote style used when parsing
88+
# @return [:dquote, :squote]
89+
attr_accessor :quote_style
90+
91+
# Render string using double quotes
92+
def as_squote?; quote_style == :squote; end
93+
94+
# Render string using single quotes
95+
def as_dquote?; quote_style != :squote; end
8096
end
8197

8298
##

lib/sxp/reader/basic.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Basic < Reader
1515
def read_token
1616
case peek_char
1717
when ?(, ?) then [:list, read_char]
18-
when ?" then [:atom, read_string] #"
18+
when ?", ?' then [:atom, read_string] #" or '
1919
else super
2020
end
2121
end
@@ -36,16 +36,18 @@ def read_atom
3636
# @return [String]
3737
def read_string
3838
buffer = ""
39-
skip_char # '"'
40-
until peek_char == ?" #"
39+
quote_char = read_char
40+
until peek_char == quote_char # " or '
4141
buffer <<
4242
case char = read_char
4343
when ?\\ then read_character
4444
else char
4545
end
4646
end
47-
skip_char # '"'
48-
buffer
47+
skip_char # " or '
48+
49+
# Return string, annotating it with the quotation style used
50+
buffer.tap {|s| s.quote_style = (quote_char == '"' ? :dquote : :squote)}
4951
end
5052

5153
##

lib/sxp/reader/common_lisp.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def read_vector
115115
# @return [Array]
116116
def read_quote
117117
skip_char # "'"
118-
[options[:quote] || :quote, read]
118+
[options[:quote] || :quote, read.tap {|s| s.quote_style = :squote if s.is_a?(String)}]
119119
end
120120

121121
##

lib/sxp/reader/sparql.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ def initialize(input, **options, &block)
9494
def read_token
9595
case peek_char
9696
when ?" then [:atom, read_rdf_literal] # "
97+
when ?' then [:atom, read_rdf_literal] # '
9798
when ?< then [:atom, read_rdf_uri]
9899
else
99100
tok = super
@@ -144,6 +145,7 @@ def read_token
144145
#
145146
# @example
146147
# "a plain literal"
148+
# 'another plain literal'
147149
# "a literal with a language"@en
148150
# "a typed literal"^^<http://example/>
149151
# "a typed literal with a PNAME"^^xsd:string

spec/common_lisp_spec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161

6262
context "when reading strings" do
6363
it "reads `\"foo\"` as a string" do
64-
expect(read(%q("foo"))).to eq "foo"
64+
res = read(%q("foo"))
65+
expect(res).to eq "foo"
66+
expect(res.quote_style == :squote)
6567
end
6668
end
6769

spec/reader_spec.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
%q{"\n"} => "\n",
6161
%q{"\r"} => "\r",
6262
%q{"\t"} => "\t",
63+
%q{"\'"} => "\'",
6364
%q{"\u0080"} => "\u0080",
6465
%q("\u07FF") => "\u07FF",
6566
%q("\u0800") => "\u0800",
@@ -75,9 +76,18 @@
7576
%q("\U000FFFFD") => "\u{FFFFD}",
7677
%q("\U00100000") => "\u{100000}",
7778
%q("\U0010FFFD") => "\u{10FFFD}",
79+
80+
%q{'\b'} => "\b",
81+
%q{'\f'} => "\f",
82+
%q{'\n'} => "\n",
83+
%q{'\r'} => "\r",
84+
%q{'\t'} => "\t",
85+
%q{'\''} => "\'",
7886
}.each do |input, output|
7987
it "reads #{input} as #{output.inspect}" do
80-
expect(read(input)).to eq output
88+
res = read(input)
89+
expect(res).to eq output
90+
expect(res.quote_style).to eql (input.start_with?('"') ? :dquote : :squote)
8191
end
8292
end
8393
end

0 commit comments

Comments
 (0)