Skip to content

Commit

Permalink
Support spec series and retrieve them for W3C specs (#851)
Browse files Browse the repository at this point in the history
This adds support for specification series, as discussed in #811. Actual
changes to the core logic are minimal and should be fully transparent for
consumers: a new `isSeriesAlias` boolean flag can now be added to an alias to
signal that it is a "series alias". This alias gets processed by bibref exactly
as any other alias, except that bibref does not create version entries when the
flag is set.

In other words, given:

```
{
  "css-fonts": {
    "aliasOf": "css-fonts-4",
    "isSeriesAlias": true
  }
}
```

`css-fonts` can then be used to reference `css-fonts-4` but, as opposed to
a regular alias, `css-fonts-20240201` cannot be used to reference
`css-fonts-4-20240201`. This is on purpose as it allows to update `css-fonts`
later on to target `css-fonts-5` when it becomes the "current" specification.

The W3C script now leverages the W3C API to retrieve the list of specification
series and create series aliases when needed and possible.

Consumers won't even know that they are dealing with a series, but it's not
clear that they need to know in any case, and we can make that more explicit
later on if needed.

Fixes #811.
  • Loading branch information
tidoust authored Jan 28, 2025
1 parent 61f0e6c commit 2eacc25
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 1 deletion.
3 changes: 3 additions & 0 deletions lib/bibref.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ function expandRefs(refs) {
});
if (ref.aliases) {
ref.aliases.forEach(function(aliasKey) {
if (refs[aliasKey].isSeriesAlias) {
return;
}
Object.keys(versions).forEach(function(subKey) {
// Watch out not to overwrite existing aliases.
if (!refs[aliasKey + '-' + subKey]) {
Expand Down
4 changes: 4 additions & 0 deletions schemas/raw-reference.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@
"aliasOf": {
"description": "ID of the aliased reference. Note aliasing can be recursive.",
"$ref": "#/definitions/id"
},
"isSeriesAlias": {
"description": "Whether the alias is for the name of a specification series.",
"type": "boolean"
}
},
"required": ["aliasOf"],
Expand Down
49 changes: 49 additions & 0 deletions scripts/w3c.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,55 @@ async function updateW3CRefs(sinceDate, verbose, filter) {
}
}

// Time to look at specification series and create custom aliases for them
// Note: the W3C API gives us the API url of the current specification in a
// series, which we need to map to an actual spec entry in the list. That
// mapping gets recorded through the "source" property. In particular, we
// cannot build that mapping while we process the specs above because the
// script typically runs in incremental mode and does not load the entire
// list of specs from the W3C API.
console.log("Updating specification series aliases...");
const source2Entry = {};
for (const [shortname, entry] of Object.entries(current)) {
source2Entry[entry.source] = shortname;
}
const specSeries = await fetchW3CPages('specification-series', 'specification-series', true);
for (const series of specSeries) {
// Look for the current specification in the list.
const currUrl = series._links['current-specification'].href;
const currShortname = source2Entry[currUrl];
if (!currShortname) {
continue;
}

// Make sure we can create an alias for the series
let entry = current[series.shortname];
if (entry) {
if (entry.aliasOf && entry.isSeriesAlias) {
// Make sure alias targets the right spec
entry.aliasOf = currShortname;
continue;
}
else {
// Many specs don't use levels. In such a case, the name of the
// series matches that of the specification, which should
// already be in the list.
continue;
}
}
else if (series.shortname in bibref.get(series.shortname)) {
console.warn(`- ${series.shortname}: series shortname already in another source in Specref`);
continue;
}

// Create an alias
entry = {
aliasOf: currShortname,
isSeriesAlias: true
};
current[series.shortname] = entry;
}

console.log("Sorting references...");
const sorted = helper.sortRefs(current);

Expand Down
8 changes: 7 additions & 1 deletion test/bibref.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ suite('Test bibref api', function() {
},
foo: { aliasOf: "FOO" },
bar: { aliasOf: "fOO" },
hello: { title: "HELLO" }
hello: { title: "HELLO" },
series: { aliasOf: "FOO", isSeriesAlias: true }
};

test('bibref constructor handles a single reference obj', function() {
Expand Down Expand Up @@ -56,6 +57,11 @@ suite('Test bibref api', function() {
assert.equal("FOO title", expanded["FOO-BAZ"].title);
});

test('bibref.expandRefs does not create versions for series aliases', function() {
var b = bibref.create(obj);
assert.ok(!('FOO' in b.get("series-BAR")), "Cannot access a spec version from a series alias.");
});

test('bibref.cleanupRefs modifies the refs correctly', function() {
var cleaned = bibref.cleanupRefs({
foo: {
Expand Down

0 comments on commit 2eacc25

Please sign in to comment.