diff --git a/README.md b/README.md
index c3a9eac..5de12e2 100644
--- a/README.md
+++ b/README.md
@@ -233,6 +233,7 @@ _Non-normative note: this would be represented by an `
` in the html._
interface Paragraph extends Parent {
type: "paragraph"
children: Phrasing[]
+ fragmentIdentifier?: string
}
```
@@ -245,6 +246,7 @@ interface Heading extends Parent {
type: "heading"
children: Text[]
level: "chapter" | "subheading" | "label"
+ fragmentIdentifier?: string
}
```
@@ -304,6 +306,7 @@ interface List extends Parent {
type: "list"
ordered: boolean
children: ListItem[]
+ fragmentIdentifier?: string
}
```
@@ -354,6 +357,7 @@ interface ImageSet extends Node {
type: "image-set"
id: string
external picture: ImageSetPicture
+ fragmentIdentifier?: string
}
```
@@ -512,6 +516,7 @@ interface Flourish extends Node {
description?: string
timestamp?: string
external fallbackImage?: Image
+ fragmentIdentifier?: string
}
```
@@ -521,9 +526,10 @@ interface Flourish extends Node {
```ts
interface BigNumber extends Node {
- type: "big-number"
- number: string
- description: string
+ type: "big-number"
+ number: string
+ description: string
+ fragmentIdentifier?: string
}
```
@@ -536,6 +542,7 @@ interface Video extends Node {
type: "video"
id: string
external title: string
+ fragmentIdentifier?: string
}
```
@@ -551,6 +558,7 @@ TODO: Figure out how Clips work, how they are different?
interface YoutubeVideo extends Node {
type: "youtube-video"
url: string
+ fragmentIdentifier?: string
}
```
@@ -624,6 +632,7 @@ interface Layout extends Parent {
layoutName: "auto" | "card" | "timeline"
layoutWidth: string
children: [Heading, LayoutImage, ...LayoutSlot[]] | [Heading, ...LayoutSlot[]] | LayoutSlot[]
+ fragmentIdentifier?: string
}
```
@@ -658,6 +667,7 @@ interface LayoutImage extends Node {
caption: string
credit: string
external picture: ImageSetPicture
+ fragmentIdentifier?: string
}
```
@@ -715,6 +725,7 @@ interface Table extends Parent {
responsiveStyle: 'overflow' | 'flat' | 'scroll'
children: [TableCaption, TableBody, TableFooter] | [TableCaption, TableBody] | [TableBody, TableFooter] | [TableBody]
columnSettings: TableColumnSettings[]
+ fragmentIdentifier?: string
}
```
@@ -742,6 +753,8 @@ interface CustomCodeComponent extends Node {
external attributesLastModified: string
/** Configuration data to be passed to the component. */
external attributes: CustomCodeComponentAttributes
+ /** Unique fragmentIdentifier to identify the component, for things such as anchor links. */
+ fragmentIdentifier?: string
}
```
diff --git a/content-tree.d.ts b/content-tree.d.ts
index c6c6a3c..82029b7 100644
--- a/content-tree.d.ts
+++ b/content-tree.d.ts
@@ -31,11 +31,13 @@ export declare namespace ContentTree {
interface Paragraph extends Parent {
type: "paragraph";
children: Phrasing[];
+ fragmentIdentifier?: string;
}
interface Heading extends Parent {
type: "heading";
children: Text[];
level: "chapter" | "subheading" | "label";
+ fragmentIdentifier?: string;
}
interface Strong extends Parent {
type: "strong";
@@ -59,6 +61,7 @@ export declare namespace ContentTree {
type: "list";
ordered: boolean;
children: ListItem[];
+ fragmentIdentifier?: string;
}
interface ListItem extends Parent {
type: "list-item";
@@ -77,6 +80,7 @@ export declare namespace ContentTree {
type: "image-set";
id: string;
picture: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type ImageSetPicture = {
layoutWidth: string;
@@ -156,20 +160,24 @@ export declare namespace ContentTree {
description?: string;
timestamp?: string;
fallbackImage?: Image;
+ fragmentIdentifier?: string;
}
interface BigNumber extends Node {
type: "big-number";
number: string;
description: string;
+ fragmentIdentifier?: string;
}
interface Video extends Node {
type: "video";
id: string;
title: string;
+ fragmentIdentifier?: string;
}
interface YoutubeVideo extends Node {
type: "youtube-video";
url: string;
+ fragmentIdentifier?: string;
}
interface ScrollyBlock extends Parent {
type: "scrolly-block";
@@ -203,6 +211,7 @@ export declare namespace ContentTree {
layoutName: "auto" | "card" | "timeline";
layoutWidth: string;
children: [Heading, LayoutImage, ...LayoutSlot[]] | [Heading, ...LayoutSlot[]] | LayoutSlot[];
+ fragmentIdentifier?: string;
}
interface LayoutSlot extends Parent {
type: "layout-slot";
@@ -215,6 +224,7 @@ export declare namespace ContentTree {
caption: string;
credit: string;
picture: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type TableColumnSettings = {
hideOnMobile: boolean;
@@ -251,6 +261,7 @@ export declare namespace ContentTree {
responsiveStyle: 'overflow' | 'flat' | 'scroll';
children: [TableCaption, TableBody, TableFooter] | [TableCaption, TableBody] | [TableBody, TableFooter] | [TableBody];
columnSettings: TableColumnSettings[];
+ fragmentIdentifier?: string;
}
type CustomCodeComponentAttributes = {
[key: string]: string | boolean | undefined;
@@ -270,6 +281,8 @@ export declare namespace ContentTree {
attributesLastModified: string;
/** Configuration data to be passed to the component. */
attributes: CustomCodeComponentAttributes;
+ /** Unique fragmentIdentifier to identify the component, for things such as anchor links. */
+ fragmentIdentifier?: string;
}
namespace full {
type BodyBlock = Paragraph | Heading | ImageSet | Flourish | BigNumber | CustomCodeComponent | Layout | List | Blockquote | Pullquote | ScrollyBlock | ThematicBreak | Table | Recommended | Tweet | Video | YoutubeVideo;
@@ -304,11 +317,13 @@ export declare namespace ContentTree {
interface Paragraph extends Parent {
type: "paragraph";
children: Phrasing[];
+ fragmentIdentifier?: string;
}
interface Heading extends Parent {
type: "heading";
children: Text[];
level: "chapter" | "subheading" | "label";
+ fragmentIdentifier?: string;
}
interface Strong extends Parent {
type: "strong";
@@ -332,6 +347,7 @@ export declare namespace ContentTree {
type: "list";
ordered: boolean;
children: ListItem[];
+ fragmentIdentifier?: string;
}
interface ListItem extends Parent {
type: "list-item";
@@ -350,6 +366,7 @@ export declare namespace ContentTree {
type: "image-set";
id: string;
picture: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type ImageSetPicture = {
layoutWidth: string;
@@ -429,20 +446,24 @@ export declare namespace ContentTree {
description?: string;
timestamp?: string;
fallbackImage?: Image;
+ fragmentIdentifier?: string;
}
interface BigNumber extends Node {
type: "big-number";
number: string;
description: string;
+ fragmentIdentifier?: string;
}
interface Video extends Node {
type: "video";
id: string;
title: string;
+ fragmentIdentifier?: string;
}
interface YoutubeVideo extends Node {
type: "youtube-video";
url: string;
+ fragmentIdentifier?: string;
}
interface ScrollyBlock extends Parent {
type: "scrolly-block";
@@ -476,6 +497,7 @@ export declare namespace ContentTree {
layoutName: "auto" | "card" | "timeline";
layoutWidth: string;
children: [Heading, LayoutImage, ...LayoutSlot[]] | [Heading, ...LayoutSlot[]] | LayoutSlot[];
+ fragmentIdentifier?: string;
}
interface LayoutSlot extends Parent {
type: "layout-slot";
@@ -488,6 +510,7 @@ export declare namespace ContentTree {
caption: string;
credit: string;
picture: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type TableColumnSettings = {
hideOnMobile: boolean;
@@ -524,6 +547,7 @@ export declare namespace ContentTree {
responsiveStyle: 'overflow' | 'flat' | 'scroll';
children: [TableCaption, TableBody, TableFooter] | [TableCaption, TableBody] | [TableBody, TableFooter] | [TableBody];
columnSettings: TableColumnSettings[];
+ fragmentIdentifier?: string;
}
type CustomCodeComponentAttributes = {
[key: string]: string | boolean | undefined;
@@ -543,6 +567,8 @@ export declare namespace ContentTree {
attributesLastModified: string;
/** Configuration data to be passed to the component. */
attributes: CustomCodeComponentAttributes;
+ /** Unique fragmentIdentifier to identify the component, for things such as anchor links. */
+ fragmentIdentifier?: string;
}
}
namespace transit {
@@ -578,11 +604,13 @@ export declare namespace ContentTree {
interface Paragraph extends Parent {
type: "paragraph";
children: Phrasing[];
+ fragmentIdentifier?: string;
}
interface Heading extends Parent {
type: "heading";
children: Text[];
level: "chapter" | "subheading" | "label";
+ fragmentIdentifier?: string;
}
interface Strong extends Parent {
type: "strong";
@@ -606,6 +634,7 @@ export declare namespace ContentTree {
type: "list";
ordered: boolean;
children: ListItem[];
+ fragmentIdentifier?: string;
}
interface ListItem extends Parent {
type: "list-item";
@@ -623,6 +652,7 @@ export declare namespace ContentTree {
interface ImageSet extends Node {
type: "image-set";
id: string;
+ fragmentIdentifier?: string;
}
type ImageSetPicture = {
layoutWidth: string;
@@ -699,19 +729,23 @@ export declare namespace ContentTree {
flourishType: string;
description?: string;
timestamp?: string;
+ fragmentIdentifier?: string;
}
interface BigNumber extends Node {
type: "big-number";
number: string;
description: string;
+ fragmentIdentifier?: string;
}
interface Video extends Node {
type: "video";
id: string;
+ fragmentIdentifier?: string;
}
interface YoutubeVideo extends Node {
type: "youtube-video";
url: string;
+ fragmentIdentifier?: string;
}
interface ScrollyBlock extends Parent {
type: "scrolly-block";
@@ -744,6 +778,7 @@ export declare namespace ContentTree {
layoutName: "auto" | "card" | "timeline";
layoutWidth: string;
children: [Heading, LayoutImage, ...LayoutSlot[]] | [Heading, ...LayoutSlot[]] | LayoutSlot[];
+ fragmentIdentifier?: string;
}
interface LayoutSlot extends Parent {
type: "layout-slot";
@@ -755,6 +790,7 @@ export declare namespace ContentTree {
alt: string;
caption: string;
credit: string;
+ fragmentIdentifier?: string;
}
type TableColumnSettings = {
hideOnMobile: boolean;
@@ -791,6 +827,7 @@ export declare namespace ContentTree {
responsiveStyle: 'overflow' | 'flat' | 'scroll';
children: [TableCaption, TableBody, TableFooter] | [TableCaption, TableBody] | [TableBody, TableFooter] | [TableBody];
columnSettings: TableColumnSettings[];
+ fragmentIdentifier?: string;
}
type CustomCodeComponentAttributes = {
[key: string]: string | boolean | undefined;
@@ -802,6 +839,12 @@ export declare namespace ContentTree {
id: string;
/** How the component should be presented in the article page according to the column layout system */
layoutWidth: LayoutWidth;
+ /** Repository for the code of the component in the format "[github org]/[github repo]/[component name]". */
+ /** Semantic version of the code of the component, e.g. "^0.3.5". */
+ /** Last date-time when the attributes for this block were modified, in ISO-8601 format. */
+ /** Configuration data to be passed to the component. */
+ /** Unique fragmentIdentifier to identify the component, for things such as anchor links. */
+ fragmentIdentifier?: string;
}
}
namespace loose {
@@ -837,11 +880,13 @@ export declare namespace ContentTree {
interface Paragraph extends Parent {
type: "paragraph";
children: Phrasing[];
+ fragmentIdentifier?: string;
}
interface Heading extends Parent {
type: "heading";
children: Text[];
level: "chapter" | "subheading" | "label";
+ fragmentIdentifier?: string;
}
interface Strong extends Parent {
type: "strong";
@@ -865,6 +910,7 @@ export declare namespace ContentTree {
type: "list";
ordered: boolean;
children: ListItem[];
+ fragmentIdentifier?: string;
}
interface ListItem extends Parent {
type: "list-item";
@@ -883,6 +929,7 @@ export declare namespace ContentTree {
type: "image-set";
id: string;
picture?: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type ImageSetPicture = {
layoutWidth: string;
@@ -962,20 +1009,24 @@ export declare namespace ContentTree {
description?: string;
timestamp?: string;
fallbackImage?: Image;
+ fragmentIdentifier?: string;
}
interface BigNumber extends Node {
type: "big-number";
number: string;
description: string;
+ fragmentIdentifier?: string;
}
interface Video extends Node {
type: "video";
id: string;
title?: string;
+ fragmentIdentifier?: string;
}
interface YoutubeVideo extends Node {
type: "youtube-video";
url: string;
+ fragmentIdentifier?: string;
}
interface ScrollyBlock extends Parent {
type: "scrolly-block";
@@ -1009,6 +1060,7 @@ export declare namespace ContentTree {
layoutName: "auto" | "card" | "timeline";
layoutWidth: string;
children: [Heading, LayoutImage, ...LayoutSlot[]] | [Heading, ...LayoutSlot[]] | LayoutSlot[];
+ fragmentIdentifier?: string;
}
interface LayoutSlot extends Parent {
type: "layout-slot";
@@ -1021,6 +1073,7 @@ export declare namespace ContentTree {
caption: string;
credit: string;
picture?: ImageSetPicture;
+ fragmentIdentifier?: string;
}
type TableColumnSettings = {
hideOnMobile: boolean;
@@ -1057,6 +1110,7 @@ export declare namespace ContentTree {
responsiveStyle: 'overflow' | 'flat' | 'scroll';
children: [TableCaption, TableBody, TableFooter] | [TableCaption, TableBody] | [TableBody, TableFooter] | [TableBody];
columnSettings: TableColumnSettings[];
+ fragmentIdentifier?: string;
}
type CustomCodeComponentAttributes = {
[key: string]: string | boolean | undefined;
@@ -1076,6 +1130,8 @@ export declare namespace ContentTree {
attributesLastModified?: string;
/** Configuration data to be passed to the component. */
attributes?: CustomCodeComponentAttributes;
+ /** Unique fragmentIdentifier to identify the component, for things such as anchor links. */
+ fragmentIdentifier?: string;
}
}
}
diff --git a/content_tree.go b/content_tree.go
index abd6b3d..64bd721 100644
--- a/content_tree.go
+++ b/content_tree.go
@@ -102,10 +102,11 @@ type ColumnSettingsItems struct {
}
type BigNumber struct {
- Type string `json:"type"`
- Data interface{} `json:"data,omitempty"`
- Description string `json:"description,omitempty"`
- Number string `json:"number,omitempty"`
+ Type string `json:"type"`
+ Data interface{} `json:"data,omitempty"`
+ Description string `json:"description,omitempty"`
+ Number string `json:"number,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *BigNumber) GetType() string {
@@ -586,14 +587,15 @@ func (n *Emphasis) GetChildren() []Node {
}
type Flourish struct {
- Type string `json:"type"`
- Data interface{} `json:"data,omitempty"`
- Description string `json:"description,omitempty"`
- FallbackImage *FlourishFallbackImage `json:"fallbackImage,omitempty"`
- FlourishType string `json:"flourishType,omitempty"`
- Id string `json:"id,omitempty"`
- LayoutWidth string `json:"layoutWidth,omitempty"`
- Timestamp string `json:"timestamp,omitempty"`
+ Type string `json:"type"`
+ Data interface{} `json:"data,omitempty"`
+ Description string `json:"description,omitempty"`
+ FallbackImage *FlourishFallbackImage `json:"fallbackImage,omitempty"`
+ FlourishType string `json:"flourishType,omitempty"`
+ Id string `json:"id,omitempty"`
+ LayoutWidth string `json:"layoutWidth,omitempty"`
+ Timestamp string `json:"timestamp,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Flourish) GetType() string {
@@ -628,6 +630,7 @@ type Heading struct {
Children []*Text `json:"children,omitempty"`
Data interface{} `json:"data,omitempty"`
Level string `json:"level,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Heading) GetType() string {
@@ -647,10 +650,11 @@ func (n *Heading) GetChildren() []Node {
}
type ImageSet struct {
- Type string `json:"type"`
- Data interface{} `json:"data,omitempty"`
- ID string `json:"id,omitempty"`
- Picture *Picture `json:"picture,omitempty"`
+ Type string `json:"type"`
+ Data interface{} `json:"data,omitempty"`
+ ID string `json:"id,omitempty"`
+ Picture *Picture `json:"picture,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *ImageSet) GetType() string {
@@ -666,11 +670,12 @@ func (n *ImageSet) GetChildren() []Node {
}
type Layout struct {
- Type string `json:"type"`
- Children []*LayoutChild `json:"children,omitempty"`
- Data interface{} `json:"data,omitempty"`
- LayoutName string `json:"layoutName,omitempty"`
- LayoutWidth string `json:"layoutWidth,omitempty"`
+ Type string `json:"type"`
+ Children []*LayoutChild `json:"children,omitempty"`
+ Data interface{} `json:"data,omitempty"`
+ LayoutName string `json:"layoutName,omitempty"`
+ LayoutWidth string `json:"layoutWidth,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Layout) GetType() string {
@@ -757,13 +762,14 @@ func (n *LayoutChild) UnmarshalJSON(data []byte) error {
}
type LayoutImage struct {
- Type string `json:"type"`
- Alt string `json:"alt,omitempty"`
- Caption string `json:"caption,omitempty"`
- Credit string `json:"credit,omitempty"`
- Data interface{} `json:"data,omitempty"`
- ID string `json:"id,omitempty"`
- Picture *Picture `json:"picture,omitempty"`
+ Type string `json:"type"`
+ Alt string `json:"alt,omitempty"`
+ Caption string `json:"caption,omitempty"`
+ Credit string `json:"credit,omitempty"`
+ Data interface{} `json:"data,omitempty"`
+ ID string `json:"id,omitempty"`
+ Picture *Picture `json:"picture,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *LayoutImage) GetType() string {
@@ -892,10 +898,11 @@ func (n *Link) GetChildren() []Node {
}
type List struct {
- Type string `json:"type"`
- Children []*ListItem `json:"children,omitempty"`
- Data interface{} `json:"data,omitempty"`
- Ordered bool `json:"ordered,omitempty"`
+ Type string `json:"type"`
+ Children []*ListItem `json:"children,omitempty"`
+ Data interface{} `json:"data,omitempty"`
+ Ordered bool `json:"ordered,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *List) GetType() string {
@@ -1059,9 +1066,10 @@ func (n *ListItemChild) UnmarshalJSON(data []byte) error {
}
type Paragraph struct {
- Type string `json:"type"`
- Children []*Phrasing `json:"children,omitempty"`
- Data interface{} `json:"data,omitempty"`
+ Type string `json:"type"`
+ Children []*Phrasing `json:"children,omitempty"`
+ Data interface{} `json:"data,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Paragraph) GetType() string {
@@ -1501,6 +1509,7 @@ type Table struct {
LayoutWidth string `json:"layoutWidth,omitempty"`
ResponsiveStyle string `json:"responsiveStyle,omitempty"`
Stripes bool `json:"stripes,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Table) GetType() string {
@@ -1752,9 +1761,10 @@ func (n *Tweet) GetChildren() []Node {
}
type Video struct {
- Type string `json:"type"`
- Data interface{} `json:"data,omitempty"`
- ID string `json:"id,omitempty"`
+ Type string `json:"type"`
+ Data interface{} `json:"data,omitempty"`
+ ID string `json:"id,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *Video) GetType() string {
@@ -1770,9 +1780,10 @@ func (n *Video) GetChildren() []Node {
}
type YoutubeVideo struct {
- Type string `json:"type"`
- Data interface{} `json:"data,omitempty"`
- URL string `json:"url,omitempty"`
+ Type string `json:"type"`
+ Data interface{} `json:"data,omitempty"`
+ URL string `json:"url,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *YoutubeVideo) GetType() string {
@@ -1796,6 +1807,7 @@ type CustomCodeComponent struct {
AttributesLastModified string `json:"attributesLastModified,omitempty"`
Path string `json:"path,omitempty"`
VersionRange string `json:"versionRange,omitempty"`
+ FragmentIdentifier string `json:"fragmentIdentifier,omitempty"`
}
func (n *CustomCodeComponent) GetType() string {
diff --git a/libraries/from-bodyxml/index.js b/libraries/from-bodyxml/index.js
index 344ecc5..fb2b7d7 100644
--- a/libraries/from-bodyxml/index.js
+++ b/libraries/from-bodyxml/index.js
@@ -56,44 +56,54 @@ export let defaultTransformers = {
* @type {Transformer}
*/
h1(h1) {
+ const fragmentId = h1.attributes["data-fragment-id"] || h1.attributes["id"];
return {
type: "heading",
level: "chapter",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
* @type {Transformer}
*/
h2(h2) {
+ const fragmentId = h2.attributes["data-fragment-id"] || h2.attributes["id"];
return {
type: "heading",
level: "subheading",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
* @type {Transformer}
*/
h3(h3) {
+ const fragmentId = h3.attributes["data-fragment-id"] || h3.attributes["id"];
return {
type: "heading",
level: "subheading",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
* @type {Transformer}
*/
h4(h4) {
+ const fragmentId = h4.attributes["data-fragment-id"] || h4.attributes["id"];
return {
type: "heading",
level: "label",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
* @type {Transformer}
*/
p(p) {
+ const fragmentId = p.attributes["data-fragment-id"] || p.attributes["id"];
return {
type: "paragraph",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
@@ -163,18 +173,22 @@ export let defaultTransformers = {
* @type {Transformer}
*/
ol(ol) {
+ const fragmentId = ol.attributes["data-fragment-id"] || ol.attributes["id"];
return {
type: "list",
ordered: true,
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
* @type {Transformer}
*/
ul(ul) {
+ const fragmentId = ul.attributes["data-fragment-id"] || ul.attributes["id"];
return {
type: "list",
ordered: false,
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
};
},
/**
@@ -210,12 +224,14 @@ export let defaultTransformers = {
* @type {Transformer}
*/
["big-number"](bn) {
+ const fragmentId = bn.attributes["data-fragment-id"] || bn.attributes["id"];
let number = find(bn, { name: "big-number-headline" });
let description = find(bn, { name: "big-number-intro" });
return {
type: "big-number",
number: number ? xastToString(number) : "",
description: description ? xastToString(description) : "",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
};
},
@@ -223,6 +239,7 @@ export let defaultTransformers = {
* @type {Transformer}
*/
img(img) {
+ const fragmentId = img.attributes["data-fragment-id"] || img.attributes["id"];
return {
type: "layout-image",
id: img.attributes.src ?? "",
@@ -230,6 +247,7 @@ export let defaultTransformers = {
// todo this can't be right
alt: img.attributes.alt ?? "",
caption: img.attributes.longdesc ?? "",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
};
},
@@ -237,9 +255,11 @@ export let defaultTransformers = {
* @type {Transformer}
*/
[ContentType.imageset](content) {
+ const fragmentId = content.attributes["data-fragment-id"] || content.attributes["id"];
return {
type: "image-set",
id: content.attributes.url ?? "",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
};
},
@@ -247,9 +267,11 @@ export let defaultTransformers = {
* @type {Transformer}
*/
[ContentType.video](content) {
+ const fragmentId = content.attributes["data-fragment-id"] || content.attributes["id"];
return {
type: "video",
id: content.attributes.url ?? "",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
};
},
@@ -260,6 +282,7 @@ export let defaultTransformers = {
[ContentType.content](content) {
const id = content.attributes.url ?? "";
const uuid = id.split("/").pop();
+ const fragmentId = content.attributes["data-fragment-id"] || content.attributes["id"];
if (content.attributes["data-asset-type"] == "flourish") {
return /** @type {ContentTree.transit.Flourish} */ ({
@@ -271,6 +294,7 @@ export let defaultTransformers = {
),
description: content.attributes["alt"] || "",
timestamp: content.attributes["data-time-stamp"] || "",
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
});
}
@@ -297,6 +321,7 @@ export let defaultTransformers = {
* @type {Transformer}
*/
[ContentType.customCodeComponent](content) {
+ const fragmentId = content.attributes["data-fragment-id"] || content.attributes["id"];
const id = content.attributes.url ?? "";
const uuid = id.split("/").pop();
return {
@@ -305,6 +330,7 @@ export let defaultTransformers = {
layoutWidth: toValidLayoutWidth(
content.attributes["data-layout-width"] || ""
),
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
children: null,
};
},
@@ -331,6 +357,8 @@ export let defaultTransformers = {
* >}
*/
div(div) {
+ const fragmentId = div.attributes["data-fragment-id"] || div.attributes["id"];
+
if (div.attributes.class === "n-content-layout") {
return /** @type {ContentTree.transit.Layout} */ ({
type: "layout",
@@ -338,6 +366,7 @@ export let defaultTransformers = {
layoutWidth: toValidLayoutWidth(
div.attributes["data-layout-width"] ?? ""
),
+ ...(fragmentId && { fragmentIdentifier: fragmentId }),
});
}
if (div.attributes.class === "n-content-layout__container") {
diff --git a/schemas/body-tree.schema.json b/schemas/body-tree.schema.json
index 5f2a150..28dd9e9 100644
--- a/schemas/body-tree.schema.json
+++ b/schemas/body-tree.schema.json
@@ -9,6 +9,9 @@
"description": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"number": {
"type": "string"
},
@@ -140,6 +143,10 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "description": "Unique fragmentIdentifier to identify the component, for things such as anchor links.",
+ "type": "string"
+ },
"id": {
"description": "Id taken from the CAPI url",
"type": "string"
@@ -192,6 +199,9 @@
"flourishType": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -224,6 +234,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"level": {
"enum": [
"chapter",
@@ -248,6 +261,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -303,6 +319,9 @@
]
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutName": {
"enum": [
"auto",
@@ -340,6 +359,9 @@
"type": "string"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -440,6 +462,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"ordered": {
"type": "boolean"
},
@@ -508,6 +533,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "paragraph",
"type": "string"
@@ -884,6 +912,9 @@
"type": "boolean"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutWidth": {
"enum": [
"auto",
@@ -1083,6 +1114,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -1101,6 +1135,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "youtube-video",
"type": "string"
diff --git a/schemas/content-tree.schema.json b/schemas/content-tree.schema.json
index 4a1114a..4f8d0f7 100644
--- a/schemas/content-tree.schema.json
+++ b/schemas/content-tree.schema.json
@@ -9,6 +9,9 @@
"description": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"number": {
"type": "string"
},
@@ -179,6 +182,10 @@
"type": "string"
},
"data": {},
+ "fragmentIdentifier": {
+ "description": "Unique fragmentIdentifier to identify the component, for things such as anchor links.",
+ "type": "string"
+ },
"id": {
"description": "Id taken from the CAPI url",
"type": "string"
@@ -303,6 +310,9 @@
"flourishType": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -335,6 +345,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"level": {
"enum": [
"chapter",
@@ -359,6 +372,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -572,6 +588,9 @@
]
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutName": {
"enum": [
"auto",
@@ -609,6 +628,9 @@
"type": "string"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -867,6 +889,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"ordered": {
"type": "boolean"
},
@@ -935,6 +960,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "paragraph",
"type": "string"
@@ -1662,6 +1690,9 @@
"type": "boolean"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutWidth": {
"enum": [
"auto",
@@ -1865,6 +1896,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -1887,6 +1921,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "youtube-video",
"type": "string"
diff --git a/schemas/transit-tree.schema.json b/schemas/transit-tree.schema.json
index 9864746..577a8aa 100644
--- a/schemas/transit-tree.schema.json
+++ b/schemas/transit-tree.schema.json
@@ -9,6 +9,9 @@
"description": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"number": {
"type": "string"
},
@@ -165,6 +168,10 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "description": "Unique fragmentIdentifier to identify the component, for things such as anchor links.",
+ "type": "string"
+ },
"id": {
"description": "Id taken from the CAPI url",
"type": "string"
@@ -217,6 +224,9 @@
"flourishType": {
"type": "string"
},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -249,6 +259,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"level": {
"enum": [
"chapter",
@@ -273,6 +286,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -328,6 +344,9 @@
]
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutName": {
"enum": [
"auto",
@@ -365,6 +384,9 @@
"type": "string"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -465,6 +487,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"ordered": {
"type": "boolean"
},
@@ -533,6 +558,9 @@
"type": "array"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "paragraph",
"type": "string"
@@ -909,6 +937,9 @@
"type": "boolean"
},
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"layoutWidth": {
"enum": [
"auto",
@@ -1108,6 +1139,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"id": {
"type": "string"
},
@@ -1126,6 +1160,9 @@
"additionalProperties": false,
"properties": {
"data": {},
+ "fragmentIdentifier": {
+ "type": "string"
+ },
"type": {
"const": "youtube-video",
"type": "string"