33 lines
1.4 KiB
JavaScript
33 lines
1.4 KiB
JavaScript
'use strict';
|
|
|
|
// First-party parser; inputs are fetched by the paced source broker, not here.
|
|
const decode = value => String(value).replace(/&/g, '&').replace(/'|'/gi, "'")
|
|
.replace(/"/g, '"').replace(/<[^>]+>/g, '').trim();
|
|
|
|
function catalog({ html, url }) {
|
|
const sourceId = new URL(url).pathname.split('/')[2];
|
|
const title = decode(html.match(/<h1\b[^>]*>([\s\S]*?)<\/h1>/i)?.[1] || 'Untitled');
|
|
const chapters = [];
|
|
const re = /<a\b[^>]*href="(\/chapters\/(\d+-\d+)\/[^"?#]+)"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
for (const match of html.matchAll(re)) {
|
|
if (match[2].split('-')[0] !== sourceId) continue;
|
|
const label = decode(match[3]);
|
|
const number = label.match(/^Chapter\s+([0-9]+(?:\.[0-9]+)?)(?:\b|$)/i)?.[1];
|
|
if (!number) continue;
|
|
chapters.push({ id: match[2], number, title: '', url: new URL(match[1], url).href, raw: label });
|
|
}
|
|
return { title, chapters: [...new Map(chapters.map(ref => [ref.id, ref])).values()],
|
|
chapterLinks: [...html.matchAll(/href="\/chapters\/\d+-\d+\//gi)].length };
|
|
}
|
|
|
|
function pages({ html }) {
|
|
const images = [];
|
|
for (const match of html.matchAll(/<img\b[^>]*class="[^"]*\bjs-page\b[^"]*"[^>]*>/gi)) {
|
|
const url = match[0].match(/\bdata-src="([^"]+)"/i)?.[1];
|
|
if (url) images.push(url.replace(/&/g, '&'));
|
|
}
|
|
return { pages: [...new Set(images)] };
|
|
}
|
|
|
|
module.exports = { catalog, pages };
|