Skip to content

Commit

Permalink
updated script file
Browse files Browse the repository at this point in the history
  • Loading branch information
krofax committed Nov 4, 2024
1 parent 66d7e38 commit 6633952
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 67 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Optimism Docs",
"scripts": {
"lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint",
"fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix",
"fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm check-breadcrumbs",
"spellcheck:lint": "cspell lint \"**/*.mdx\"",
"spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt",
"linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"",
Expand Down
107 changes: 57 additions & 50 deletions utils/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,70 @@ import * as path from 'path';
import matter from 'gray-matter';

const rootDir = path.join(process.cwd(), 'pages');
const errors: string[] = [];
const warnings: string[] = [];

interface PageInfo {
title: string;
url: string;
}
// ANSI color codes
const YELLOW = '\x1b[33m';
const RESET = '\x1b[0m';
const BOLD = '\x1b[1m';

async function getReferencedPages(breadcrumbContent: string): Promise<string[]> {
// Extract URLs from Card components in the breadcrumb file
const cardRegex = /<Card[^>]*href="([^"]+)"[^>]*>/g;
const urls: string[] = [];
let match;

while ((match = cardRegex.exec(breadcrumbContent)) !== null) {
urls.push(match[1]);
// Pages to exclude from checks
const excludedPages = [
'400.mdx',
'500.mdx',
'index.mdx',
'404.mdx'
];

async function getReferencedPagesFromBreadcrumb(breadcrumbPath: string): Promise<string[]> {
try {
const content = await fs.readFile(breadcrumbPath, 'utf-8');
const cardMatches = content.match(/<Card[^>]*href="([^"]+)"[^>]*>/g) || [];
return cardMatches.map(match => {
const hrefMatch = match.match(/href="([^"]+)"/);
return hrefMatch ? hrefMatch[1] : '';
}).filter(Boolean);
} catch (error) {
return [];
}

return urls;
}

async function checkDirectory(dirPath: string): Promise<void> {
const entries = await fs.readdir(dirPath, { withFileTypes: true });
const currentDir = path.basename(dirPath);

// First, find the breadcrumb file for this directory
const dirName = path.basename(dirPath);
const breadcrumbFile = path.join(dirPath, `${dirName}.mdx`);
let referencedPages: string[] = [];

try {
const breadcrumbContent = await fs.readFile(breadcrumbFile, 'utf-8');
referencedPages = await getReferencedPages(breadcrumbContent);
} catch (error) {
// Only check for missing references if not in root directory
if (dirPath !== rootDir) {
errors.push(`Missing breadcrumb file for directory: ${path.relative(rootDir, dirPath)}`);
return;
// Skip the root directory check
if (dirPath !== rootDir) {
const breadcrumbPath = path.join(dirPath, `${currentDir}.mdx`);
const referencedPages = await getReferencedPagesFromBreadcrumb(breadcrumbPath);

// Check all .mdx and .md files in the current directory
for (const entry of entries) {
if (entry.isFile() &&
(entry.name.endsWith('.mdx') || entry.name.endsWith('.md')) &&
!excludedPages.includes(entry.name) &&
entry.name !== `${currentDir}.mdx`) {

const pageName = entry.name.replace(/\.(md|mdx)$/, '');
const relativePath = `/stack/${path.relative(rootDir, dirPath)}/${pageName}`.replace(/\\/g, '/');

if (!referencedPages.includes(relativePath)) {
const humanReadableName = pageName.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');

warnings.push(
`Page "${humanReadableName}" at path "${relativePath}" is not listed in the breadcrumb navigation of ${currentDir}.mdx`
);
}
}
}
}

// Check each entry in the directory
// Process subdirectories
for (const entry of entries) {
if (entry.name.startsWith('_') || entry.name.startsWith('.')) continue;

const fullPath = path.join(dirPath, entry.name);

if (entry.isDirectory()) {
// Recursively check subdirectories
await checkDirectory(fullPath);
} else if ((entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) &&
entry.name !== `${dirName}.mdx`) {
// Check if this page is referenced in the breadcrumb
const relativePath = '/' + path.relative(rootDir, fullPath)
.replace(/\.(md|mdx)$/, '');

if (!referencedPages.includes(relativePath)) {
errors.push(`Page not referenced in breadcrumb: ${relativePath}`);
}
if (entry.isDirectory() && !entry.name.startsWith('_') && !entry.name.startsWith('.')) {
await checkDirectory(path.join(dirPath, entry.name));
}
}
}
Expand All @@ -68,15 +75,15 @@ async function main() {
try {
await checkDirectory(rootDir);

if (errors.length > 0) {
console.error('Breadcrumb check failed:');
errors.forEach(error => console.error(`- ${error}`));
if (warnings.length > 0) {
console.log(`${YELLOW}${BOLD}Missing pages in breadcrumb navigation:${RESET}`);
warnings.forEach(warning => console.log(`${YELLOW}- ${warning}${RESET}`));
process.exit(1);
} else {
console.log('All pages are properly referenced in breadcrumb navigation.');
console.log('All pages are properly listed in their respective breadcrumb navigation files.');
}
} catch (error) {
console.error('Error checking breadcrumbs:', error);
console.log(`${YELLOW}${BOLD}Error checking breadcrumbs:${RESET}`, error);
process.exit(1);
}
}
Expand Down
10 changes: 3 additions & 7 deletions utils/create-breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@ function toTitleCase(str: string): string {
}

function extractFirstParagraph(content: string): string {
// Remove frontmatter

content = content.replace(/^---[\s\S]*?---/, '');

// Remove import statements
content = content.replace(/^import[\s\S]*?\n/gm, '');

// Remove HTML/MDX tags

content = content.replace(/<[^>]+>/g, ' ');

// Remove markdown links but keep text

content = content.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');

// Remove headers
content = content.replace(/^#.+$/gm, '');

const paragraphs = content.split(/\n\n+/);
Expand Down
9 changes: 0 additions & 9 deletions words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Allocs
allocs
altda
ANDI
Ankr
Apeworx
Arweave
authrpc
Expand Down Expand Up @@ -148,7 +147,6 @@ Holesky
holesky
IGNOREPRICE
ignoreprice
Immunefi
implicity
Inator
inator
Expand Down Expand Up @@ -197,7 +195,6 @@ minsuggestedpriorityfee
Mintable
Mintplex
MIPSEVM
Mitigations
Monitorism
Moralis
Mordor
Expand Down Expand Up @@ -291,8 +288,6 @@ Protip
Proxied
proxyd
pseudorandomly
Pyth
Pyth's
QRNG
Quicknode
quicknode
Expand Down Expand Up @@ -326,9 +321,6 @@ safedb
Schnorr
secp
SELFDESTRUCT
SEPOLIA
Sepolia
sepolia
seqnr
SEQUENCERHTTP
sequencerhttp
Expand Down Expand Up @@ -398,7 +390,6 @@ VMDEBUG
vmdebug
VMODULE
vmodule
voxel
wagmi
Warpcast
xlarge
Expand Down

0 comments on commit 6633952

Please sign in to comment.