@jocmp/mercury-parser 3.0.0 → 3.0.2

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.
@@ -4613,31 +4613,31 @@ var WwwSlateComExtractor = {
4613
4613
  var IciRadioCanadaCaExtractor = {
4614
4614
  domain: 'ici.radio-canada.ca',
4615
4615
  title: {
4616
- selectors: ['h1']
4616
+ selectors: [['meta[name="dc.title"]', 'value']]
4617
4617
  },
4618
4618
  author: {
4619
4619
  selectors: [['meta[name="dc.creator"]', 'value']]
4620
4620
  },
4621
4621
  date_published: {
4622
- selectors: [['meta[name="dc.date.created"]', 'value']],
4623
- format: 'YYYY-MM-DD|HH[h]mm',
4624
- timezone: 'America/New_York'
4622
+ selectors: [['meta[name="dc.date.created"]', 'value']]
4625
4623
  },
4626
4624
  dek: {
4627
- selectors: ['div.lead-container', '.bunker-component.lead']
4625
+ selectors: [['meta[name="description"]', 'value']]
4628
4626
  },
4629
4627
  lead_image_url: {
4630
4628
  selectors: [['meta[name="og:image"]', 'value']]
4631
4629
  },
4632
4630
  content: {
4633
- selectors: ['section.document-content-style', ['.main-multimedia-item', '.news-story-content']],
4634
- // Is there anything in the content you selected that needs transformed
4635
- // before it's consumable content? E.g., unusual lazy loaded images
4636
- transforms: {},
4637
- // Is there anything that is in the result that shouldn't be?
4638
- // The clean selectors will remove anything that matches from
4639
- // the result
4640
- clean: []
4631
+ selectors: ['article main', 'article'],
4632
+ transforms: {
4633
+ h2: function h2(node) {
4634
+ return node.attr('class', 'mercury-parser-keep');
4635
+ },
4636
+ ul: function ul(node) {
4637
+ return node.attr('class', 'mercury-parser-keep');
4638
+ }
4639
+ },
4640
+ clean: ['header', 'nav', 'button', 'figcaption', '[class*="adBox"]', '.framed']
4641
4641
  }
4642
4642
  };
4643
4643
  var WwwFortinetComExtractor = {
@@ -6883,12 +6883,6 @@ var WwwVortezNetExtractor = {
6883
6883
  title: {
6884
6884
  selectors: ['title']
6885
6885
  },
6886
- author: {
6887
- selectors: []
6888
- },
6889
- date_published: {
6890
- selectors: []
6891
- },
6892
6886
  dek: {
6893
6887
  selectors: []
6894
6888
  },
@@ -7244,6 +7238,50 @@ var WwwNumeramaComExtractor = {
7244
7238
  clean: ['.js-newsletter-block', '.premium-promo-alert', '[data-nosnippet]', '.ultimedia_cntr']
7245
7239
  }
7246
7240
  };
7241
+ var TerminaltroveComExtractor = {
7242
+ domain: 'terminaltrove.com',
7243
+ title: {
7244
+ selectors: [['meta[name="og:title"]', 'value']]
7245
+ },
7246
+ dek: {
7247
+ selectors: [['meta[name="og:description"]', 'value']]
7248
+ },
7249
+ lead_image_url: {
7250
+ selectors: [['meta[name="og:image"]', 'value']]
7251
+ },
7252
+ content: {
7253
+ selectors: ['main'],
7254
+ clean: ['.share-badge', '.modal', '.modal-toggle', '.sr-only', '.premium-sponsor-featured']
7255
+ }
7256
+ };
7257
+ var NewsPtsOrgTwExtractor = {
7258
+ domain: 'news.pts.org.tw',
7259
+ title: {
7260
+ selectors: ['h1.article-title']
7261
+ },
7262
+ author: {
7263
+ selectors: [['meta[name="author"]', 'content'], ['meta[name="author"]', 'value']]
7264
+ },
7265
+ date_published: {
7266
+ selectors: [['meta[property="article:published_time"]', 'content'], ['meta[name="article:published_time"]', 'value']]
7267
+ },
7268
+ dek: {
7269
+ selectors: [['meta[name="description"]', 'content'], ['meta[name="description"]', 'value']]
7270
+ },
7271
+ lead_image_url: {
7272
+ selectors: [['meta[property="og:image"]', 'content'], ['meta[name="og:image"]', 'value']]
7273
+ },
7274
+ content: {
7275
+ selectors: ['.post-article', '.article-content'],
7276
+ // Is there anything in the content you selected that needs transformed
7277
+ // before it's consumable content? E.g., unusual lazy loaded images
7278
+ transforms: {},
7279
+ // Is there anything that is in the result that shouldn't be?
7280
+ // The clean selectors will remove anything that matches from
7281
+ // the result
7282
+ clean: ['.articleimg', 'ul']
7283
+ }
7284
+ };
7247
7285
  var CustomExtractors = /*#__PURE__*/_Object$freeze__default["default"]({
7248
7286
  __proto__: null,
7249
7287
  BloggerExtractor: BloggerExtractor,
@@ -7431,7 +7469,9 @@ var CustomExtractors = /*#__PURE__*/_Object$freeze__default["default"]({
7431
7469
  GonintendoComExtractor: GonintendoComExtractor,
7432
7470
  OrfAtExtractor: OrfAtExtractor,
7433
7471
  WwwVideogameschronicleComExtractor: WwwVideogameschronicleComExtractor,
7434
- WwwNumeramaComExtractor: WwwNumeramaComExtractor
7472
+ WwwNumeramaComExtractor: WwwNumeramaComExtractor,
7473
+ TerminaltroveComExtractor: TerminaltroveComExtractor,
7474
+ NewsPtsOrgTwExtractor: NewsPtsOrgTwExtractor
7435
7475
  });
7436
7476
  function ownKeys$5(e, r) {
7437
7477
  var t = _Object$keys__default["default"](e);
@@ -1 +1 @@
1
- {"version":3,"file":"generate-custom-parser.js","sources":["../src/utils/dom/constants.js","../src/utils/dom/get-attrs.js","../src/utils/dom/strip-junk-tags.js","../src/utils/dom/set-attr.js","../src/utils/dom/make-links-absolute.js","../scripts/templates/insert-values.js","../scripts/templates/index.js","../scripts/templates/custom-extractor.js","../scripts/templates/custom-extractor-test.js","../scripts/generate-custom-parser.js"],"sourcesContent":["// Spacer images to be removed\nexport const SPACER_RE = new RegExp('transparent|spacer|blank', 'i');\n\n// The class we will use to mark elements we want to keep\n// but would normally remove\nexport const KEEP_CLASS = 'mercury-parser-keep';\n\nexport const KEEP_SELECTORS = [\n 'iframe[src^=\"https://www.youtube.com\"]',\n 'iframe[src^=\"https://www.youtube-nocookie.com\"]',\n 'iframe[src^=\"http://www.youtube.com\"]',\n 'iframe[src^=\"https://player.vimeo\"]',\n 'iframe[src^=\"http://player.vimeo\"]',\n 'iframe[src^=\"https://www.redditmedia.com\"]',\n];\n\n// A list of tags to strip from the output if we encounter them.\nexport const STRIP_OUTPUT_TAGS = [\n 'title',\n 'script',\n 'noscript',\n 'link',\n 'style',\n 'hr',\n 'embed',\n 'iframe',\n 'object',\n];\n\n// cleanAttributes\nexport const REMOVE_ATTRS = ['style', 'align'];\nexport const REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(\n selector => `[${selector}]`\n);\nexport const REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nexport const WHITELIST_ATTRS = [\n 'src',\n 'srcset',\n 'start',\n 'sizes',\n 'type',\n 'href',\n 'class',\n 'id',\n 'alt',\n 'xlink:href',\n 'width',\n 'height',\n];\n\nexport const WHITELIST_ATTRS_RE = new RegExp(\n `^(${WHITELIST_ATTRS.join('|')})$`,\n 'i'\n);\n\n// removeEmpty\nexport const REMOVE_EMPTY_TAGS = ['p'];\nexport const REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(\n tag => `${tag}:empty`\n).join(',');\n\n// cleanTags\nexport const CLEAN_CONDITIONALLY_TAGS = [\n 'ul',\n 'ol',\n 'table',\n 'div',\n 'button',\n 'form',\n].join(',');\n\n// cleanHeaders\nconst HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nexport const HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n // 'form', // This is too generic, has too many false positives\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'outbrain',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'taboola',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE = new RegExp(\n `^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`,\n 'i'\n);\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = ['figure', 'photo', 'image', 'caption'];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(\n POSITIVE_SCORE_HINTS.join('|'),\n 'i'\n);\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(\n NEGATIVE_SCORE_HINTS.join('|'),\n 'i'\n);\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nexport const IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nexport const EXTRANEOUS_LINK_HINTS = [\n 'print',\n 'archive',\n 'comment',\n 'discuss',\n 'e-mail',\n 'email',\n 'share',\n 'reply',\n 'all',\n 'login',\n 'sign',\n 'single',\n 'adx',\n 'entry-unrelated',\n];\nexport const EXTRANEOUS_LINK_HINTS_RE = new RegExp(\n EXTRANEOUS_LINK_HINTS.join('|'),\n 'i'\n);\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nexport const PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\n// export const NEXT_LINK_TEXT_RE = new RegExp('(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))', 'i');\nexport const NEXT_LINK_TEXT_RE = /(next|weiter|continue|>([^|]|$)|»([^|]|$))/i;\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nexport const CAP_LINK_TEXT_RE = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nexport const PREV_LINK_TEXT_RE = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(\n `^(${BLOCK_LEVEL_TAGS.join('|')})$`,\n 'i'\n);\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(\n `!(${candidatesWhitelist})|(${candidatesBlacklist})`,\n 'i'\n);\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","export default function getAttrs(node) {\n const { attribs, attributes } = node;\n\n if (!attribs && attributes) {\n const attrs = Reflect.ownKeys(attributes).reduce((acc, index) => {\n const attr = attributes[index];\n\n // In browser, Reflect.ownKeys includes non-numeric keys like 'length', 'item', etc.\n if (!attr || !attr.name || !attr.value) return acc;\n\n acc[attr.name] = attr.value;\n return acc;\n }, {});\n return attrs;\n }\n\n return attribs;\n}\n","import { STRIP_OUTPUT_TAGS, KEEP_CLASS } from './constants';\n\nexport default function stripJunkTags(article, $, tags = []) {\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n // Remove matching elements, but ignore\n // any element with a class of mercury-parser-keep\n $(tags.join(','), article)\n .not(`.${KEEP_CLASS}`)\n .remove();\n\n return $;\n}\n","export default function setAttr(node, attr, val) {\n if (node.attribs) {\n node.attribs[attr] = val;\n } else if (node.attributes) {\n node.setAttribute(attr, val);\n }\n\n return node;\n}\n","import URL from 'url';\n\nimport getAttrs from './get-attrs';\nimport setAttr from './set-attr';\n\nfunction absolutize($, rootUrl, attr) {\n const baseUrl = $('base').attr('href');\n\n $(`[${attr}]`).each((_, node) => {\n const attrs = getAttrs(node);\n const url = attrs[attr];\n if (!url) return;\n const absoluteUrl = URL.resolve(baseUrl || rootUrl, url);\n\n setAttr(node, attr, absoluteUrl);\n });\n}\n\nfunction absolutizeSet($, rootUrl, $content) {\n $('[srcset]', $content).each((_, node) => {\n const attrs = getAttrs(node);\n const urlSet = attrs.srcset;\n\n if (urlSet) {\n // a comma should be considered part of the candidate URL unless preceded by a descriptor\n // descriptors can only contain positive numbers followed immediately by either 'w' or 'x'\n // space characters inside the URL should be encoded (%20 or +)\n const candidates = urlSet.match(\n /(?:\\s*)(\\S+(?:\\s*[\\d.]+[wx])?)(?:\\s*,\\s*)?/g\n );\n if (!candidates) return;\n const absoluteCandidates = candidates.map(candidate => {\n // a candidate URL cannot start or end with a comma\n // descriptors are separated from the URLs by unescaped whitespace\n const parts = candidate\n .trim()\n .replace(/,$/, '')\n .split(/\\s+/);\n parts[0] = URL.resolve(rootUrl, parts[0]);\n return parts.join(' ');\n });\n const absoluteUrlSet = [...new Set(absoluteCandidates)].join(', ');\n setAttr(node, 'srcset', absoluteUrlSet);\n }\n });\n}\n\nexport default function makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(attr => absolutize($, url, attr));\n absolutizeSet($, url, $content);\n\n return $content;\n}\n","export default function insertValues(strings, ...values) {\n if (values.length) {\n return strings.reduce((result, part, idx) => {\n let value = values[idx];\n\n if (value && typeof value.toString === 'function') {\n value = value.toString();\n } else {\n value = '';\n }\n\n return result + part + value;\n }, '');\n }\n\n return strings.join('');\n}\n","import insertValues from './insert-values';\n\nconst bodyPattern = /^\\n([\\s\\S]+)\\s{2}$/gm;\nconst trailingWhitespace = /\\s+$/;\n\nexport default function template(strings, ...values) {\n const compiled = insertValues(strings, ...values);\n let [body] = compiled.match(bodyPattern) || [];\n let indentLevel = /^\\s{0,4}(.+)$/g;\n\n if (!body) {\n body = compiled;\n indentLevel = /^\\s{0,2}(.+)$/g;\n }\n\n return body\n .split('\\n')\n .slice(1)\n .map(line => {\n line = line.replace(indentLevel, '$1');\n\n if (trailingWhitespace.test(line)) {\n line = line.replace(trailingWhitespace, '');\n }\n\n return line;\n })\n .join('\\n');\n}\n","import template from './index';\n\nexport default function(hostname, name) {\n return template`\n export const ${name} = {\n domain: '${hostname}',\n\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n }\n `;\n}\n","import template from './index';\n\nconst IGNORE = [\n 'url',\n 'domain',\n 'content',\n 'word_count',\n 'next_page_url',\n 'excerpt',\n 'direction',\n 'total_pages',\n 'rendered_pages',\n];\n\nfunction testFor(key, value, dir) {\n if (IGNORE.find(k => k === key)) return '';\n\n return template`\n it('returns the ${key}', async () => {\n // To pass this test, fill out the ${key} selector\n // in ${dir}/index.js.\n const { ${key} } = await result\n\n // Update these values with the expected values from\n // the article.\n assert.strictEqual(${key}, ${value ? `\\`${value}\\`` : \"''\"})\n });\n `;\n}\n\nexport default function(file, url, dir, result, name) {\n return template`\n import assert from 'assert';\n import * as cheerio from 'cheerio';\n\n import Parser from 'mercury';\n import getExtractor from 'extractors/get-extractor';\n import { excerptContent } from 'utils/text';\n\n const fs = require('fs');\n\n describe('${name}', () => {\n describe('initial test case', () => {\n let result;\n let url;\n beforeAll(() => {\n url =\n '${url}';\n const html =\n fs.readFileSync('${file}');\n result =\n Parser.parse(url, { html, fallback: false });\n });\n\n it('is selected properly', () => {\n // This test should be passing by default.\n // It sanity checks that the correct parser\n // is being selected for URLs from this domain\n const extractor = getExtractor(url);\n assert.strictEqual(extractor.domain, new URL(url).hostname)\n })\n\n ${Reflect.ownKeys(result)\n .map(k => testFor(k, result[k], dir))\n .join('\\n\\n')}\n\n it('returns the content', async () => {\n // To pass this test, fill out the content selector\n // in ${dir}/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const { content } = await result;\n\n const $ = cheerio.load(content || '');\n\n const first13 = excerptContent($('*').first().text(), 13)\n\n // Update these values with the expected values from the article.\n // Add the first 13 words of the article here\n assert.strictEqual(first13, null);\n });\n });\n });\n `;\n}\n","/* eslint-disable import/no-extraneous-dependencies */\n/* eslint-disable no-use-before-define */\n/* eslint-disable no-console */\nimport fs from 'fs';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport { exec } from 'child_process';\n\nimport { stripJunkTags, makeLinksAbsolute } from 'utils/dom';\nimport Parser from '../dist/mercury';\nimport extractorTemplate from './templates/custom-extractor';\nimport extractorTestTemplate from './templates/custom-extractor-test';\n\nconst questions = [\n {\n type: 'input',\n name: 'website',\n message:\n \"Paste a url to an article you'd like to create or extend a parser for:\",\n validate(value) {\n const { hostname } = new URL(value);\n if (hostname) return true;\n\n return false;\n },\n },\n];\nlet spinner;\n\nfunction confirm(fn, args, msg, newParser) {\n spinner = ora({ text: msg });\n spinner.start();\n const result = fn(...args);\n\n if (result && result.then) {\n result.then(r => savePage(r, args, newParser));\n } else {\n spinner.succeed();\n }\n\n return result;\n}\n\nfunction confirmCreateDir(dir, msg) {\n if (!fs.existsSync(dir)) {\n confirm(fs.mkdirSync, [dir], msg);\n }\n}\n\nfunction getDir(url) {\n const { hostname } = new URL(url);\n return `./src/extractors/custom/${hostname}`;\n}\n\nfunction scaffoldCustomParser(url) {\n const dir = getDir(url);\n const { hostname } = new URL(url);\n let newParser = false;\n\n if (!fs.existsSync(dir)) {\n newParser = true;\n confirmCreateDir(dir, `Creating ${hostname} directory`);\n confirmCreateDir(`./fixtures/${hostname}`, 'Creating fixtures directory');\n }\n\n confirm(Parser.fetchResource, [url], 'Fetching fixture', newParser);\n}\n\n// if has arg, just assume that arg is a url and skip prmopt\nconst urlArg = process.argv[2];\nif (urlArg) {\n scaffoldCustomParser(urlArg);\n} else {\n inquirer.prompt(questions).then(answers => {\n scaffoldCustomParser(answers.website);\n });\n}\n\nfunction generateScaffold(url, file, result) {\n const { hostname } = new URL(url);\n const extractor = extractorTemplate(hostname, extractorName(hostname));\n const extractorTest = extractorTestTemplate(\n file,\n url,\n getDir(url),\n result,\n extractorName(hostname)\n );\n\n fs.writeFileSync(`${getDir(url)}/index.js`, extractor);\n fs.writeFileSync(`${getDir(url)}/index.test.js`, extractorTest);\n fs.appendFileSync('./src/extractors/custom/index.js', exportString(url));\n exec(`npm run lint-fix-quiet -- ${getDir(url)}/*.js`);\n}\n\nfunction savePage($, [url], newParser) {\n const { hostname } = new URL(url);\n\n spinner.succeed();\n\n const filename = new Date().getTime();\n const file = `./fixtures/${hostname}/${filename}.html`;\n // fix http(s) relative links:\n makeLinksAbsolute($('*').first(), $, url);\n $('[src], [href]').each((index, node) => {\n const $node = $(node);\n const link = $node.attr('src');\n if (link && link.slice(0, 2) === '//') {\n $node.attr('src', `http:${link}`);\n }\n });\n const html = stripJunkTags($('*').first(), $, ['script']).html();\n\n fs.writeFileSync(file, html);\n\n Parser.parse(url, { html }).then(result => {\n if (newParser) {\n confirm(\n generateScaffold,\n [url, file, result],\n 'Generating parser and tests'\n );\n console.log(`Your custom site extractor has been set up. To get started building it, run\n yarn watch:test -- ${hostname}\n -- OR --\n npm run watch:test -- ${hostname}`);\n } else {\n console.log(`\n It looks like you already have a custom parser for this url.\n The page you linked to has been added to ${file}. Copy and paste\n the following code to use that page in your tests:\n const html = fs.readFileSync('${file}');`);\n }\n });\n}\n\nfunction exportString(url) {\n const { hostname } = new URL(url);\n return `export * from './${hostname}';`;\n}\n\nfunction extractorName(hostname) {\n const name = hostname\n .split('.')\n .map(w => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)\n .join('');\n return `${name}Extractor`;\n}\n"],"names":["KEEP_CLASS","STRIP_OUTPUT_TAGS","getAttrs","node","attribs","attributes","attrs","_Reflect$ownKeys","reduce","acc","index","attr","name","value","stripJunkTags","article","$","tags","arguments","length","undefined","join","not","concat","remove","setAttr","val","setAttribute","absolutize","rootUrl","baseUrl","each","_","url","absoluteUrl","URL","resolve","absolutizeSet","$content","urlSet","srcset","candidates","match","absoluteCandidates","map","candidate","parts","trim","replace","split","absoluteUrlSet","_toConsumableArray","_Set","makeLinksAbsolute","forEach","insertValues","strings","_len","values","Array","_key","result","part","idx","toString","bodyPattern","trailingWhitespace","template","compiled","apply","_ref","_ref2","_slicedToArray","body","indentLevel","slice","line","test","hostname","_templateObject","_taggedTemplateLiteral","IGNORE","testFor","key","dir","find","k","file","_templateObject2","questions","type","message","validate","_URL","spinner","confirm","fn","args","msg","newParser","ora","text","start","then","r","savePage","succeed","confirmCreateDir","fs","existsSync","mkdirSync","getDir","_URL2","scaffoldCustomParser","_URL3","Parser","fetchResource","urlArg","process","argv","inquirer","prompt","answers","website","generateScaffold","_URL4","extractor","extractorTemplate","extractorName","extractorTest","extractorTestTemplate","writeFileSync","appendFileSync","exportString","exec","_URL5","filename","Date","getTime","first","$node","link","html","parse","console","log","_URL6","w","charAt","toUpperCase"],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"generate-custom-parser.js","sources":["../src/utils/dom/constants.js","../src/utils/dom/get-attrs.js","../src/utils/dom/strip-junk-tags.js","../src/utils/dom/set-attr.js","../src/utils/dom/make-links-absolute.js","../scripts/templates/insert-values.js","../scripts/templates/index.js","../scripts/templates/custom-extractor.js","../scripts/templates/custom-extractor-test.js","../scripts/generate-custom-parser.js"],"sourcesContent":["// Spacer images to be removed\nexport const SPACER_RE = new RegExp('transparent|spacer|blank', 'i');\n\n// The class we will use to mark elements we want to keep\n// but would normally remove\nexport const KEEP_CLASS = 'mercury-parser-keep';\n\nexport const KEEP_SELECTORS = [\n 'iframe[src^=\"https://www.youtube.com\"]',\n 'iframe[src^=\"https://www.youtube-nocookie.com\"]',\n 'iframe[src^=\"http://www.youtube.com\"]',\n 'iframe[src^=\"https://player.vimeo\"]',\n 'iframe[src^=\"http://player.vimeo\"]',\n 'iframe[src^=\"https://www.redditmedia.com\"]',\n];\n\n// A list of tags to strip from the output if we encounter them.\nexport const STRIP_OUTPUT_TAGS = [\n 'title',\n 'script',\n 'noscript',\n 'link',\n 'style',\n 'hr',\n 'embed',\n 'iframe',\n 'object',\n];\n\n// cleanAttributes\nexport const REMOVE_ATTRS = ['style', 'align'];\nexport const REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(\n selector => `[${selector}]`\n);\nexport const REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nexport const WHITELIST_ATTRS = [\n 'src',\n 'srcset',\n 'start',\n 'sizes',\n 'type',\n 'href',\n 'class',\n 'id',\n 'alt',\n 'xlink:href',\n 'width',\n 'height',\n];\n\nexport const WHITELIST_ATTRS_RE = new RegExp(\n `^(${WHITELIST_ATTRS.join('|')})$`,\n 'i'\n);\n\n// removeEmpty\nexport const REMOVE_EMPTY_TAGS = ['p'];\nexport const REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(\n tag => `${tag}:empty`\n).join(',');\n\n// cleanTags\nexport const CLEAN_CONDITIONALLY_TAGS = [\n 'ul',\n 'ol',\n 'table',\n 'div',\n 'button',\n 'form',\n].join(',');\n\n// cleanHeaders\nconst HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nexport const HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n // 'form', // This is too generic, has too many false positives\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'outbrain',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'taboola',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE = new RegExp(\n `^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`,\n 'i'\n);\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = ['figure', 'photo', 'image', 'caption'];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(\n POSITIVE_SCORE_HINTS.join('|'),\n 'i'\n);\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(\n NEGATIVE_SCORE_HINTS.join('|'),\n 'i'\n);\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nexport const IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nexport const EXTRANEOUS_LINK_HINTS = [\n 'print',\n 'archive',\n 'comment',\n 'discuss',\n 'e-mail',\n 'email',\n 'share',\n 'reply',\n 'all',\n 'login',\n 'sign',\n 'single',\n 'adx',\n 'entry-unrelated',\n];\nexport const EXTRANEOUS_LINK_HINTS_RE = new RegExp(\n EXTRANEOUS_LINK_HINTS.join('|'),\n 'i'\n);\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nexport const PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\n// export const NEXT_LINK_TEXT_RE = new RegExp('(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))', 'i');\nexport const NEXT_LINK_TEXT_RE = /(next|weiter|continue|>([^|]|$)|»([^|]|$))/i;\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nexport const CAP_LINK_TEXT_RE = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nexport const PREV_LINK_TEXT_RE = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(\n `^(${BLOCK_LEVEL_TAGS.join('|')})$`,\n 'i'\n);\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(\n `!(${candidatesWhitelist})|(${candidatesBlacklist})`,\n 'i'\n);\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","export default function getAttrs(node) {\n const { attribs, attributes } = node;\n\n if (!attribs && attributes) {\n const attrs = Reflect.ownKeys(attributes).reduce((acc, index) => {\n const attr = attributes[index];\n\n // In browser, Reflect.ownKeys includes non-numeric keys like 'length', 'item', etc.\n if (!attr || !attr.name || !attr.value) return acc;\n\n acc[attr.name] = attr.value;\n return acc;\n }, {});\n return attrs;\n }\n\n return attribs;\n}\n","import { STRIP_OUTPUT_TAGS, KEEP_CLASS } from './constants';\n\nexport default function stripJunkTags(article, $, tags = []) {\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n // Remove matching elements, but ignore\n // any element with a class of mercury-parser-keep\n $(tags.join(','), article)\n .not(`.${KEEP_CLASS}`)\n .remove();\n\n return $;\n}\n","export default function setAttr(node, attr, val) {\n if (node.attribs) {\n node.attribs[attr] = val;\n } else if (node.attributes) {\n node.setAttribute(attr, val);\n }\n\n return node;\n}\n","import URL from 'url';\n\nimport getAttrs from './get-attrs';\nimport setAttr from './set-attr';\n\nfunction absolutize($, rootUrl, attr) {\n const baseUrl = $('base').attr('href');\n\n $(`[${attr}]`).each((_, node) => {\n const attrs = getAttrs(node);\n const url = attrs[attr];\n if (!url) return;\n const absoluteUrl = URL.resolve(baseUrl || rootUrl, url);\n\n setAttr(node, attr, absoluteUrl);\n });\n}\n\nfunction absolutizeSet($, rootUrl, $content) {\n $('[srcset]', $content).each((_, node) => {\n const attrs = getAttrs(node);\n const urlSet = attrs.srcset;\n\n if (urlSet) {\n // a comma should be considered part of the candidate URL unless preceded by a descriptor\n // descriptors can only contain positive numbers followed immediately by either 'w' or 'x'\n // space characters inside the URL should be encoded (%20 or +)\n const candidates = urlSet.match(\n /(?:\\s*)(\\S+(?:\\s*[\\d.]+[wx])?)(?:\\s*,\\s*)?/g\n );\n if (!candidates) return;\n const absoluteCandidates = candidates.map(candidate => {\n // a candidate URL cannot start or end with a comma\n // descriptors are separated from the URLs by unescaped whitespace\n const parts = candidate\n .trim()\n .replace(/,$/, '')\n .split(/\\s+/);\n parts[0] = URL.resolve(rootUrl, parts[0]);\n return parts.join(' ');\n });\n const absoluteUrlSet = [...new Set(absoluteCandidates)].join(', ');\n setAttr(node, 'srcset', absoluteUrlSet);\n }\n });\n}\n\nexport default function makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(attr => absolutize($, url, attr));\n absolutizeSet($, url, $content);\n\n return $content;\n}\n","export default function insertValues(strings, ...values) {\n if (values.length) {\n return strings.reduce((result, part, idx) => {\n let value = values[idx];\n\n if (value && typeof value.toString === 'function') {\n value = value.toString();\n } else {\n value = '';\n }\n\n return result + part + value;\n }, '');\n }\n\n return strings.join('');\n}\n","import insertValues from './insert-values';\n\nconst bodyPattern = /^\\n([\\s\\S]+)\\s{2}$/gm;\nconst trailingWhitespace = /\\s+$/;\n\nexport default function template(strings, ...values) {\n const compiled = insertValues(strings, ...values);\n let [body] = compiled.match(bodyPattern) || [];\n let indentLevel = /^\\s{0,4}(.+)$/g;\n\n if (!body) {\n body = compiled;\n indentLevel = /^\\s{0,2}(.+)$/g;\n }\n\n return body\n .split('\\n')\n .slice(1)\n .map(line => {\n line = line.replace(indentLevel, '$1');\n\n if (trailingWhitespace.test(line)) {\n line = line.replace(trailingWhitespace, '');\n }\n\n return line;\n })\n .join('\\n');\n}\n","import template from './index';\n\nexport default function(hostname, name) {\n return template`\n export const ${name} = {\n domain: '${hostname}',\n\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n }\n `;\n}\n","import template from './index';\n\nconst IGNORE = [\n 'url',\n 'domain',\n 'content',\n 'word_count',\n 'next_page_url',\n 'excerpt',\n 'direction',\n 'total_pages',\n 'rendered_pages',\n];\n\nfunction testFor(key, value, dir) {\n if (IGNORE.find(k => k === key)) return '';\n\n return template`\n it('returns the ${key}', async () => {\n // To pass this test, fill out the ${key} selector\n // in ${dir}/index.js.\n const { ${key} } = await result\n\n // Update these values with the expected values from\n // the article.\n assert.strictEqual(${key}, ${value ? `\\`${value}\\`` : \"''\"})\n });\n `;\n}\n\nexport default function(file, url, dir, result, name) {\n return template`\n import assert from 'assert';\n import * as cheerio from 'cheerio';\n\n import Parser from 'mercury';\n import getExtractor from 'extractors/get-extractor';\n import { excerptContent } from 'utils/text';\n\n const fs = require('fs');\n\n describe('${name}', () => {\n describe('initial test case', () => {\n let result;\n let url;\n beforeAll(() => {\n url =\n '${url}';\n const html =\n fs.readFileSync('${file}');\n result =\n Parser.parse(url, { html, fallback: false });\n });\n\n it('is selected properly', () => {\n // This test should be passing by default.\n // It sanity checks that the correct parser\n // is being selected for URLs from this domain\n const extractor = getExtractor(url);\n assert.strictEqual(extractor.domain, new URL(url).hostname)\n })\n\n ${Reflect.ownKeys(result)\n .map(k => testFor(k, result[k], dir))\n .join('\\n\\n')}\n\n it('returns the content', async () => {\n // To pass this test, fill out the content selector\n // in ${dir}/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const { content } = await result;\n\n const $ = cheerio.load(content || '');\n\n const first13 = excerptContent($('*').first().text(), 13)\n\n // Update these values with the expected values from the article.\n // Add the first 13 words of the article here\n assert.strictEqual(first13, null);\n });\n });\n });\n `;\n}\n","/* eslint-disable import/no-extraneous-dependencies */\n/* eslint-disable no-use-before-define */\n/* eslint-disable no-console */\nimport fs from 'fs';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport { exec } from 'child_process';\n\nimport { stripJunkTags, makeLinksAbsolute } from 'utils/dom';\nimport Parser from '../dist/mercury';\nimport extractorTemplate from './templates/custom-extractor';\nimport extractorTestTemplate from './templates/custom-extractor-test';\n\nconst questions = [\n {\n type: 'input',\n name: 'website',\n message:\n \"Paste a url to an article you'd like to create or extend a parser for:\",\n validate(value) {\n const { hostname } = new URL(value);\n if (hostname) return true;\n\n return false;\n },\n },\n];\nlet spinner;\n\nfunction confirm(fn, args, msg, newParser) {\n spinner = ora({ text: msg });\n spinner.start();\n const result = fn(...args);\n\n if (result && result.then) {\n result.then(r => savePage(r, args, newParser));\n } else {\n spinner.succeed();\n }\n\n return result;\n}\n\nfunction confirmCreateDir(dir, msg) {\n if (!fs.existsSync(dir)) {\n confirm(fs.mkdirSync, [dir], msg);\n }\n}\n\nfunction getDir(url) {\n const { hostname } = new URL(url);\n return `./src/extractors/custom/${hostname}`;\n}\n\nfunction scaffoldCustomParser(url) {\n const dir = getDir(url);\n const { hostname } = new URL(url);\n let newParser = false;\n\n if (!fs.existsSync(dir)) {\n newParser = true;\n confirmCreateDir(dir, `Creating ${hostname} directory`);\n confirmCreateDir(`./fixtures/${hostname}`, 'Creating fixtures directory');\n }\n\n confirm(Parser.fetchResource, [url], 'Fetching fixture', newParser);\n}\n\n// if has arg, just assume that arg is a url and skip prmopt\nconst urlArg = process.argv[2];\nif (urlArg) {\n scaffoldCustomParser(urlArg);\n} else {\n inquirer.prompt(questions).then(answers => {\n scaffoldCustomParser(answers.website);\n });\n}\n\nfunction generateScaffold(url, file, result) {\n const { hostname } = new URL(url);\n const extractor = extractorTemplate(hostname, extractorName(hostname));\n const extractorTest = extractorTestTemplate(\n file,\n url,\n getDir(url),\n result,\n extractorName(hostname)\n );\n\n fs.writeFileSync(`${getDir(url)}/index.js`, extractor);\n fs.writeFileSync(`${getDir(url)}/index.test.js`, extractorTest);\n fs.appendFileSync('./src/extractors/custom/index.js', exportString(url));\n exec(`npm run lint-fix-quiet -- ${getDir(url)}/*.js`);\n}\n\nfunction savePage($, [url], newParser) {\n const { hostname } = new URL(url);\n\n spinner.succeed();\n\n const filename = new Date().getTime();\n const file = `./fixtures/${hostname}/${filename}.html`;\n // fix http(s) relative links:\n makeLinksAbsolute($('*').first(), $, url);\n $('[src], [href]').each((index, node) => {\n const $node = $(node);\n const link = $node.attr('src');\n if (link && link.slice(0, 2) === '//') {\n $node.attr('src', `http:${link}`);\n }\n });\n const html = stripJunkTags($('*').first(), $, ['script']).html();\n\n fs.writeFileSync(file, html);\n\n Parser.parse(url, { html }).then(result => {\n if (newParser) {\n confirm(\n generateScaffold,\n [url, file, result],\n 'Generating parser and tests'\n );\n console.log(`Your custom site extractor has been set up. To get started building it, run\n yarn watch:test -- ${hostname}\n -- OR --\n npm run watch:test -- ${hostname}`);\n } else {\n console.log(`\n It looks like you already have a custom parser for this url.\n The page you linked to has been added to ${file}. Copy and paste\n the following code to use that page in your tests:\n const html = fs.readFileSync('${file}');`);\n }\n });\n}\n\nfunction exportString(url) {\n const { hostname } = new URL(url);\n return `export * from './${hostname}';`;\n}\n\nfunction extractorName(hostname) {\n const name = hostname\n .split('.')\n .map(w => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)\n .join('');\n return `${name}Extractor`;\n}\n"],"names":["KEEP_CLASS","STRIP_OUTPUT_TAGS","getAttrs","node","attribs","attributes","attrs","_Reflect$ownKeys","reduce","acc","index","attr","name","value","stripJunkTags","article","$","tags","arguments","length","undefined","join","not","concat","remove","setAttr","val","setAttribute","absolutize","rootUrl","baseUrl","each","_","url","absoluteUrl","URL","resolve","absolutizeSet","$content","urlSet","srcset","candidates","match","absoluteCandidates","map","candidate","parts","trim","replace","split","absoluteUrlSet","_toConsumableArray","_Set","makeLinksAbsolute","forEach","insertValues","strings","_len","values","Array","_key","result","part","idx","toString","bodyPattern","trailingWhitespace","template","compiled","apply","_ref","_ref2","_slicedToArray","body","indentLevel","slice","line","test","hostname","_templateObject","_taggedTemplateLiteral","IGNORE","testFor","key","dir","find","k","file","_templateObject2","questions","type","message","validate","_URL","spinner","confirm","fn","args","msg","newParser","ora","text","start","then","r","savePage","succeed","confirmCreateDir","fs","existsSync","mkdirSync","getDir","_URL2","scaffoldCustomParser","_URL3","Parser","fetchResource","urlArg","process","argv","inquirer","prompt","answers","website","generateScaffold","_URL4","extractor","extractorTemplate","extractorName","extractorTest","extractorTestTemplate","writeFileSync","appendFileSync","exportString","exec","_URL5","filename","Date","getTime","first","$node","link","html","parse","console","log","_URL6","w","charAt","toUpperCase"],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
package/dist/mercury.js CHANGED
@@ -4390,31 +4390,31 @@ var WwwSlateComExtractor = {
4390
4390
  var IciRadioCanadaCaExtractor = {
4391
4391
  domain: 'ici.radio-canada.ca',
4392
4392
  title: {
4393
- selectors: ['h1']
4393
+ selectors: [['meta[name="dc.title"]', 'value']]
4394
4394
  },
4395
4395
  author: {
4396
4396
  selectors: [['meta[name="dc.creator"]', 'value']]
4397
4397
  },
4398
4398
  date_published: {
4399
- selectors: [['meta[name="dc.date.created"]', 'value']],
4400
- format: 'YYYY-MM-DD|HH[h]mm',
4401
- timezone: 'America/New_York'
4399
+ selectors: [['meta[name="dc.date.created"]', 'value']]
4402
4400
  },
4403
4401
  dek: {
4404
- selectors: ['div.lead-container', '.bunker-component.lead']
4402
+ selectors: [['meta[name="description"]', 'value']]
4405
4403
  },
4406
4404
  lead_image_url: {
4407
4405
  selectors: [['meta[name="og:image"]', 'value']]
4408
4406
  },
4409
4407
  content: {
4410
- selectors: ['section.document-content-style', ['.main-multimedia-item', '.news-story-content']],
4411
- // Is there anything in the content you selected that needs transformed
4412
- // before it's consumable content? E.g., unusual lazy loaded images
4413
- transforms: {},
4414
- // Is there anything that is in the result that shouldn't be?
4415
- // The clean selectors will remove anything that matches from
4416
- // the result
4417
- clean: []
4408
+ selectors: ['article main', 'article'],
4409
+ transforms: {
4410
+ h2: function h2(node) {
4411
+ return node.attr('class', 'mercury-parser-keep');
4412
+ },
4413
+ ul: function ul(node) {
4414
+ return node.attr('class', 'mercury-parser-keep');
4415
+ }
4416
+ },
4417
+ clean: ['header', 'nav', 'button', 'figcaption', '[class*="adBox"]', '.framed']
4418
4418
  }
4419
4419
  };
4420
4420
 
@@ -6576,12 +6576,6 @@ var WwwVortezNetExtractor = {
6576
6576
  title: {
6577
6577
  selectors: ['title']
6578
6578
  },
6579
- author: {
6580
- selectors: []
6581
- },
6582
- date_published: {
6583
- selectors: []
6584
- },
6585
6579
  dek: {
6586
6580
  selectors: []
6587
6581
  },
@@ -6950,6 +6944,52 @@ var WwwNumeramaComExtractor = {
6950
6944
  }
6951
6945
  };
6952
6946
 
6947
+ var TerminaltroveComExtractor = {
6948
+ domain: 'terminaltrove.com',
6949
+ title: {
6950
+ selectors: [['meta[name="og:title"]', 'value']]
6951
+ },
6952
+ dek: {
6953
+ selectors: [['meta[name="og:description"]', 'value']]
6954
+ },
6955
+ lead_image_url: {
6956
+ selectors: [['meta[name="og:image"]', 'value']]
6957
+ },
6958
+ content: {
6959
+ selectors: ['main'],
6960
+ clean: ['.share-badge', '.modal', '.modal-toggle', '.sr-only', '.premium-sponsor-featured']
6961
+ }
6962
+ };
6963
+
6964
+ var NewsPtsOrgTwExtractor = {
6965
+ domain: 'news.pts.org.tw',
6966
+ title: {
6967
+ selectors: ['h1.article-title']
6968
+ },
6969
+ author: {
6970
+ selectors: [['meta[name="author"]', 'content'], ['meta[name="author"]', 'value']]
6971
+ },
6972
+ date_published: {
6973
+ selectors: [['meta[property="article:published_time"]', 'content'], ['meta[name="article:published_time"]', 'value']]
6974
+ },
6975
+ dek: {
6976
+ selectors: [['meta[name="description"]', 'content'], ['meta[name="description"]', 'value']]
6977
+ },
6978
+ lead_image_url: {
6979
+ selectors: [['meta[property="og:image"]', 'content'], ['meta[name="og:image"]', 'value']]
6980
+ },
6981
+ content: {
6982
+ selectors: ['.post-article', '.article-content'],
6983
+ // Is there anything in the content you selected that needs transformed
6984
+ // before it's consumable content? E.g., unusual lazy loaded images
6985
+ transforms: {},
6986
+ // Is there anything that is in the result that shouldn't be?
6987
+ // The clean selectors will remove anything that matches from
6988
+ // the result
6989
+ clean: ['.articleimg', 'ul']
6990
+ }
6991
+ };
6992
+
6953
6993
  var CustomExtractors = /*#__PURE__*/Object.freeze({
6954
6994
  __proto__: null,
6955
6995
  BloggerExtractor: BloggerExtractor,
@@ -7137,7 +7177,9 @@ var CustomExtractors = /*#__PURE__*/Object.freeze({
7137
7177
  GonintendoComExtractor: GonintendoComExtractor,
7138
7178
  OrfAtExtractor: OrfAtExtractor,
7139
7179
  WwwVideogameschronicleComExtractor: WwwVideogameschronicleComExtractor,
7140
- WwwNumeramaComExtractor: WwwNumeramaComExtractor
7180
+ WwwNumeramaComExtractor: WwwNumeramaComExtractor,
7181
+ TerminaltroveComExtractor: TerminaltroveComExtractor,
7182
+ NewsPtsOrgTwExtractor: NewsPtsOrgTwExtractor
7141
7183
  });
7142
7184
 
7143
7185
  function ownKeys$5(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }