@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.
Files changed (102) hide show
  1. package/README.md +135 -35
  2. package/dist/index.js +1 -1
  3. package/docs/LinkData.class.mjs.html +119 -56
  4. package/docs/LinkTemplate.class.mjs.html +120 -36
  5. package/docs/Linkifier.class.mjs.html +141 -66
  6. package/docs/PageData.class.mjs.html +145 -72
  7. package/docs/defaults.mjs.html +136 -12
  8. package/docs/docdash-overrides.css +11 -0
  9. package/docs/externals.jsdoc.html +95 -4
  10. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  11. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  12. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  13. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  14. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  15. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  16. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  17. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  18. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  19. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  20. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  24. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  28. package/docs/global.html +1276 -0
  29. package/docs/index.html +1018 -26
  30. package/docs/index.js.html +143 -17
  31. package/docs/mermaid-init.js +21 -0
  32. package/docs/module-cheerio.html +193 -3
  33. package/docs/module-defaults.html +680 -3
  34. package/docs/module-link-data.LinkData.html +813 -0
  35. package/docs/module-link-data.html +226 -0
  36. package/docs/module-link-template.LinkTemplate.html +792 -0
  37. package/docs/module-link-template.html +226 -0
  38. package/docs/module-linkifier.Linkifier.html +2050 -0
  39. package/docs/module-linkifier.html +236 -0
  40. package/docs/module-linkify.html +810 -3
  41. package/docs/module-mustache.html +193 -3
  42. package/docs/module-node-fetch.html +193 -3
  43. package/docs/module-page-data.PageData.html +1810 -0
  44. package/docs/module-page-data.html +226 -0
  45. package/docs/module-title-case.html +193 -3
  46. package/docs/module-urijs.html +193 -3
  47. package/docs/module-url-slug.html +193 -3
  48. package/docs/module-utilities.html +1518 -3
  49. package/docs/scripts/collapse.js +39 -0
  50. package/docs/scripts/commonNav.js +28 -0
  51. package/docs/scripts/linenumber.js +25 -0
  52. package/docs/scripts/nav.js +12 -0
  53. package/docs/scripts/polyfill.js +4 -0
  54. package/docs/scripts/{third-party → prettify}/Apache-License-2.0.txt +202 -202
  55. package/docs/scripts/prettify/lang-css.js +2 -0
  56. package/docs/scripts/prettify/prettify.js +28 -0
  57. package/docs/scripts/search.js +99 -265
  58. package/docs/styles/jsdoc.css +776 -0
  59. package/docs/styles/prettify.css +80 -0
  60. package/docs/typedefs.jsdoc.html +145 -0
  61. package/docs/utilities.mjs.html +154 -22
  62. package/examples/clipboardURLToMarkdown.mjs +80 -1
  63. package/package.json +5 -3
  64. package/src/LinkData.class.mjs +24 -52
  65. package/src/LinkTemplate.class.mjs +25 -32
  66. package/src/Linkifier.class.mjs +46 -62
  67. package/src/PageData.class.mjs +50 -68
  68. package/src/defaults.mjs +42 -8
  69. package/src/index.js +48 -13
  70. package/src/typedefs.jsdoc +52 -0
  71. package/src/utilities.mjs +59 -18
  72. package/docs/data/search.json +0 -1
  73. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  74. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  75. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  76. package/docs/module-LinkData.LinkData.html +0 -13
  77. package/docs/module-LinkData.html +0 -3
  78. package/docs/module-LinkTemplate.LinkTemplate.html +0 -3
  79. package/docs/module-LinkTemplate.html +0 -3
  80. package/docs/module-Linkifier.Linkifier.html +0 -3
  81. package/docs/module-Linkifier.html +0 -3
  82. package/docs/module-PageData.PageData.html +0 -15
  83. package/docs/module-PageData.html +0 -3
  84. package/docs/scripts/core.js +0 -726
  85. package/docs/scripts/core.min.js +0 -23
  86. package/docs/scripts/resize.js +0 -90
  87. package/docs/scripts/search.min.js +0 -6
  88. package/docs/scripts/third-party/fuse.js +0 -9
  89. package/docs/scripts/third-party/hljs-line-num-original.js +0 -369
  90. package/docs/scripts/third-party/hljs-line-num.js +0 -1
  91. package/docs/scripts/third-party/hljs-original.js +0 -5171
  92. package/docs/scripts/third-party/hljs.js +0 -1
  93. package/docs/scripts/third-party/popper.js +0 -5
  94. package/docs/scripts/third-party/tippy.js +0 -1
  95. package/docs/scripts/third-party/tocbot.js +0 -672
  96. package/docs/scripts/third-party/tocbot.min.js +0 -1
  97. package/docs/styles/clean-jsdoc-theme-base.css +0 -1159
  98. package/docs/styles/clean-jsdoc-theme-dark.css +0 -412
  99. package/docs/styles/clean-jsdoc-theme-light.css +0 -482
  100. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -30
  101. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -1
  102. package/docs/styles/clean-jsdoc-theme.min.css +0 -1
