diff --git a/demo/21-bookmarks.ts b/demo/21-bookmarks.ts index 6c673f1520..56343c94cd 100644 --- a/demo/21-bookmarks.ts +++ b/demo/21-bookmarks.ts @@ -18,10 +18,12 @@ const doc = new Document({ new Paragraph({ children: [ new InternalHyperlink({ - child: new TextRun({ - text: "Click here!", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Click here!", + style: "Hyperlink", + }), + ], anchor: "myAnchorId", }), ], @@ -47,19 +49,23 @@ const doc = new Document({ new Paragraph({ children: [ new InternalHyperlink({ - child: new TextRun({ - text: "Anchor Text", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Styled", + bold: true, + style: "Hyperlink", + }), + new TextRun({ + text: " Anchor Text", + style: "Hyperlink", + }), + ], anchor: "myAnchorId", }), ], }), new Paragraph({ - children: [ - new TextRun("The bookmark can be seen on page "), - new PageRef("myAnchorId"), - ] + children: [new TextRun("The bookmark can be seen on page "), new PageRef("myAnchorId")], }), ], }, diff --git a/demo/35-hyperlinks.ts b/demo/35-hyperlinks.ts index f8aca4f622..6039e6f443 100644 --- a/demo/35-hyperlinks.ts +++ b/demo/35-hyperlinks.ts @@ -11,10 +11,12 @@ const doc = new Document({ children: [ new TextRun("Click here for the "), new ExternalHyperlink({ - child: new TextRun({ - text: "Footnotes external hyperlink", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Footnotes external hyperlink", + style: "Hyperlink", + }), + ], link: "http://www.example.com", }), ], @@ -31,10 +33,12 @@ const doc = new Document({ children: [ new TextRun("Click here for the "), new ExternalHyperlink({ - child: new TextRun({ - text: "Footer external hyperlink", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Footer external hyperlink", + style: "Hyperlink", + }), + ], link: "http://www.example.com", }), ], @@ -49,10 +53,12 @@ const doc = new Document({ children: [ new TextRun("Click here for the "), new ExternalHyperlink({ - child: new TextRun({ - text: "Header external hyperlink", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Header external hyperlink", + style: "Hyperlink", + }), + ], link: "http://www.google.com", }), ], @@ -64,10 +70,12 @@ const doc = new Document({ new Paragraph({ children: [ new ExternalHyperlink({ - child: new TextRun({ - text: "Anchor Text", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "Anchor Text", + style: "Hyperlink", + }), + ], link: "http://www.example.com", }), new FootnoteReferenceRun(1), @@ -76,24 +84,63 @@ const doc = new Document({ new Paragraph({ children: [ new ExternalHyperlink({ - child: new ImageRun({ - data: fs.readFileSync("./demo/images/image1.jpeg"), - transformation: { - width: 100, - height: 100, - }, - }), + children: [ + new ImageRun({ + data: fs.readFileSync("./demo/images/image1.jpeg"), + transformation: { + width: 100, + height: 100, + }, + }), + ], link: "http://www.google.com", }), new ExternalHyperlink({ - child: new TextRun({ - text: "BBC News Link", - style: "Hyperlink", - }), + children: [ + new TextRun({ + text: "BBC News Link", + style: "Hyperlink", + }), + ], link: "https://www.bbc.co.uk/news", }), ], }), + new Paragraph({ + children: [ + new TextRun({ + text: "This is a hyperlink with formatting: ", + }), + new ExternalHyperlink({ + children: [ + new TextRun({ + text: "A ", + style: "Hyperlink", + }), + new TextRun({ + text: "single ", + bold: true, + style: "Hyperlink", + }), + new TextRun({ + text: "link", + doubleStrike: true, + style: "Hyperlink", + }), + new TextRun({ + text: "1", + superScript: true, + style: "Hyperlink", + }), + new TextRun({ + text: "!", + style: "Hyperlink", + }), + ], + link: "http://www.example.com", + }), + ], + }), ], }, ], diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 7fa4e9f745..356f64239a 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -15,6 +15,7 @@ * [Image](usage/images.md) * [Headers & Footers](usage/headers-and-footers.md) * [Bullet Points](usage/bullet-points.md) + * [Hyperlinks](usage/hyperlinks.md) * [Numbering](usage/numbering.md) * [Tables](usage/tables.md) * [Tab Stops](usage/tab-stops.md) diff --git a/docs/usage/hyperlinks.md b/docs/usage/hyperlinks.md index f8d53416ee..d49d9aa0a2 100644 --- a/docs/usage/hyperlinks.md +++ b/docs/usage/hyperlinks.md @@ -1,58 +1,98 @@ # Hyperlinks +!> Hyperlinks require an understanding of [Paragraphs](usage/paragraph.md) and [Text](usage/text.md). + There are two types of hyperlinks: internal (pointing to a bookmark inside the document) and external (pointing to an external url). ## Internal -To create an internal hyperlink you need first to create a bookmark (the paragraph that will be the destination of the hyperlink) with `doc.createBookmark(anchor, text)`. +To create an internal hyperlink you need first to create a `Bookmark`, which contains the content that will be the destination of the hyperlink. -A bookmark is composed of an anchor (an identifier) and the text displayed. After creating a bookmark just add it to a paragraph with `paragraph.addBookmark(bookmark)` - -For example: +A bookmark is composed of an anchor (an identifier) and the text displayed. After creating a bookmark just add it to a paragraph. For example, creating a bookmarked heading: ```ts -const paragraph = this.doc.createParagraph(); -const bookmark = this.doc.createBookmark('anchorForChapter1', 'This is chapter1'); -paragraph.addBookmark(bookmark); +const chapter1 = new Paragraph({ + heading: HeadingLevel.HEADING_1, + children: [ + new Bookmark({ + id: "anchorForChapter1", + children: [ + new TextRun("Chapter 1"), + ], + }), + ], +}) ``` -Then you can create an hyperlink pointing to that bookmark with `doc.createInternalHyperLink(anchor,text)`: +Then you can create an hyperlink pointing to that bookmark with an `InternalHyperLink`: ```ts -const paragraph = this.doc.createParagraph(); -const link = this.doc.createInternalHyperLink('anchorForChapter1', 'This is a link to chapter1'); -paragraph.addHyperLink(link); +const link = new InternalHyperlink({ + children: [ + new TextRun({ + text: "See Chapter 1", + style: "Hyperlink", + }), + ], + anchor: "anchorForChapter1", +}) ``` You can also get the page number of the bookmark by creating a page reference to it: ```ts -new Paragraph({ +const paragraph = new Paragraph({ children: [ - new TextRun("The chapter1 can be seen on page "), + new TextRun("Chapter 1 can be seen on page "), new PageRef("anchorForChapter1"), - ] -}) + ], +}); ``` ## External -To create an external hyperlink you just need to specify the url and the text of the link, then add it to a paragraph with `doc.createHyperlink(url, text)`: +To create an external hyperlink you just need to specify the url and the text of the link, then add it to a paragraph: ```ts -const paragraph = this.doc.createParagraph(); -const link = this.doc.createHyperlink('https://docx.js.org', 'This is an external link'); -paragraph.addHyperLink(link); +const paragraph = new Paragraph({ + children: [ + new ExternalHyperlink({ + children: [ + new TextRun({ + text: "This is an external link!", + style: "Hyperlink", + }), + ], + link: "https://docx.js.org", + }), + ], +}); ``` -## Styling an hyperlink +## Styling hyperlinks -It is possible to set the style of the text of an hyperlink. This can be done applying run formatting on `TextRun` property of the hyperlink. +It is possible to set the style of the text of both internal and external hyperlinks. This can be done applying run formatting on any of the `TextRun` children of the hyperlink. Use the `style: "Hyperlink"` property to show the default link styles, which can be combined with any other style. Example: ```ts -const link = this.doc.createHyperlink('https://docx.js.org', 'This is an external link'); -link.TextRun.bold().italics() +const styledLink = new ExternalHyperlink({ + children: [ + new TextRun({ + text: "This is a ", + style: "Hyperlink", + }), + new TextRun({ + text: "bold", + bold: true, + style: "Hyperlink", + }), + new TextRun({ + text: " link!", + style: "Hyperlink", + }), + ], + link: "https://docx.js.org", +}); ``` diff --git a/src/file/paragraph/links/hyperlink.spec.ts b/src/file/paragraph/links/hyperlink.spec.ts index 50d6aa76aa..9f79a19ff1 100644 --- a/src/file/paragraph/links/hyperlink.spec.ts +++ b/src/file/paragraph/links/hyperlink.spec.ts @@ -10,10 +10,12 @@ describe("ConcreteHyperlink", () => { beforeEach(() => { hyperlink = new ConcreteHyperlink( - new TextRun({ - text: "https://example.com", - style: "Hyperlink", - }), + [ + new TextRun({ + text: "https://example.com", + style: "Hyperlink", + }), + ], "superid", ); }); @@ -42,10 +44,12 @@ describe("ConcreteHyperlink", () => { describe("with optional anchor parameter", () => { beforeEach(() => { hyperlink = new ConcreteHyperlink( - new TextRun({ - text: "Anchor Text", - style: "Hyperlink", - }), + [ + new TextRun({ + text: "Anchor Text", + style: "Hyperlink", + }), + ], "superid2", "anchor", ); @@ -78,7 +82,7 @@ describe("ExternalHyperlink", () => { describe("#constructor()", () => { it("should create", () => { const externalHyperlink = new ExternalHyperlink({ - child: new TextRun("test"), + children: [new TextRun("test")], link: "http://www.google.com", }); @@ -91,7 +95,7 @@ describe("InternalHyperlink", () => { describe("#constructor()", () => { it("should create", () => { const internalHyperlink = new InternalHyperlink({ - child: new TextRun("test"), + children: [new TextRun("test")], anchor: "test-id", }); diff --git a/src/file/paragraph/links/hyperlink.ts b/src/file/paragraph/links/hyperlink.ts index 7ced10d07c..2c39997908 100644 --- a/src/file/paragraph/links/hyperlink.ts +++ b/src/file/paragraph/links/hyperlink.ts @@ -13,7 +13,7 @@ export enum HyperlinkType { export class ConcreteHyperlink extends XmlComponent { public readonly linkId: string; - constructor(child: ParagraphChild, relationshipId: string, anchor?: string) { + constructor(children: ParagraphChild[], relationshipId: string, anchor?: string) { super("w:hyperlink"); this.linkId = relationshipId; @@ -26,16 +26,18 @@ export class ConcreteHyperlink extends XmlComponent { const attributes = new HyperlinkAttributes(props); this.root.push(attributes); - this.root.push(child); + children.forEach((child) => { + this.root.push(child); + }); } } export class InternalHyperlink extends ConcreteHyperlink { - constructor(options: { readonly child: ParagraphChild; readonly anchor: string }) { - super(options.child, uniqueId(), options.anchor); + constructor(options: { readonly children: ParagraphChild[]; readonly anchor: string }) { + super(options.children, uniqueId(), options.anchor); } } export class ExternalHyperlink { - constructor(public readonly options: { readonly child: ParagraphChild; readonly link: string }) {} + constructor(public readonly options: { readonly children: ParagraphChild[]; readonly link: string }) {} } diff --git a/src/file/paragraph/paragraph.spec.ts b/src/file/paragraph/paragraph.spec.ts index 90c6c8bedd..ab06d59ac1 100644 --- a/src/file/paragraph/paragraph.spec.ts +++ b/src/file/paragraph/paragraph.spec.ts @@ -927,7 +927,7 @@ describe("Paragraph", () => { const paragraph = new Paragraph({ children: [ new ExternalHyperlink({ - child: new TextRun("test"), + children: [new TextRun("test")], link: "http://www.google.com", }), ], diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index afd9da1b7d..2f73f7cc65 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -75,7 +75,7 @@ export class Paragraph extends XmlComponent { for (const element of this.root) { if (element instanceof ExternalHyperlink) { const index = this.root.indexOf(element); - const concreteHyperlink = new ConcreteHyperlink(element.options.child, uniqueId()); + const concreteHyperlink = new ConcreteHyperlink(element.options.children, uniqueId()); context.viewWrapper.Relationships.createRelationship( concreteHyperlink.linkId, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",