{ "translatorID": "57517a91-b881-4da3-b205-751f6c7e2cae", "label": "LWN.net", "creator": "Tim Hollmann", "target": "^https?://lwn\\.net/", "minVersion": "5.0", "maxVersion": "", "priority": 100, "inRepository": true, "translatorType": 4, "browserSupport": "gcsibv", "lastUpdated": "2025-08-28 14:37:28" } /* ***** BEGIN LICENSE BLOCK ***** Copyright © 2025 Tim Hollmann This file is part of Zotero. Zotero is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Zotero is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Zotero. If not, see . ***** END LICENSE BLOCK ***** */ function detectWeb(doc, _url) { if ((doc.location.pathname.startsWith('/Articles/') || doc.location.pathname === '/Search/DoTextSearch') && getSearchResults(doc, true)) { return 'multiple'; } if (isNewsItem(doc) || isFeatureArticle(doc) || isGuestArticle(doc)) { return 'newspaperArticle'; } return false; } function getSearchResults(doc, checkOnly) { var items = {}; var found = false; // Weekly Edition pages var rows = doc.querySelectorAll('.SummaryHL > a[href*="/Articles/"]'); if (!rows.length && doc.location.pathname === '/Search/DoTextSearch') { // Issue pages rows = doc.querySelectorAll('.ArticleText > p > a[href*="/Articles/"]'); } for (let row of rows) { let href = row.href; let title = ZU.trimInternal(row.textContent); if (!href || !title) continue; if (title.startsWith('Welcome to the LWN.net Weekly Edition')) { continue; } if (checkOnly) return true; found = true; items[href] = title; } return found ? items : false; } async function doWeb(doc, url) { if (detectWeb(doc, url) == 'multiple') { let items = await Zotero.selectItems(getSearchResults(doc, false)); if (!items) return; for (let url of Object.keys(items)) { scrape(await requestDocument(url)); } } else { scrape(doc, url); } } function scrape(doc, url = doc.location.href) { const title = getTitle(doc); const author = getAuthor(doc); const date = ZU.strToISO(getDate(doc)); if (!title || !author || !date) { return; } let item = new Zotero.Item('newspaperArticle'); item.title = getTitle(doc); item.creators.push(ZU.cleanAuthor(author, 'author', false)); item.date = date; item.url = appendUrl(url, ''); // Clean the URL item.publicationTitle = 'LWN.net'; // "Linux Weekly News" is discouraged (see their FAQ) item.language = 'en-US'; item.attachments.push({ title: 'Snapshot', document: doc, }); item.attachments.push({ title: 'Article EPUB', mimeType: 'application/epub+zip', url: appendUrl(url, 'epub'), }); item.complete(); } /* * Detection of article type */ function isNewsItem(doc) { return doc.querySelectorAll('.Byline').length == 1; } function isFeatureArticle(doc) { return doc.querySelectorAll('.FeatureByline').length == 1; } function isGuestArticle(doc) { return doc.querySelectorAll('.GAByline').length == 1; } /* * Metadata scraping */ function getTitle(doc) { return text(doc, '.PageHeadline > h1'); } function getAuthor(doc) { if (isNewsItem(doc)) { let author = text(doc, '.Byline').match(/\[Posted (.*) by (.*)\]/i)?.[2]; // Regular news items are published with abbreviated author names, so we have to map them back to their full names. // Since regular news items should only be authored by the LWN staff themselves (4 people), this should suffice. const knownAuthors = { 'corbet': 'Jonathan Corbet', 'daroc': 'Daroc Alden', 'jake': 'Jake Edge', 'jzb': 'Joe Brockmeier', }; if (knownAuthors.hasOwnProperty(author)) { author = knownAuthors[author]; } return author; } if (isFeatureArticle(doc)) { return text(doc, '.FeatureByline > b'); } if (isGuestArticle(doc)) { return text(doc, '.GAByline > p:last-child').match(/contributed by (.*)/i)?.[1]; } return null; // Error } function getDate(doc) { if (isNewsItem(doc)) { return text(doc, '.Byline').match(/Posted (.*) by (.*)\]/i)?.[1]; } if (isFeatureArticle(doc)) { return doc.querySelector('.FeatureByline br').nextSibling.textContent; } if (isGuestArticle(doc)) { return text(doc, '.GAByline > p:first-child'); } return null; // Error } /** * Append the provided URL by a given relative path and also remove anchors. */ function appendUrl(url, path = '') { return (new URL(path, url)).href; } /** BEGIN TEST CASES **/ var testCases = [ { "type": "web", "url": "https://lwn.net/Articles/525592/", "items": [ { "itemType": "newspaperArticle", "title": "The module signing endgame", "creators": [ { "firstName": "Jake", "lastName": "Edge", "creatorType": "author" } ], "date": "2012-11-21", "language": "en-US", "libraryCatalog": "LWN.net", "publicationTitle": "LWN.net", "url": "https://lwn.net/Articles/525592/", "attachments": [ { "title": "Snapshot", "mimeType": "text/html" }, { "title": "Article EPUB", "mimeType": "application/epub+zip" } ], "tags": [], "notes": [], "seeAlso": [] } ] }, { "type": "web", "url": "https://lwn.net/Articles/709201/", "items": [ { "itemType": "newspaperArticle", "title": "Debian considering automated upgrades", "creators": [ { "firstName": "Antoine", "lastName": "Beaupré", "creatorType": "author" } ], "date": "2016-12-14", "language": "en-US", "libraryCatalog": "LWN.net", "publicationTitle": "LWN.net", "url": "https://lwn.net/Articles/709201/", "attachments": [ { "title": "Snapshot", "mimeType": "text/html" }, { "title": "Article EPUB", "mimeType": "application/epub+zip" } ], "tags": [], "notes": [], "seeAlso": [] } ] }, { "type": "web", "url": "https://lwn.net/Articles/1013723/", "items": [ { "itemType": "newspaperArticle", "title": "Framework Mono 6.14.0 released", "creators": [ { "firstName": "Joe", "lastName": "Brockmeier", "creatorType": "author" } ], "date": "2025-03-11", "language": "en-US", "libraryCatalog": "LWN.net", "publicationTitle": "LWN.net", "url": "https://lwn.net/Articles/1013723/", "attachments": [ { "title": "Snapshot", "mimeType": "text/html" }, { "title": "Article EPUB", "mimeType": "application/epub+zip" } ], "tags": [], "notes": [], "seeAlso": [] } ] }, { "type": "web", "url": "https://lwn.net/Articles/1012147/", "items": "multiple" }, { "type": "web", "url": "https://lwn.net/Search/DoTextSearch?words=test&ctype11=yes&ctype8=yes&ctype3=yes&cat_79=yes&cat_271=yes&cat_56=yes&cat_25=yes&cat_21=yes&cat_1=yes&cat_8=yes&cat_2=yes&cat_84=yes&cat_72=yes&cat_3=yes&catsbox=yes&order=relevance&Search=Search", "items": "multiple" }, { "type": "web", "url": "https://lwn.net/Articles/1033373/", "items": [ { "itemType": "newspaperArticle", "title": "Python, tail calls, and performance", "creators": [ { "firstName": "Jake", "lastName": "Edge", "creatorType": "author" } ], "date": "2025-08-20", "language": "en-US", "libraryCatalog": "LWN.net", "publicationTitle": "LWN.net", "url": "https://lwn.net/Articles/1033373/", "attachments": [ { "title": "Snapshot", "mimeType": "text/html" }, { "title": "Article EPUB", "mimeType": "application/epub+zip" } ], "tags": [], "notes": [], "seeAlso": [] } ] } ] /** END TEST CASES **/