@@ -1,25 +1,25 @@
1
1
  /**
2
- * @file The definition of the class representing a web page.
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 as class for representing the information extracted from web pages which can be used to generate the link data avaiable for rendering links.
8
- * @module PageData
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
- * A class representing the data extracted from web pages that can be transformed into link data for use when rendering links.
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
- * This constructor throws a {@link ValidationError} unless a valid URL is passed.
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 {URIObject}
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 {plainObject}
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
- * @returns {string}
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
- * @returns {Object} A URI.js object.
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
- * Get the domain-part of the URL as a string.
84
- *
85
- * @returns {string} The domain-part of the URL.
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
- * @returns {string} The path-part of the URL.
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
- * @returns {string}
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
- * Get the page's section headings.
114
- *
115
- * @returns {Object} A plain object containing arrays of strings indexed by `h1` and `h2`.
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
- * @returns {string[]}
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
- * @see PageData#topLevelHeadings
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
- * @returns {string[]}
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
- * @see PageData#secondaryHeadings
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
- * @returns {string} Heading text as a string, or an empty string.
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 of the form:
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 The default values used throughout the linkifier classes.
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
- * This module provides default values for use by the various linkifier functions and classes. These separated out for clarity, helping users decide which values to override or augment.
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 module:LinkTemplate
10
- * @requires module:utilities
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 collection of named link templates loaded by the Linkifier constructor.
17
- * @type {Object.<string, LinkTemplate>}
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
- * The default list of words with special capitalisations.
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 The module's entry point. This file determines what does and does not get exported by the module.
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 entry-point.
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 Linkifier
11
- * @requires LinkData
12
- * @requires LinkTemplate
13
- * @requires PageData
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
- /** The module's current SEMVER version number. */
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
- /** An instantiated Linkifier object ready for use. */
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
- /** The Linkifier class that encapsulates the link generations functionality. */
49
+ /**
50
+ * The Linkifier class that provides the core link generation functionality.
51
+ * @type {module:linkifier.Linkifier}
52
+ */
32
53
  Linkifier,
33
54
 
34
- /** The PageData class used to store webpage properties like title and headings. */
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 LinkData class use to store link properties like title and url. */
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 LinkTempalte class used for defining the templates for generating links. */
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
- /** The default export. */
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
- * This module provides utility functions which are both used by the core code, and, available for use by users when defining link data transformers and link templates.
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 module:defaults
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
- * @return {string}
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
- * @return {string}
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
- * @return {string}
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-customise word casings in a string. E.g. force `fbi` to `FBI`, `ios` to `iOS`, etc..
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 replacemnts to.
67
- * @param {string[]} [words] - an array of words in their desired capitalisations. Defaults to the default list of custom capitalisations.
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
- * @return {string}
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 = batchFixCustomWordCases(title, words);
187
+ title = toTitleCase(title, words);
147
188
 
148
189
  return title;
149
190
  };