extract-webpage 1.2.419 → 1.2.421

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 (39) hide show
  1. package/README.md +7 -1
  2. package/dist/extract-webpage.cjs.js +1 -1
  3. package/dist/extract-webpage.cjs.js.map +1 -1
  4. package/dist/extract-webpage.es.js +2 -4
  5. package/dist/extract-webpage.es.js.map +1 -1
  6. package/dist/html-to-content/highlight.d.ts +8 -0
  7. package/dist/index.d.ts +3 -2
  8. package/package.json +6 -6
  9. package/src/html-to-content/highlight.ts +59 -0
  10. package/src/html-to-content/html-to-content.ts +1 -2
  11. package/src/html-to-content/html-utils.ts +11 -20
  12. package/src/index.ts +5 -2
  13. package/src/url-to-content/docx-to-content.ts +9 -5
  14. package/dist/html-to-cite/extract-author.d.ts +0 -11
  15. package/dist/html-to-cite/extract-cite.d.ts +0 -33
  16. package/dist/html-to-cite/extract-date/date-extractors.d.ts +0 -40
  17. package/dist/html-to-cite/extract-date/date-validators.d.ts +0 -15
  18. package/dist/html-to-cite/extract-date/extract-date-quick.d.ts +0 -8
  19. package/dist/html-to-cite/extract-date/extract-date.d.ts +0 -26
  20. package/dist/html-to-cite/extract-source.d.ts +0 -11
  21. package/dist/html-to-cite/extract-title.d.ts +0 -11
  22. package/dist/html-to-cite/human-names-recognize.d.ts +0 -16
  23. package/dist/html-to-cite/metadata-to-cite.d.ts +0 -16
  24. package/dist/html-to-cite/url-to-domain.d.ts +0 -20
  25. package/dist/html-to-content/prism-global.d.ts +0 -12
  26. package/src/html-to-cite/extract-author.ts +0 -125
  27. package/src/html-to-cite/extract-cite.ts +0 -97
  28. package/src/html-to-cite/extract-date/date-extractors.ts +0 -484
  29. package/src/html-to-cite/extract-date/date-validators.ts +0 -191
  30. package/src/html-to-cite/extract-date/extract-date-quick.ts +0 -184
  31. package/src/html-to-cite/extract-date/extract-date.ts +0 -1049
  32. package/src/html-to-cite/extract-source.ts +0 -35
  33. package/src/html-to-cite/extract-title.ts +0 -78
  34. package/src/html-to-cite/human-names-92k.json +0 -1
  35. package/src/html-to-cite/human-names-recognize.ts +0 -396
  36. package/src/html-to-cite/metadata-to-cite.ts +0 -77
  37. package/src/html-to-cite/url-to-domain.ts +0 -50
  38. package/src/html-to-content/prism-global.d.ts +0 -40
  39. package/src/html-to-content/prism-global.ts +0 -82
