Comparing version 1.0.0-beta.1 to 1.0.0-beta.2
@@ -232,3 +232,3 @@ // N3.js implementations of the RDF/JS core data types | ||
if (!(this instanceof Quad)) | ||
return new Quad(); | ||
return new Quad(subject, predicate, object, graph); | ||
this.subject = subject; | ||
@@ -235,0 +235,0 @@ this.predicate = predicate; |
@@ -54,5 +54,8 @@ // **N3Lexer** tokenizes N3 documents. | ||
_unescapedIri: /^<([^\x00-\x20<>\\"\{\}\|\^\`]*)>[ \t]*/, // IRI without escape sequences; no unescaping | ||
_unescapedString: /^"([^"\\\r\n]+)"/, // non-empty string without escape sequences | ||
_singleQuotedString: /^"((?:[^"\\\r\n]|\\.)*)"(?=[^"])|^'((?:[^'\\\r\n]|\\.)*)'(?=[^'])/, | ||
_tripleQuotedString: /^"""([^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*)"""|^'''([^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*)'''/, | ||
_unescapedQuote: /^"([^"\\\r\n]+)"/, // non-empty string without escape sequences | ||
_unescapedApos: /^'([^'\\\r\n]+)'/, | ||
_singleQuote: /^"((?:[^"\\\r\n]|\\.)*)"(?=[^"])/, | ||
_singleApos: /^'((?:[^'\\\r\n]|\\.)*)'(?=[^'])/, | ||
_tripleQuote: /^"""([^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*)"""/, | ||
_tripleApos: /^'''([^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*)'''/, | ||
_langcode: /^@([a-z]+(?:-[a-z0-9]+)*)(?=[^a-z0-9\-])/i, | ||
@@ -159,18 +162,43 @@ _prefix: /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:(?=[#\s<])/, | ||
case '"': | ||
// Try to find a literal without escape sequences | ||
if (match = this._unescapedQuote.exec(input)) | ||
value = match[1]; | ||
// Before attempting more complex string patterns, try to detect a closing quote | ||
else if (input.indexOf('"', 1) > 0) { | ||
// Try to find any other literal wrapped in a pair of quotes | ||
if (match = this._singleQuote.exec(input)) | ||
value = this._unescape(match[1]); | ||
// Try to find a literal wrapped in three pairs of quotes | ||
else if (match = this._tripleQuote.exec(input)) { | ||
value = match[1]; | ||
// Advance line counter | ||
this._line += value.split(/\r\n|\r|\n/).length - 1; | ||
value = this._unescape(value); | ||
} | ||
if (value === null) | ||
return reportSyntaxError(this); | ||
} | ||
if (match !== null) | ||
type = 'literal'; | ||
break; | ||
case "'": | ||
// Try to find a non-empty double-quoted literal without escape sequences | ||
if (match = this._unescapedString.exec(input)) | ||
// Try to find a literal without escape sequences | ||
if (match = this._unescapedApos.exec(input)) | ||
value = match[1]; | ||
// Try to find any other literal wrapped in a pair of single or double quotes | ||
else if (match = this._singleQuotedString.exec(input)) | ||
value = this._unescape(typeof match[1] === 'string' ? match[1] : match[2]); | ||
// Try to find a literal wrapped in three pairs of single or double quotes | ||
else if (match = this._tripleQuotedString.exec(input)) { | ||
value = typeof match[1] === 'string' ? match[1] : match[2]; | ||
// Advance line counter | ||
this._line += value.split(/\r\n|\r|\n/).length - 1; | ||
value = this._unescape(value); | ||
// Before attempting more complex string patterns, try to detect a closing apostrophe | ||
else if (input.indexOf("'", 1) > 0) { | ||
// Try to find any other literal wrapped in a pair of apostrophes | ||
if (match = this._singleApos.exec(input)) | ||
value = this._unescape(match[1]); | ||
// Try to find a literal wrapped in three pairs of apostrophes | ||
else if (match = this._tripleApos.exec(input)) { | ||
value = match[1]; | ||
// Advance line counter | ||
this._line += value.split(/\r\n|\r|\n/).length - 1; | ||
value = this._unescape(value); | ||
} | ||
if (value === null) | ||
return reportSyntaxError(this); | ||
} | ||
if (value === null) | ||
return reportSyntaxError(this); | ||
if (match !== null) | ||
@@ -177,0 +205,0 @@ type = 'literal'; |
@@ -6,7 +6,2 @@ // **N3Parser** parses N3 documents. | ||
// Regexes for IRIs | ||
var absoluteIRI = /^[a-z][a-z0-9+.-]*:/i, | ||
schemeAuthority = /^(?:([a-z][a-z0-9+.-]*:))?(?:\/\/[^\/]*)?/i, | ||
dotSegments = /(?:^|\/)\.\.?(?:$|[\/#?])/; | ||
// The next ID for new blank nodes | ||
@@ -38,9 +33,4 @@ var blankNodePrefix = 0, blankNodeCount = 0; | ||
// Disable relative IRIs in N-Triples or N-Quads mode | ||
if (isLineMode) { | ||
this._base = ''; | ||
this._resolveIRI = function (token) { | ||
this._error('Disallowed relative IRI', token); | ||
return this._callback = noop, this._subject = null; | ||
}; | ||
} | ||
if (isLineMode) | ||
this._resolveRelativeIRI = function (iri) { return ''; }; | ||
this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : | ||
@@ -81,3 +71,3 @@ options.blankNodePrefix.replace(/^(?!_:)/, '_:'); | ||
baseIRI.replace(/[^\/?]*(?:\?.*)?$/, ''); | ||
baseIRI = baseIRI.match(schemeAuthority); | ||
baseIRI = baseIRI.match(/^(?:([a-z][a-z0-9+.-]*:))?(?:\/\/[^\/]*)?/i); | ||
this._baseRoot = baseIRI[0]; | ||
@@ -169,4 +159,6 @@ this._baseScheme = baseIRI[1]; | ||
case 'typeIRI': | ||
value = this._namedNode(this._base === null || absoluteIRI.test(token.value) ? | ||
token.value : this._resolveIRI(token)); | ||
var iri = this._resolveIRI(token.value); | ||
if (iri === '') | ||
return this._error('Invalid IRI', token); | ||
value = this._namedNode(iri); | ||
break; | ||
@@ -630,6 +622,6 @@ // Read a prefixed name | ||
_readBaseIRI: function (token) { | ||
if (token.type !== 'IRI') | ||
return this._error('Expected IRI to follow base declaration', token); | ||
this._setBase(this._base === null || absoluteIRI.test(token.value) ? | ||
token.value : this._resolveIRI(token)); | ||
var iri = token.type === 'IRI' && this._resolveIRI(token.value); | ||
if (!iri) | ||
return this._error('Expected valid IRI to follow base declaration', token); | ||
this._setBase(iri); | ||
return this._readDeclarationPunctuation; | ||
@@ -817,9 +809,15 @@ }, | ||
// ### `_resolveIRI` resolves a relative IRI token against the base path, | ||
// ### `_resolveIRI` resolves an IRI against the base path | ||
_resolveIRI: function (iri) { | ||
return /^[a-z][a-z0-9+.-]*:/i.test(iri) ? iri : this._resolveRelativeIRI(iri); | ||
}, | ||
// ### `_resolveRelativeIRI` resolves an IRI against the base path, | ||
// assuming that a base path has been set and that the IRI is indeed relative | ||
_resolveIRI: function (token) { | ||
var iri = token.value; | ||
_resolveRelativeIRI: function (iri) { | ||
// An empty relative IRI indicates the base IRI | ||
if (!iri.length) | ||
return this._base; | ||
// Decide resolving strategy based in the first character | ||
switch (iri[0]) { | ||
// An empty relative IRI indicates the base IRI | ||
case undefined: return this._base; | ||
// Resolve relative fragment IRIs against the base IRI | ||
@@ -835,3 +833,4 @@ case '#': return this._base + iri; | ||
default: | ||
return this._removeDotSegments(this._basePath + iri); | ||
// Relative IRIs cannot contain a colon in the first path segment | ||
return (/^[^/:]*:/.test(iri)) ? '' : this._removeDotSegments(this._basePath + iri); | ||
} | ||
@@ -843,3 +842,3 @@ }, | ||
// Don't modify the IRI if it does not contain any dot segments | ||
if (!dotSegments.test(iri)) | ||
if (!/(^|\/)\.\.?($|[/#?])/.test(iri)) | ||
return iri; | ||
@@ -846,0 +845,0 @@ |
{ | ||
"name": "n3", | ||
"version": "1.0.0-beta.1", | ||
"version": "1.0.0-beta.2", | ||
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.", | ||
@@ -28,7 +28,7 @@ "author": "Ruben Verborgh <ruben.verborgh@gmail.com>", | ||
"coveralls": "^3.0.0", | ||
"docco": "^0.7.0", | ||
"docco": "^0.8.0", | ||
"eslint": "^4.1.1", | ||
"follow-redirects": "^1.4.1", | ||
"mocha": "^5.0.1", | ||
"nyc": "^11.0.3", | ||
"nyc": "^12.0.2", | ||
"pre-commit": "^1.2.2" | ||
@@ -35,0 +35,0 @@ }, |
125679
2686
2