Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/improved prefix handling #262

Merged
merged 3 commits into from
Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion addon/model/model-range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ export default class ModelRange {
),
] as ModelText[];
if (nodes.length) {
console.log(nodes);
let result = nodes[0].marks.clone();
for (const node of nodes.slice(1)) {
result = result.intersection(node.marks);
Expand Down
21 changes: 21 additions & 0 deletions addon/model/util/datastore/datastore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ export default interface Datastore {
action: (dataset: RDF.Dataset, termconverter: TermConverter) => RDF.Dataset
): Datastore;

/** Transformer method.
* Allows specifying of custom prefixes for use in the {@link match} method
* and the termConverter in the {@link transformDataset} method,
* or overwrite the ones that were scanned from the document.
*
* Reminder: only has an effect on the convenience "concise term syntax".
* Has no effect on the actual rdfa parsing.
*/
withExtraPrefixes(prefixes: Record<string, string>): this;

/**
* Consumer method.
* Returns a {@link TermMapping} of the currently valid subjects and the nodes that define them.
Expand Down Expand Up @@ -229,8 +239,12 @@ export class EditorStore implements Datastore {
predicateToNodesMapping,
nodeToPredicatesMapping,
quadToNodesMapping,
seenPrefixes,
} = RdfaParser.parse(config);
const prefixMap = new Map<string, string>(Object.entries(defaultPrefixes));
for (const [key, value] of seenPrefixes.entries()) {
prefixMap.set(key, value);
}

return new EditorStore({
dataset,
Expand Down Expand Up @@ -301,6 +315,13 @@ export class EditorStore implements Datastore {
});
}

withExtraPrefixes(prefixes: Record<string, string>): this {
for (const [key, value] of Object.entries(prefixes)) {
this._prefixMapping.set(key, value);
}
return this;
}

asSubjectNodeMapping(): TermMapping<RDF.Quad_Subject> {
return new TermMapping<RDF.Quad_Subject>(
this.subjectNodeGenerator(),
Expand Down
7 changes: 6 additions & 1 deletion addon/utils/rdfa-parser/rdfa-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface RdfaParseResponse {
predicateToNodesMapping: Map<string, ModelNode[]>;

quadToNodesMapping: Map<string, QuadNodes>;
seenPrefixes: Map<string, string>;
}

export class RdfaParser {
Expand Down Expand Up @@ -97,6 +98,7 @@ export class RdfaParser {

private rootModelNode?: ModelNode;
private seenNodes: Map<RDF.Term, ModelNode>;
private globallySeenPrefixes: Map<string, string>;

constructor(options: IRdfaParserOptions) {
this.options = options;
Expand All @@ -113,6 +115,7 @@ export class RdfaParser {
this.rdfaPatterns = {};
this.pendingRdfaPatternCopies = {};
this.resultSet = new GraphyDataset();
this.globallySeenPrefixes = new Map<string, string>();

this.nodeToSubjectMapping = new Map<ModelNode, ModelQuadSubject>();
this.subjectToNodesMapping = new Map<string, ModelNode[]>();
Expand Down Expand Up @@ -186,6 +189,7 @@ export class RdfaParser {
nodeToObjectsMapping: parser.nodeToObjectsMapping,
objectToNodesMapping: parser.objectToNodesMapping,
quadToNodesMapping: parser.quadToNodesMapping,
seenPrefixes: parser.globallySeenPrefixes,
};
}

Expand Down Expand Up @@ -386,7 +390,8 @@ export class RdfaParser {
activeTag.prefixesCustom = Util.parsePrefixes(
attributes,
parentTag.prefixesCustom,
this.features.xmlnsPrefixMappings
this.features.xmlnsPrefixMappings,
this.globallySeenPrefixes
);
activeTag.prefixesAll =
Object.keys(activeTag.prefixesCustom).length > 0
Expand Down
15 changes: 14 additions & 1 deletion addon/utils/rdfa-parser/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,14 @@ export class Util {
* @param {{[p: string]: string}} attributes A tag's attributes.
* @param {{[p: string]: string}} parentPrefixes The prefixes from the parent tag.
* @param {boolean} xmlnsPrefixMappings If prefixes should be extracted from xmlnsPrefixMappings.
* @param globallySeenPrefixes Optionally keep track of all encountered prefixes
* @return {{[p: string]: string}} The new prefixes.
*/
public static parsePrefixes(
attributes: { [s: string]: string },
parentPrefixes: { [prefix: string]: string },
xmlnsPrefixMappings = false
xmlnsPrefixMappings = false,
globallySeenPrefixes?: Map<string, string>
): { [prefix: string]: string } {
const additionalPrefixes: { [prefix: string]: string } = {};
if (xmlnsPrefixMappings) {
Expand All @@ -137,6 +139,17 @@ export class Util {
let prefixMatch = Util.PREFIX_REGEX.exec(attributes.prefix);
while (prefixMatch) {
prefixes[prefixMatch[1]] = prefixMatch[2];
if (globallySeenPrefixes) {
const key = prefixMatch[1];
const uri = prefixMatch[2];
const previousUri = globallySeenPrefixes.get(key);
if (previousUri && uri !== previousUri) {
console.warn(`Prefix ${key} is defined multiple times with a different uri.
Previous uri was ${previousUri}, now found ${uri}.
Will use latest value in concise-term-mapping logic`);
}
globallySeenPrefixes.set(key, uri);
}
prefixMatch = Util.PREFIX_REGEX.exec(attributes.prefix);
}
}
Expand Down