@@ -1,191 +0,0 @@
1
- /**
2
- * @fileoverview Validation and filtering logic for extracted date candidates.
3
- * Ensures dates fall within plausible ranges and meet format requirements.
4
- */
5
-
6
- // Function cache
7
- var CACHE_SIZE = 8192;
8
- // earliest possible date to take into account (inclusive)
9
- var MIN_DATE = new Date(2002, 0, 0, 1); // Note: month is 0-indexed in JavaScript
10
-
11
- var DEBUG = 0;
12
-
13
- const LOGGER = DEBUG ? console : { debug: () => { }, log: () => { }, error: () => { }, warn: () => { } };
14
-
15
- function is_valid_date(date_input, outputformat, earliest, latest) {
16
- // safety check
17
- if (date_input === null) {
18
- return false;
19
- }
20
- if (!earliest || !earliest.getFullYear)
21
- earliest = new Date(2002, 0, 0, 1);
22
- if (!latest)
23
- latest = new Date();
24
-
25
- let dateobject;
26
- if (date_input instanceof Date) {
27
- dateobject = date_input;
28
- } else {
29
- try {
30
- if (outputformat === 'YYYY-MM-DD') {
31
- dateobject = new Date(date_input.slice(0, 4), date_input.slice(5, 7) - 1, date_input.slice(8, 10));
32
- } else {
33
- dateobject = new Date(date_input);
34
- }
35
- } catch (error) {
36
- return false;
37
- }
38
- }
39
-
40
- if (
41
- earliest.getFullYear() <= dateobject.getFullYear() &&
42
- dateobject.getFullYear() <= latest.getFullYear() &&
43
- earliest.getTime() <= dateobject.getTime() &&
44
- dateobject.getTime() <= latest.getTime()
45
- ) {
46
- return true;
47
- }
48
- LOGGER.debug(`date not valid: ${date_input}`);
49
- return false;
50
- }
51
-
52
- function is_valid_format(outputformat) {
53
- // test with date object
54
- var dateobject = new Date(2017, 8, 1, 0, 0);
55
- try {
56
- dateobject.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
57
- } catch (err) {
58
- LOGGER.error(`wrong output format or type: ${outputformat} ${err}`);
59
- return false;
60
- }
61
- // test in abstracto (could be the only test)
62
- if (typeof outputformat !== 'string' || !outputformat.includes('%')) {
63
- LOGGER.error(`malformed output format: ${outputformat}`);
64
- return false;
65
- }
66
- return true;
67
- }
68
-
69
- function plausible_year_filter(htmlstring, pattern, yearpat, earliest, latest, incomplete = false) {
70
- var occurrences = new Map();
71
-
72
-
73
- if (!htmlstring)
74
- return occurrences;
75
-
76
- var matches = htmlstring.match(new RegExp(pattern, 'g')) || [];
77
-
78
- matches.forEach(item => {
79
- var count = occurrences.get(item) || 0;
80
- occurrences.set(item, count + 1);
81
- });
82
-
83
- for (var [item, count] of occurrences) {
84
- var year_match = item.match(yearpat);
85
- if (!year_match) {
86
- LOGGER.debug(`not a year pattern: ${item}`);
87
- occurrences.delete(item);
88
- continue;
89
- }
90
-
91
- var lastdigits = year_match[1];
92
- let potential_year;
93
- if (!incomplete) {
94
- potential_year = parseInt(lastdigits);
95
- } else {
96
- var century = lastdigits[0] === '9' ? '19' : '20';
97
- potential_year = parseInt(century + lastdigits);
98
- }
99
-
100
- if (!(earliest.getFullYear() <= potential_year && potential_year <= latest.getFullYear())) {
101
- LOGGER.debug(`no potential year: ${item}`);
102
- occurrences.delete(item);
103
- }
104
- }
105
-
106
- return occurrences;
107
- }
108
-
109
- function compare_values(reference, attempt, options) {
110
- try {
111
- var timestamp = new Date(attempt).getTime() / 1000;
112
- if (options.original) {
113
- reference = reference ? Math.min(reference, timestamp) : timestamp;
114
- } else {
115
- reference = Math.max(reference, timestamp);
116
- }
117
- } catch (err) {
118
- LOGGER.debug(`Date parsing exception: ${err} for string ${attempt}`);
119
- }
120
- return reference;
121
- }
122
-
123
- function filter_ymd_candidate(bestmatch, pattern, original_date, copyear, outputformat, min_date, max_date) {
124
- if (bestmatch) {
125
- var pagedate = `${bestmatch[1]}-${bestmatch[2]}-${bestmatch[3]}`;
126
- if (is_valid_date(pagedate, 'YYYY-MM-DD', min_date, max_date) &&
127
- (copyear === 0 || parseInt(bestmatch[1]) >= copyear)) {
128
- LOGGER.debug(`date found for pattern "${pattern}": ${pagedate}`);
129
- return convert_date(pagedate, 'YYYY-MM-DD', outputformat);
130
- }
131
- }
132
- return null;
133
- }
134
-
135
- function convert_date(datestring, inputformat, outputformat) {
136
- if (inputformat === outputformat) {
137
- return datestring;
138
- }
139
- if (datestring instanceof Date) {
140
- return datestring.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
141
- }
142
- var dateobject = new Date(datestring);
143
- return dateobject.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
144
- }
145
-
146
- function check_extracted_reference(reference, options) {
147
- if (reference > 0) {
148
- var dateobject = new Date(reference * 1000);
149
- var converted = dateobject.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
150
- if (is_valid_date(converted, options.format, options.min, options.max)) {
151
- return converted;
152
- }
153
- }
154
- return null;
155
- }
156
-
157
- function check_date_input(date_object, default_date) {
158
- if (date_object instanceof Date) {
159
- return date_object;
160
- }
161
- if (typeof date_object === 'string') {
162
- try {
163
- return new Date(date_object);
164
- } catch (error) {
165
- LOGGER.warn(`invalid datetime string: ${date_object}`);
166
- }
167
- }
168
- return default_date;
169
- }
170
-
171
- function get_min_date(min_date) {
172
- return check_date_input(min_date, MIN_DATE);
173
- }
174
-
175
- function get_max_date(max_date) {
176
- return check_date_input(max_date, new Date());
177
- }
178
-
179
-
180
- export {
181
- is_valid_date,
182
- is_valid_format,
183
- plausible_year_filter,
184
- compare_values,
185
- filter_ymd_candidate,
186
- convert_date,
187
- check_extracted_reference,
188
- check_date_input,
189
- get_min_date,
190
- get_max_date
191
- };
@@ -1,184 +0,0 @@
1
- /**
2
- * @fileoverview High-performance date extraction utility for HTML documents.
3
- * Prioritizes meta tags, specific selectors, and URL patterns for fast results.
4
- */
5
- // Constants
6
- const DATE_PUBLISHED_META_TAGS = [
7
- 'article:published_time',
8
- 'displaydate',
9
- 'dc.date',
10
- 'dc.date.issued',
11
- 'rbpubdate',
12
- 'publish_date',
13
- 'pub_date',
14
- 'pagedate',
15
- 'pubdate',
16
- 'revision_date',
17
- 'doc_date',
18
- 'date_created',
19
- 'content_create_date',
20
- 'lastmodified',
21
- 'created',
22
- 'date',
23
- ];
24
-
25
- const DATE_PUBLISHED_SELECTORS = [
26
- '.hentry .dtstamp.published',
27
- '.hentry .published',
28
- '.hentry .dtstamp.updated',
29
- '.hentry .updated',
30
- '.single .published',
31
- '.meta .published',
32
- '.meta .postDate',
33
- '.entry-date',
34
- '.byline .date',
35
- '.postmetadata .date',
36
- '.article_datetime',
37
- '.date-header',
38
- '.story-date',
39
- '.dateStamp',
40
- '#story .datetime',
41
- '.dateline',
42
- '.pubdate',
43
- ];
44
-
45
- const abbrevMonthsStr = '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)';
46
- const DATE_PUBLISHED_URL_RES = [
47
- new RegExp('/(20\\d{2}/\\d{2}/\\d{2})/', 'i'),
48
- new RegExp('(20\\d{2}-[01]\\d-[0-3]\\d)', 'i'),
49
- new RegExp(`/(20\\d{2}/${abbrevMonthsStr}/[0-3]\\d)/`, 'i'),
50
- ];
51
-
52
- const MS_DATE_STRING = /^\d{13}$/;
53
- const SEC_DATE_STRING = /^\d{10}$/;
54
- const CLEAN_DATE_STRING_RE = /^(.+?)(?: [a-z]{3})?(?::\d{2}| \d{4})? (?:[a-z]{3} )?[a-z]{3}$/i;
55
- const TIME_AGO_STRING = /(\d+)\s+(.*?)\s+ago/;
56
- const TIME_NOW_STRING = /^\s*(now|\d{1,2}\s*min(ute)?s?)\s*$/i;
57
-
58
- /**
59
- * Extract date from document using various methods
60
- *
61
- * @param {Document} document - DOM object with article content
62
- * @param {string} url - URL of the page
63
- * @returns {string|null} Extracted date or null if not found
64
- */
65
- export function extractDateQuick(document, url) {
66
- let datePublished;
67
-
68
- // Helper function to extract content from meta tags
69
- function extractFromMeta(tags) {
70
- for (const tag of tags) {
71
- const metaTag = document.querySelector(`meta[name="${tag}"], meta[property="${tag}"]`);
72
- if (metaTag) {
73
- return metaTag.getAttribute('content');
74
- }
75
- }
76
- return null;
77
- }
78
-
79
- // Helper function to extract content from selectors
80
- function extractFromSelectors(selectors) {
81
- for (const selector of selectors) {
82
- const element = document.querySelector(selector);
83
- if (element) {
84
- return element.textContent.trim();
85
- }
86
- }
87
- return null;
88
- }
89
-
90
- // 1. Check meta tags
91
- datePublished = extractFromMeta(DATE_PUBLISHED_META_TAGS);
92
- if (datePublished) return cleanDatePublished(datePublished);
93
-
94
- // 2. Check selectors
95
- datePublished = extractFromSelectors(DATE_PUBLISHED_SELECTORS);
96
- if (datePublished) return cleanDatePublished(datePublished);
97
-
98
- // 3. Check URL
99
- for (const regex of DATE_PUBLISHED_URL_RES) {
100
- const match = url.match(regex);
101
- if (match) {
102
- return cleanDatePublished(match[1]);
103
- }
104
- }
105
-
106
- // 4. Check for specific text patterns
107
- const textPatterns = ['Published', 'Updated', 'Posted'];
108
- for (const pattern of textPatterns) {
109
- for (const tag of ['time', 'span', 'div', 'p']) {
110
- const elements = document.getElementsByTagName(tag);
111
- for (const el of elements) {
112
- if (el.textContent.includes(pattern)) {
113
- datePublished = el.textContent.split(pattern)[1].trim();
114
- if (datePublished) return cleanDatePublished(datePublished);
115
- }
116
- }
117
- }
118
- }
119
-
120
- return null;
121
- }
122
-
123
- function cleanDatePublished(dateString) {
124
- // If string is in milliseconds or seconds, convert to int and return
125
- if (MS_DATE_STRING.test(dateString)) {
126
- return new Date(parseInt(dateString, 10)).toISOString();
127
- }
128
- if (SEC_DATE_STRING.test(dateString)) {
129
- return new Date(parseInt(dateString, 10) * 1000).toISOString();
130
- }
131
-
132
- dateString = cleanDateString(dateString);
133
-
134
- return dateString
135
- }
136
-
137
- function cleanDateString(dateString) {
138
- return dateString?.replace(CLEAN_DATE_STRING_RE, '$1').trim();
139
- }
140
-
141
- function createDate(dateString) {
142
- if (TIME_AGO_STRING.test(dateString)) {
143
- const [, amount, unit] = TIME_AGO_STRING.exec(dateString);
144
- const now = new Date();
145
- now.setMilliseconds(0);
146
- switch (unit?.toLowerCase()) {
147
- case 'second':
148
- case 'seconds':
149
- now.setSeconds(now.getSeconds() - parseInt(amount));
150
- break;
151
- case 'minute':
152
- case 'minutes':
153
- now.setMinutes(now.getMinutes() - parseInt(amount));
154
- break;
155
- case 'hour':
156
- case 'hours':
157
- now.setHours(now.getHours() - parseInt(amount));
158
- break;
159
- case 'day':
160
- case 'days':
161
- now.setDate(now.getDate() - parseInt(amount));
162
- break;
163
- case 'week':
164
- case 'weeks':
165
- now.setDate(now.getDate() - parseInt(amount) * 7);
166
- break;
167
- case 'month':
168
- case 'months':
169
- now.setMonth(now.getMonth() - parseInt(amount));
170
- break;
171
- case 'year':
172
- case 'years':
173
- now.setFullYear(now.getFullYear() - parseInt(amount));
174
- break;
175
- }
176
- return now;
177
- }
178
-
179
- if (TIME_NOW_STRING.test(dateString)) {
180
- return new Date();
181
- }
182
-
183
- return new Date(dateString);
184
- }