Created
July 6, 2024 12:23
-
-
Save replete/0ce7523639677e0e113f8d77b0394d7b to your computer and use it in GitHub Desktop.
statamic.dev reference to Dash Docset
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// npm install axios cheerio sqlite3 plist fs-extra | |
// WIP, too busy to finish this | |
const axios = require('axios'); | |
const cheerio = require('cheerio'); | |
const fs = require('fs-extra'); | |
const path = require('path'); | |
const sqlite3 = require('sqlite3').verbose(); | |
const plist = require('plist'); | |
const BASE_URL = 'https://statamic.dev'; | |
const SECTIONS = ['Fieldtypes', 'Modifiers', 'Repositories', 'Tags', 'Variables', 'Widgets']; | |
const OUTPUT_DIR = path.join(__dirname, 'statamic-reference'); | |
const DOCSET_DIR = path.join(__dirname, 'Statamic.docset'); | |
const DOCUMENTS_DIR = path.join(DOCSET_DIR, 'Contents', 'Resources', 'Documents'); | |
async function downloadPage(url) { | |
const response = await axios.get(url); | |
return response.data; | |
} | |
async function downloadDocumentation() { | |
const mainUrl = `${BASE_URL}/reference`; | |
await fs.ensureDir(OUTPUT_DIR); | |
const mainPage = await downloadPage(mainUrl); | |
await fs.outputFile(path.join(OUTPUT_DIR, 'index.html'), mainPage); | |
console.log('Downloaded main documentation page'); | |
} | |
async function parseAndDownloadLinks() { | |
const indexPath = path.join(OUTPUT_DIR, 'index.html'); | |
const content = await fs.readFile(indexPath, 'utf-8'); | |
const $ = cheerio.load(content); | |
const links = []; | |
$('#side-nav nav button').each((i, elem) => { | |
const sectionName = $(elem).text().trim(); | |
if (SECTIONS.includes(sectionName)) { | |
$(elem).next('ul').find('a').each((j, linkElem) => { | |
const link = $(linkElem).attr('href'); | |
const title = $(linkElem).text().trim(); | |
if (title && !title.startsWith('All')) { | |
links.push({ section: sectionName, title, link: `${BASE_URL}${link}` }); | |
} | |
}); | |
} | |
}); | |
for (const linkObj of links) { | |
const outputPath = path.join(OUTPUT_DIR, linkObj.section, `${linkObj.title}.html`); | |
if (!fs.existsSync(outputPath)) { | |
const pageContent = await downloadPage(linkObj.link); | |
await fs.outputFile(outputPath, pageContent); | |
console.log(`Downloaded ${linkObj.title}`); | |
} | |
} | |
console.log('Downloaded all linked pages'); | |
return links; | |
} | |
async function extractContent(entries) { | |
for (const entry of entries) { | |
const entryPath = path.join(OUTPUT_DIR, entry.section, `${entry.title}.html`); | |
const content = await fs.readFile(entryPath, 'utf-8'); | |
const $ = cheerio.load(content); | |
// Remove unwanted sections | |
$('#breadcrumbs, #table-of-contents').remove(); | |
// Update internal links | |
$('a').each((i, link) => { | |
const href = $(link).attr('href'); | |
if (href && href.startsWith('/')) { | |
const newHref = href.replace('/', ''); | |
$(link).attr('href', newHref + '.html'); | |
} | |
}); | |
// Extract and save content | |
const extractedContent = $('#content').html(); | |
const docPath = path.join(DOCUMENTS_DIR, entry.section, `${entry.title}.html`); | |
await fs.outputFile(docPath, extractedContent); | |
console.log(`Extracted content for ${entry.title}`); | |
} | |
} | |
function createSQLiteIndex(entries) { | |
const dbPath = path.join(DOCSET_DIR, 'Contents', 'Resources', 'docSet.dsidx'); | |
const db = new sqlite3.Database(dbPath); | |
db.serialize(() => { | |
db.run('CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);'); | |
db.run('CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path);'); | |
const stmt = db.prepare('INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (?, ?, ?)'); | |
entries.forEach(entry => { | |
const docPath = path.join(entry.section, `${entry.title}.html`); | |
stmt.run(entry.title, entry.section, docPath); | |
}); | |
stmt.finalize(); | |
}); | |
db.close(); | |
} | |
function createPlist() { | |
const plistContent = plist.build({ | |
CFBundleIdentifier: 'statamic', | |
CFBundleName: 'Statamic', | |
DocSetPlatformFamily: 'statamic', | |
isDashDocset: true, | |
dashIndexFilePath: 'index.html' | |
}); | |
const plistPath = path.join(DOCSET_DIR, 'Contents', 'Info.plist'); | |
fs.outputFileSync(plistPath, plistContent); | |
console.log('Created Info.plist'); | |
} | |
(async () => { | |
await downloadDocumentation(); | |
const docEntries = await parseAndDownloadLinks(); | |
await fs.ensureDir(DOCUMENTS_DIR); | |
await extractContent(docEntries); | |
createSQLiteIndex(docEntries); | |
createPlist(); | |
console.log('Docset creation complete'); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment