@bartificer/linkify 2.3.5 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -35
- package/dist/index.js +1 -1
- package/docs/LinkData.class.mjs.html +119 -56
- package/docs/LinkTemplate.class.mjs.html +120 -36
- package/docs/Linkifier.class.mjs.html +141 -66
- package/docs/PageData.class.mjs.html +145 -72
- package/docs/defaults.mjs.html +136 -12
- package/docs/docdash-overrides.css +11 -0
- package/docs/externals.jsdoc.html +95 -4
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/global.html +1276 -0
- package/docs/index.html +1018 -26
- package/docs/index.js.html +143 -17
- package/docs/mermaid-init.js +21 -0
- package/docs/module-cheerio.html +193 -3
- package/docs/module-defaults.html +680 -3
- package/docs/module-link-data.LinkData.html +813 -0
- package/docs/module-link-data.html +226 -0
- package/docs/module-link-template.LinkTemplate.html +792 -0
- package/docs/module-link-template.html +226 -0
- package/docs/module-linkifier.Linkifier.html +2050 -0
- package/docs/module-linkifier.html +236 -0
- package/docs/module-linkify.html +810 -3
- package/docs/module-mustache.html +193 -3
- package/docs/module-node-fetch.html +193 -3
- package/docs/module-page-data.PageData.html +1810 -0
- package/docs/module-page-data.html +226 -0
- package/docs/module-title-case.html +193 -3
- package/docs/module-urijs.html +193 -3
- package/docs/module-url-slug.html +193 -3
- package/docs/module-utilities.html +1518 -3
- package/docs/scripts/collapse.js +39 -0
- package/docs/scripts/commonNav.js +28 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/nav.js +12 -0
- package/docs/scripts/polyfill.js +4 -0
- package/docs/scripts/{third-party → prettify}/Apache-License-2.0.txt +202 -202
- package/docs/scripts/prettify/lang-css.js +2 -0
- package/docs/scripts/prettify/prettify.js +28 -0
- package/docs/scripts/search.js +99 -265
- package/docs/styles/jsdoc.css +776 -0
- package/docs/styles/prettify.css +80 -0
- package/docs/typedefs.jsdoc.html +145 -0
- package/docs/utilities.mjs.html +154 -22
- package/examples/clipboardURLToMarkdown.mjs +80 -1
- package/package.json +5 -3
- package/src/LinkData.class.mjs +24 -52
- package/src/LinkTemplate.class.mjs +25 -32
- package/src/Linkifier.class.mjs +46 -62
- package/src/PageData.class.mjs +50 -68
- package/src/defaults.mjs +42 -8
- package/src/index.js +48 -13
- package/src/typedefs.jsdoc +52 -0
- package/src/utilities.mjs +59 -18
- package/docs/data/search.json +0 -1
- package/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/module-LinkData.LinkData.html +0 -13
- package/docs/module-LinkData.html +0 -3
- package/docs/module-LinkTemplate.LinkTemplate.html +0 -3
- package/docs/module-LinkTemplate.html +0 -3
- package/docs/module-Linkifier.Linkifier.html +0 -3
- package/docs/module-Linkifier.html +0 -3
- package/docs/module-PageData.PageData.html +0 -15
- package/docs/module-PageData.html +0 -3
- package/docs/scripts/core.js +0 -726
- package/docs/scripts/core.min.js +0 -23
- package/docs/scripts/resize.js +0 -90
- package/docs/scripts/search.min.js +0 -6
- package/docs/scripts/third-party/fuse.js +0 -9
- package/docs/scripts/third-party/hljs-line-num-original.js +0 -369
- package/docs/scripts/third-party/hljs-line-num.js +0 -1
- package/docs/scripts/third-party/hljs-original.js +0 -5171
- package/docs/scripts/third-party/hljs.js +0 -1
- package/docs/scripts/third-party/popper.js +0 -5
- package/docs/scripts/third-party/tippy.js +0 -1
- package/docs/scripts/third-party/tocbot.js +0 -672
- package/docs/scripts/third-party/tocbot.min.js +0 -1
- package/docs/styles/clean-jsdoc-theme-base.css +0 -1159
- package/docs/styles/clean-jsdoc-theme-dark.css +0 -412
- package/docs/styles/clean-jsdoc-theme-light.css +0 -482
- package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -30
- package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
- package/docs/styles/clean-jsdoc-theme.min.css +0 -1
package/src/PageData.class.mjs
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Data model for web page information.
|
|
3
3
|
* @author Bart Busschots <opensource@bartificer.ie>
|
|
4
|
+
* @license MIT
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* This module provides
|
|
8
|
-
* @module
|
|
8
|
+
* This module provides the class for representing the information that is extracted from web pages.
|
|
9
|
+
* @module page-data
|
|
9
10
|
* @requires module:urijs
|
|
10
11
|
*/
|
|
11
12
|
import {default as URI} from 'urijs';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
+
* The information extracted from web pages that can be used to render a link.
|
|
16
|
+
*
|
|
17
|
+
* Instances of this class are created from the information extracted from web pages and converted to link information by data transformers before being rendered to links via templates.
|
|
18
|
+
* @see {@link dataTransformer} for details of how instances of this class are used in the link generation process.
|
|
15
19
|
*/
|
|
16
20
|
export class PageData {
|
|
17
21
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param {URL} url - The page's full URL.
|
|
21
|
-
* @throws {ValidationError} A validation error is thrown if an invalid URL
|
|
22
|
-
* is passed.
|
|
22
|
+
* @param {string} url - The page's full URL.
|
|
23
23
|
*/
|
|
24
24
|
constructor(url){
|
|
25
25
|
// TO DO - add validation
|
|
@@ -28,7 +28,7 @@ export class PageData {
|
|
|
28
28
|
* The page's URL as a URI object.
|
|
29
29
|
*
|
|
30
30
|
* @private
|
|
31
|
-
* @type {
|
|
31
|
+
* @type {module:urijs}
|
|
32
32
|
*/
|
|
33
33
|
this._uri = URI();
|
|
34
34
|
|
|
@@ -45,74 +45,73 @@ export class PageData {
|
|
|
45
45
|
* `h1` and `h2`.
|
|
46
46
|
*
|
|
47
47
|
* @private
|
|
48
|
-
* @type {
|
|
48
|
+
* @type {Object}
|
|
49
|
+
* @property {string[]} h1 - The page's top-level headings (`h1` tags).
|
|
50
|
+
* @property {string[]} h2 - The page's secondary headings (`h2` tags).
|
|
49
51
|
*/
|
|
50
52
|
this._headings = {
|
|
51
53
|
h1: [],
|
|
52
54
|
h2: []
|
|
53
55
|
};
|
|
54
56
|
|
|
55
|
-
// store the URL
|
|
57
|
+
// store the URL using the public setter to ensure it's stored as a URI object
|
|
56
58
|
this.url = url;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
|
-
* @
|
|
62
|
+
* @type {string}
|
|
63
|
+
* @throws {TypeError} on invalid URLs.
|
|
61
64
|
*/
|
|
62
65
|
get url(){
|
|
63
66
|
return this._uri.toString();
|
|
64
67
|
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param {string} url - A URL as a string.
|
|
68
|
-
* @throws {ValidationError} A validation error is thrown if an argument
|
|
69
|
-
* is passed that's not a valid URL string.
|
|
70
|
-
*/
|
|
71
68
|
set url(url){
|
|
72
69
|
this._uri = URI(url).normalize();
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
/**
|
|
76
|
-
* @
|
|
73
|
+
* @type {module:urijs}
|
|
74
|
+
* @readonly
|
|
77
75
|
*/
|
|
78
76
|
get uri(){
|
|
79
77
|
return this._uri.clone();
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* @
|
|
81
|
+
* The domain-part of the URL.
|
|
82
|
+
* @type {string}
|
|
83
|
+
* @readonly
|
|
86
84
|
*/
|
|
87
85
|
get domain(){
|
|
88
86
|
return this._uri.hostname();
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
/**
|
|
92
|
-
*
|
|
90
|
+
* The path-part of the URL.
|
|
91
|
+
* @type {string}
|
|
92
|
+
* @readonly
|
|
93
93
|
*/
|
|
94
94
|
get path(){
|
|
95
95
|
return this._uri.path();
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
99
|
+
* The page's title. Values are coerced to strings with `String(title)`.
|
|
100
|
+
* @type {string}
|
|
100
101
|
*/
|
|
101
102
|
get title(){
|
|
102
103
|
return this._title;
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param {string} title - the page's title as a string. Values passed will be coerced to strings.
|
|
107
|
-
*/
|
|
108
105
|
set title(title){
|
|
109
106
|
this._title = String(title);
|
|
110
107
|
}
|
|
111
108
|
|
|
112
109
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* @
|
|
110
|
+
* The page's primary and secondary headings.
|
|
111
|
+
* @type {Object}
|
|
112
|
+
* @property {string[]} h1 - The page's top-level headings (`h1` tags).
|
|
113
|
+
* @property {string[]} h2 - The page's secondary headings (`h2` tags).
|
|
114
|
+
* @readonly
|
|
116
115
|
*/
|
|
117
116
|
get headings(){
|
|
118
117
|
let ans = {
|
|
@@ -130,8 +129,8 @@ export class PageData {
|
|
|
130
129
|
|
|
131
130
|
/**
|
|
132
131
|
* The page's top-level headings (`h1` tags).
|
|
133
|
-
*
|
|
134
|
-
* @
|
|
132
|
+
* @type {string[]}
|
|
133
|
+
* @readonly
|
|
135
134
|
*/
|
|
136
135
|
get topLevelHeadings(){
|
|
137
136
|
var ans = [];
|
|
@@ -143,7 +142,8 @@ export class PageData {
|
|
|
143
142
|
|
|
144
143
|
/**
|
|
145
144
|
* An alias for `.topLevelHeadings`.
|
|
146
|
-
* @
|
|
145
|
+
* @readonly
|
|
146
|
+
* @see {@link module:page-data.PageData#topLevelHeadings}
|
|
147
147
|
*/
|
|
148
148
|
get h1s(){
|
|
149
149
|
return this.topLevelHeadings;
|
|
@@ -151,8 +151,8 @@ export class PageData {
|
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
153
|
* The page's secondary headings (`h2` tags).
|
|
154
|
-
*
|
|
155
|
-
* @
|
|
154
|
+
* @type {string[]}
|
|
155
|
+
* @readonly
|
|
156
156
|
*/
|
|
157
157
|
get secondaryHeadings(){
|
|
158
158
|
var ans = [];
|
|
@@ -164,8 +164,9 @@ export class PageData {
|
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* An alias for `.secondaryHeadings`.
|
|
167
|
-
* @
|
|
168
|
-
|
|
167
|
+
* @readonly
|
|
168
|
+
* @see {@link module:page-data.PageData#secondaryHeadings}
|
|
169
|
+
*/
|
|
169
170
|
get h2s(){
|
|
170
171
|
return this.secondaryHeadings;
|
|
171
172
|
}
|
|
@@ -175,8 +176,8 @@ export class PageData {
|
|
|
175
176
|
* has `h1` tags, the first one will be used, if not, the first `h2` tag
|
|
176
177
|
* will be used, and if there's none of those either, an empty string will
|
|
177
178
|
* be returned.
|
|
178
|
-
*
|
|
179
|
-
* @
|
|
179
|
+
* @type {string}
|
|
180
|
+
* @readonly
|
|
180
181
|
*/
|
|
181
182
|
get mainHeading(){
|
|
182
183
|
if(this._headings.h1.length > 0){
|
|
@@ -192,7 +193,7 @@ export class PageData {
|
|
|
192
193
|
* Add a top-level heading.
|
|
193
194
|
*
|
|
194
195
|
* @param {string} h1Text
|
|
195
|
-
* @returns {PageData} A reference to self to
|
|
196
|
+
* @returns {module:page-data.PageData} A reference to self to
|
|
196
197
|
* facilitate function chaning.
|
|
197
198
|
*/
|
|
198
199
|
addTopLevelHeading(h1Text){
|
|
@@ -205,7 +206,7 @@ export class PageData {
|
|
|
205
206
|
* Add a seconary heading.
|
|
206
207
|
*
|
|
207
208
|
* @param {string} h2Text
|
|
208
|
-
* @returns {PageData} A reference to self to
|
|
209
|
+
* @returns {module:page-data.PageData} A reference to self to
|
|
209
210
|
* facilitate function chaning.
|
|
210
211
|
*/
|
|
211
212
|
addSecondaryHeading(h2Text){
|
|
@@ -215,27 +216,8 @@ export class PageData {
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
/**
|
|
218
|
-
* Get the page data as a plain object
|
|
219
|
-
*
|
|
220
|
-
* {
|
|
221
|
-
* url: 'http://www.bartificer.net/',
|
|
222
|
-
* title: 'the page title',
|
|
223
|
-
* topLevelHeadings: [ 'first h1', 'second h1' ],
|
|
224
|
-
* secondaryHeadings: [ 'first h2', 'second h2' ],
|
|
225
|
-
* mainHeading: 'first h1',
|
|
226
|
-
* uri: {
|
|
227
|
-
* hostname: 'www.bartificer.net',
|
|
228
|
-
* path: '/',
|
|
229
|
-
* hasPath: false
|
|
230
|
-
* }
|
|
231
|
-
* }
|
|
232
|
-
* ```
|
|
233
|
-
*
|
|
234
|
-
* Note that the `uri` could contain more fields - it's initialised with
|
|
235
|
-
* output from the `URI.parse()` function from the `URI` module.
|
|
236
|
-
*
|
|
237
|
-
* @returns {Object} A plain object containing the page data.
|
|
238
|
-
* @see {@link https://medialize.github.io/URI.js/docs.html#static-parse}
|
|
219
|
+
* Get the page data as a plain object.
|
|
220
|
+
* @returns {plainPageInformationObject}
|
|
239
221
|
*/
|
|
240
222
|
asPlainObject(){
|
|
241
223
|
let ans = {
|
|
@@ -253,18 +235,18 @@ export class PageData {
|
|
|
253
235
|
|
|
254
236
|
/**
|
|
255
237
|
* A shortcut for `.addTopLevelHeading()`.
|
|
256
|
-
*
|
|
238
|
+
* @name module:page-data.PageData#h1
|
|
257
239
|
* @function
|
|
258
|
-
* @see PageData#addTopLevelHeading
|
|
240
|
+
* @see {@link module:page-data.PageData#addTopLevelHeading}
|
|
259
241
|
*
|
|
260
242
|
*/
|
|
261
243
|
PageData.prototype.h1 = PageData.prototype.addTopLevelHeading;
|
|
262
244
|
|
|
263
245
|
/**
|
|
264
246
|
* A shortcut for `.addSecondaryHeading()`.
|
|
265
|
-
*
|
|
247
|
+
* @name module:page-data.PageData#h2
|
|
266
248
|
* @function
|
|
267
|
-
* @see PageData#addSecondaryHeading
|
|
249
|
+
* @see {@link module:page-data.PageData#addSecondaryHeading}
|
|
268
250
|
*
|
|
269
251
|
*/
|
|
270
252
|
PageData.prototype.h2 = PageData.prototype.addSecondaryHeading;
|
package/src/defaults.mjs
CHANGED
|
@@ -1,20 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Central location for the default values used throughout the codebase.
|
|
3
3
|
* @author Bart Busschots <opensource@bartificer.ie>
|
|
4
|
+
* @license MIT
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* Default values used by the various functions and classes.
|
|
9
|
+
*
|
|
10
|
+
* The defaults are collected here for clarity, helping module users both understand the defaults, and, make informed decisions about which defaults to augment or override completely.
|
|
8
11
|
* @module defaults
|
|
9
|
-
* @requires
|
|
10
|
-
* @requires
|
|
12
|
+
* @requires link-template
|
|
13
|
+
* @requires utilities
|
|
11
14
|
*/
|
|
12
15
|
import { LinkTemplate } from './LinkTemplate.class.mjs';
|
|
13
16
|
import * as utilities from "./utilities.mjs";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
|
-
* The
|
|
17
|
-
*
|
|
19
|
+
* The default link transformer. The Linkifier constructor assigns this data transformer to the root DNS name `.`, ensuring it acts as the fallback when no other domains are matched.
|
|
20
|
+
*
|
|
21
|
+
* If the page has exactly one top-level heading, this heading is used as a the link text, otherwise the page title is used.
|
|
22
|
+
*
|
|
23
|
+
* The description field is not explicitly set, so will default to the link text.
|
|
24
|
+
* @type {dataTransformer}
|
|
25
|
+
*/
|
|
26
|
+
export function dataTransformer(pData){
|
|
27
|
+
let text = pData.title;
|
|
28
|
+
if(pData.h1s.length === 1){
|
|
29
|
+
text = pData.mainHeading;
|
|
30
|
+
}
|
|
31
|
+
return new LinkData(pData.url, text);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The collection of named link templates loaded by the Linkifier constructor. All templates strip UTM parameters from the URL, and regularise white space in the text and descriptions.
|
|
36
|
+
* @type {Object.<string, module:link-template.LinkTemplate>}
|
|
37
|
+
* @property {module:link-template.LinkTemplate} html - The default HTML link template. Uses the link title as a the text and description as the hover-text.
|
|
38
|
+
* @property {module:link-template.LinkTemplate} htmlNewTab - The same as the `html` template, but with a `target="_blank"` attribute added.
|
|
39
|
+
* @property {module:link-template.LinkTemplate} markdown - The default Markdown link template. Uses the link title as the text, and ignores the description.
|
|
40
|
+
* @see {@link module:utilities.stripUTMParameters} for the function used to strip UTM parameters from the URL.
|
|
41
|
+
* @see {@link module:utilities.regulariseWhitespace} for the function used to regularise white space in the text and description.
|
|
18
42
|
*/
|
|
19
43
|
export const linkTemplates = {
|
|
20
44
|
html: new LinkTemplate(
|
|
@@ -43,8 +67,18 @@ export const linkTemplates = {
|
|
|
43
67
|
};
|
|
44
68
|
|
|
45
69
|
/**
|
|
46
|
-
*
|
|
70
|
+
* When conbverting strings to title case, some joiner words should be preserved in all lower case. The Title Case module handles most appropriately, but not all.
|
|
71
|
+
* These are the additional words that also treated as so-called *small words* by the functions in the utility module.
|
|
72
|
+
* @type {string[]}
|
|
73
|
+
* @see {@link module:utilities.toTitleCase} for the function that uses this list to treat these words as small words by default.
|
|
74
|
+
* @see {@link module:title-case} for the Title Case module who's default small word list is augmented by this list.
|
|
75
|
+
*/
|
|
76
|
+
export const smallWords = [ 'is', 'its' ];
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* When converting strings to title case, some words need to have their capitalisations corrected. These are the custom capitalisations that will be used by default.
|
|
47
80
|
* @type {string[]}
|
|
81
|
+
* @see {@link module:utilities.toTitleCase} for the function that uses this list to correct capitalisations by default.
|
|
48
82
|
*/
|
|
49
83
|
export const speciallyCapitalisedWords = [
|
|
50
84
|
// generic acronyms
|
|
@@ -100,4 +134,4 @@ export const speciallyCapitalisedWords = [
|
|
|
100
134
|
'DisplayPort',
|
|
101
135
|
'LinkedIn',
|
|
102
136
|
'ChatGPT'
|
|
103
|
-
];
|
|
137
|
+
];
|
package/src/index.js
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Defines the public interface for the published module.
|
|
3
3
|
* @author Bart Busschots <opensource@bartificer.ie>
|
|
4
|
+
* @license MIT
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* The package
|
|
8
|
+
* The main module exposed in the npm package `@bartificer/linkify`. This module exposes the public interface, but does not implement any functionality.
|
|
8
9
|
*
|
|
10
|
+
* To understand the link generation functionality, the appropraite entry point into the code is the {@link module:linkifier.Linkifier} class.
|
|
11
|
+
* @summary The main module exposed in the npm package `@bartificer/linkify`.
|
|
9
12
|
* @module linkify
|
|
10
|
-
* @requires
|
|
11
|
-
* @requires
|
|
12
|
-
* @requires
|
|
13
|
-
* @requires
|
|
13
|
+
* @requires linkifier
|
|
14
|
+
* @requires link-data
|
|
15
|
+
* @requires link-template
|
|
16
|
+
* @requires page-data
|
|
17
|
+
* @see {@link module:linkifier.Linkifier} for the entry point into the link generation functionality.
|
|
18
|
+
* @example <caption>Basic Usage</caption>
|
|
19
|
+
* import { linkify } from '@bartificer/linkify';
|
|
20
|
+
*
|
|
21
|
+
* (async () => {
|
|
22
|
+
* console.log(await linkify.generateLink('https://github.com/bartificer'));
|
|
23
|
+
* // Output: <a href="https://github.com/bartificer" title="Bartificer Creations · GitHub">Bartificer Creations · GitHub</a>
|
|
24
|
+
* })();
|
|
14
25
|
*/
|
|
15
26
|
import { Linkifier } from "./Linkifier.class.mjs";
|
|
16
27
|
import { LinkData } from "./LinkData.class.mjs";
|
|
@@ -21,27 +32,51 @@ import { PageData } from "./PageData.class.mjs";
|
|
|
21
32
|
// === export the public API ===
|
|
22
33
|
//
|
|
23
34
|
|
|
24
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The module's current SEMVER version number.
|
|
37
|
+
* @type {string}
|
|
38
|
+
* @see {@link https://semver.org/}
|
|
39
|
+
*/
|
|
25
40
|
export const VERSION = process.env.VERSION; // Webpack replaces this line with the actual version string during build
|
|
26
41
|
|
|
27
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* An instantiated Linkifier object ready for use with the default settings as generated with the defauly constructor.
|
|
44
|
+
* @type {module:linkifier.Linkifier}
|
|
45
|
+
*/
|
|
28
46
|
export const linkify = new Linkifier();
|
|
29
47
|
|
|
30
48
|
export {
|
|
31
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* The Linkifier class that provides the core link generation functionality.
|
|
51
|
+
* @type {module:linkifier.Linkifier}
|
|
52
|
+
*/
|
|
32
53
|
Linkifier,
|
|
33
54
|
|
|
34
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* The data representation class capturing the information extracted from a web page, for example the page's title and headings.
|
|
57
|
+
* @type {module:page-data.PageData}
|
|
58
|
+
*/
|
|
35
59
|
PageData,
|
|
36
60
|
|
|
37
61
|
/**
|
|
38
|
-
* The
|
|
62
|
+
* The data representation class capturing the information about a link, for example its title and URL.
|
|
63
|
+
* @type {module:link-data.LinkData}
|
|
64
|
+
*/
|
|
39
65
|
LinkData,
|
|
40
66
|
|
|
41
67
|
/**
|
|
42
|
-
* The
|
|
68
|
+
* The class capturing the details of a template used to render links.
|
|
69
|
+
* @type {module:link-template.LinkTemplate}
|
|
70
|
+
*/
|
|
43
71
|
LinkTemplate
|
|
44
72
|
};
|
|
45
73
|
|
|
46
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* The default export, equivalent to the `linkify` named export.
|
|
76
|
+
* @name default
|
|
77
|
+
* @static
|
|
78
|
+
* @constant
|
|
79
|
+
* @type {module:linkifier.Linkifier}
|
|
80
|
+
* @see {@link module:linkify.linkify}
|
|
81
|
+
*/
|
|
47
82
|
export { linkify as default };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functions for converting information extracted from a web page into the information used to render links.
|
|
3
|
+
* @callback dataTransformer
|
|
4
|
+
* @param {module:page-data.PageData} pData - The web page data to be transrormed to link data.
|
|
5
|
+
* @returns {module:link-data.LinkData} The link information derived from the page data.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Functions for filtering template field values before their use to render links. Arbitrarily many of these functions can be added to a template in order to filter individual fields, or all fields.
|
|
10
|
+
* @callback templateFieldFilterFunction
|
|
11
|
+
* @param {string} originalString - the original value for the field to be filtered.
|
|
12
|
+
* @returns {string} the filtered version of the original string.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A tupple (array of length exactly two) for assigning a field filter to a template.
|
|
17
|
+
* @typedef {Array} templateFieldFilterTuple
|
|
18
|
+
* @property {"all"|"url"|"text"|"description"} 0 - the property the filter should be applied to.
|
|
19
|
+
* @property {templateFieldFilterFunction} 1 - the filter function to apply.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A plain object represeting the information about about link that can get utilised in a template.
|
|
24
|
+
*
|
|
25
|
+
* Note that the `uri` could contain more fields - it's initialised with output from the `URI.parse()` function from the `URI` module.
|
|
26
|
+
* @typedef {Object} plainLinkInformationObject
|
|
27
|
+
* @property {string} url - the URL for the link.
|
|
28
|
+
* @property {string} text - the text for the link.
|
|
29
|
+
* @property {string} description - a description for the link.
|
|
30
|
+
* @property {Object} uri - the URL's components
|
|
31
|
+
* @property {string} url.hostname - the hostname part of the URL.
|
|
32
|
+
* @property {string} url.path - the path part of the UL, `/` for an empty path.
|
|
33
|
+
* @property {boolean} url.hasPath - whether or not the URL has a path, note that `/` is considered no path.
|
|
34
|
+
* @see {@link https://medialize.github.io/URI.js/docs.html#static-parse}
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A plain object representing the infomration extracted from a web page.
|
|
39
|
+
*
|
|
40
|
+
* Note that the `uri` could contain more fields - it's initialised with output from the `URI.parse()` function from the `URI` module.
|
|
41
|
+
* @typedef {Object} plainPageInformationObject
|
|
42
|
+
* @property {string} url - the page's URL.
|
|
43
|
+
* @property {string} title - the page's title.
|
|
44
|
+
* @property {string[]} topLevelHeadings - the text from the page's `h1` tags.
|
|
45
|
+
* @property {string[]} secondaryHeadings - text from the page's `h2` tags.
|
|
46
|
+
* @property {string} mainHeading - the text from the most semantically important heading that exists in the page.
|
|
47
|
+
* @property {Object} uri - the URL's components
|
|
48
|
+
* @property {string} url.hostname - the hostname part of the URL.
|
|
49
|
+
* @property {string} url.path - the path part of the UL, `/` for an empty path.
|
|
50
|
+
* @property {boolean} url.hasPath - whether or not the URL has a path, note that `/` is considered no path.
|
|
51
|
+
* @see {@link https://medialize.github.io/URI.js/docs.html#static-parse}
|
|
52
|
+
*/
|
package/src/utilities.mjs
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file A collection of useful utility functions.
|
|
3
3
|
* @author Bart Busschots <opensource@bartificer.ie>
|
|
4
|
+
* @license MIT
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* Utility functions, intended both for use within the core link generation code, and, by users defining their own custom templates, transformer functions, and filter functions.
|
|
9
|
+
*
|
|
10
|
+
* This module is exposed to end-users as {@link module:linkifier.Linkifier#utilities} and {@link module:linkifier.Linkifier#util}.
|
|
8
11
|
* @module utilities
|
|
9
|
-
* @requires
|
|
12
|
+
* @requires defaults
|
|
10
13
|
* @requires module:urijs
|
|
11
14
|
* @requires module:url-slug
|
|
12
15
|
* @requires module:title-case
|
|
16
|
+
* @see {@link module:linkifier.Linkifier#utilities} for the short-cut to this module exposed on the Linkifier class.
|
|
17
|
+
* @see {@link module:linkifier.Linkifier#util} for the short-cut to this module exposed on the Linkifier class.
|
|
13
18
|
*/
|
|
14
19
|
import * as defaults from './defaults.mjs';
|
|
15
20
|
import URI from 'urijs';
|
|
@@ -20,27 +25,27 @@ import * as titleCase from 'title-case';
|
|
|
20
25
|
* Regularise white space by replacing all sequences of whitespace characters with a single space and trimming leading and trailing whitespace.
|
|
21
26
|
*
|
|
22
27
|
* @param {string} text
|
|
23
|
-
* @
|
|
28
|
+
* @returns {string}
|
|
24
29
|
*/
|
|
25
30
|
export function regulariseWhitespace(text){
|
|
26
31
|
return String(text).replace(/[\s\n]+/g, ' ').trim();
|
|
27
32
|
};
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
|
-
* Strip the query string from a URL.
|
|
35
|
+
* Strip the query string from a URL, if present.
|
|
31
36
|
*
|
|
32
|
-
* @param {string} url
|
|
33
|
-
* @
|
|
37
|
+
* @param {string} url - a URL with our without a query string.
|
|
38
|
+
* @returns {string} the original URL with the query string removed, if it was present.
|
|
34
39
|
*/
|
|
35
40
|
export function stripQueryString(url){
|
|
36
41
|
return URI(url).query('').toString();
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
|
-
* Remove UTM parameters from the query string in a URL.
|
|
45
|
+
* Remove UTM parameters from the query string in a URL, if present.
|
|
41
46
|
*
|
|
42
|
-
* @param {string} url
|
|
43
|
-
* @
|
|
47
|
+
* @param {string} url - a URL with or without UTM parameters in the query string.
|
|
48
|
+
* @returns {string} the original URL with the UTM parameters removed, if they were present, but with any other query parameters preserved.
|
|
44
49
|
* @see {@link https://en.wikipedia.org/wiki/UTM_parameters}
|
|
45
50
|
*/
|
|
46
51
|
export function stripUTMParameters(url){
|
|
@@ -53,7 +58,7 @@ export function stripUTMParameters(url){
|
|
|
53
58
|
* _**Note:** this is not a standard Javascript feature as of April 2026, though it is coming in future versions of Javascript._
|
|
54
59
|
*
|
|
55
60
|
* @param {string} str - the string to escape.
|
|
56
|
-
* @returns {string}
|
|
61
|
+
* @returns {string} the escaped string, ready for use in a regular expression.
|
|
57
62
|
* @see {@link https://stackoverflow.com/a/3561711/174985}
|
|
58
63
|
*/
|
|
59
64
|
export function escapeRegex(str) {
|
|
@@ -61,11 +66,12 @@ export function escapeRegex(str) {
|
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
/**
|
|
64
|
-
* Batch-
|
|
69
|
+
* Batch-fix words with special capitalisations in a string. E.g. force `fbi` to `FBI`, `ios` to `iOS`, etc..
|
|
65
70
|
*
|
|
66
|
-
* @param {string} str - the string to apply the
|
|
67
|
-
* @param {string[]} [words] -
|
|
68
|
-
* @returns {string}
|
|
71
|
+
* @param {string} str - the string to apply the capitalisation corrections to.
|
|
72
|
+
* @param {string[]} [words] - the list of words with special capitalisations. Defaults to the default list {@link module:defaults.speciallyCapitalisedWords}.
|
|
73
|
+
* @returns {string} the original string with all occurrences of the words in the list capitalised as per the word list. All other capitatlisations will be left un-changed.
|
|
74
|
+
* @see {@link module:defaults.speciallyCapitalisedWords} for the default list of custom capitalisations.
|
|
69
75
|
*/
|
|
70
76
|
export function batchFixCustomWordCases(str, words){
|
|
71
77
|
// coerce the first argument to a string
|
|
@@ -96,12 +102,47 @@ export function batchFixCustomWordCases(str, words){
|
|
|
96
102
|
return ans;
|
|
97
103
|
}
|
|
98
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Convert a string to title case, with some custom capitalisations.
|
|
107
|
+
*
|
|
108
|
+
* This functions uses the {@link module:title-case} to perform the initial title-caseing, and then applies the custom capitalisations to fix any words with unusual capitalisation requirements.
|
|
109
|
+
* All words this mododule defies as being so-called *small words* (e.g., "the", "a" & "an") are preserved in lower case, as well as the additional words defined in {@link module:defaults.smallWords}.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} str - the string to convert to title case.
|
|
112
|
+
* @param {string[]} [words] - a list of words with custom capitalisations to correct after title-casing. Defaults to {@link module:defaults.speciallyCapitalisedWords}.
|
|
113
|
+
* @returns {string} the original string converted to title case, with the custom capitalisations applied.
|
|
114
|
+
* @see {@link module:defaults.speciallyCapitalisedWords} for the default list of custom capitalisations.
|
|
115
|
+
* @see {@link module:title-case} for the Title Case module who's `titleCase()` function is used to convert to title case, and which has its own default list of small words that are preserved in lower case.
|
|
116
|
+
* @see {@link module:defaults.smallWords} for the additional list of small words that are preserved in lower case.
|
|
117
|
+
*/
|
|
118
|
+
export function toTitleCase(str, words){
|
|
119
|
+
// coerce the first argument to a string
|
|
120
|
+
let ans = String(str);
|
|
121
|
+
|
|
122
|
+
// add the additional small words
|
|
123
|
+
for (const smallWord of defaults.smallWords){
|
|
124
|
+
console.log(`adding smallWord: ${smallWord}`);
|
|
125
|
+
titleCase.SMALL_WORDS.add(smallWord);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// convert to title case
|
|
129
|
+
ans = titleCase.titleCase(ans);
|
|
130
|
+
|
|
131
|
+
// fix any words with unusual customisations
|
|
132
|
+
ans = batchFixCustomWordCases(ans, words);
|
|
133
|
+
|
|
134
|
+
// return the result
|
|
135
|
+
return ans;
|
|
136
|
+
}
|
|
137
|
+
|
|
99
138
|
/**
|
|
100
139
|
* Extract the slug from a URL and convert it to a title-case string.
|
|
101
140
|
*
|
|
102
|
-
* @param {string} url
|
|
103
|
-
* @param {string[]} [words] - a list of words with custom capitalisations to correct after title-casing.
|
|
104
|
-
* @
|
|
141
|
+
* @param {string} url - the URL to extract the slug from. The slug is taken to be the last segment of the path, with any file extension removed, and with the query string and fragment ignored.
|
|
142
|
+
* @param {string[]} [words] - a list of words with custom capitalisations to correct after title-casing. Defaults to {@link module:defaults.speciallyCapitalisedWords}.
|
|
143
|
+
* @returns {string} the slug extracted from the URL, converted to title case, with the custom capitalisations applied.
|
|
144
|
+
* @see {@link module:defaults.speciallyCapitalisedWords} for the default list of custom capitalisations.
|
|
145
|
+
* @see {@link toTitleCase} for the function used for the title-casing.
|
|
105
146
|
*/
|
|
106
147
|
export function extractSlug(url, words){
|
|
107
148
|
// TO DO - add validation
|
|
@@ -143,7 +184,7 @@ export function extractSlug(url, words){
|
|
|
143
184
|
title = titleCase.titleCase(title);
|
|
144
185
|
|
|
145
186
|
// fix any words with unusual customisations
|
|
146
|
-
title =
|
|
187
|
+
title = toTitleCase(title, words);
|
|
147
188
|
|
|
148
189
|
return title;
|
|
149
190
|
};
|