diff --git a/package.json b/package.json index 6d5319a..6993cd5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,11 @@ "build": "astro build", "preview": "astro preview", "astro": "astro", - "lint": "pnpm lint:eslint && pnpm lint:md && pnpm lint:regions && pnpm typecheck", + "generate:glossary": "tsx scripts/generate-glossary.ts", + "lint:glossary": "tsx scripts/generate-glossary.ts --check", + "prebuild": "tsx scripts/generate-glossary.ts", + "predev": "tsx scripts/generate-glossary.ts", + "lint": "pnpm lint:eslint && pnpm lint:md && pnpm lint:regions && pnpm lint:glossary && pnpm typecheck", "lint:eslint": "eslint .", "lint:md": "remark src/content/docs --ext mdx --frail", "lint:regions": "tsx scripts/validate-regions.ts", diff --git a/scripts/generate-glossary.ts b/scripts/generate-glossary.ts new file mode 100644 index 0000000..9dacca1 --- /dev/null +++ b/scripts/generate-glossary.ts @@ -0,0 +1,59 @@ +import { execSync } from 'child_process'; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'; +import { join, resolve } from 'path'; +import { fileURLToPath } from 'url'; +import { glossaryTerms } from '../src/data/glossary'; + +const ROOT = fileURLToPath(new URL('..', import.meta.url)); +const OUTPUT = resolve(ROOT, 'src/content/docs/resources/glossary.mdx'); +const CHECK = process.argv.includes('--check'); + +const sorted = [...glossaryTerms].sort((a, b) => + a.term.toLowerCase().localeCompare(b.term.toLowerCase()), +); + +const frontmatter = ['---', 'title: Glossary', '---']; + +const body = [ + '{/* This file is auto-generated by scripts/generate-glossary.ts. Do not edit directly. */}', + '', + '', +]; + +for (const { term, definition } of sorted) { + body.push(`**${term}**`); + body.push(''); + body.push(`${definition}`); + body.push(''); +} + +const content = [...frontmatter, '', ...body].join('\n'); + +function formatFile(filePath: string) { + execSync(`pnpm prettier --write "${filePath}"`, { + cwd: ROOT, + stdio: 'pipe', + }); +} + +if (CHECK) { + const existing = readFileSync(OUTPUT, 'utf-8'); + const tmpDir = mkdtempSync( + join(ROOT, 'src', 'content', 'docs', 'glossary-'), + ); + const tmpFile = join(tmpDir, 'glossary.mdx'); + writeFileSync(tmpFile, content); + formatFile(tmpFile); + const formatted = readFileSync(tmpFile, 'utf-8'); + rmSync(tmpDir, { recursive: true }); + if (formatted !== existing) { + console.error( + 'src/content/docs/resources/glossary.mdx is out of date.\n' + + 'Run `pnpm generate:glossary` to regenerate it.', + ); + process.exit(1); + } +} else { + writeFileSync(OUTPUT, content); + formatFile(OUTPUT); +} diff --git a/src/content/docs/resources/glossary.mdx b/src/content/docs/resources/glossary.mdx index 412746b..1082c96 100644 --- a/src/content/docs/resources/glossary.mdx +++ b/src/content/docs/resources/glossary.mdx @@ -1,55 +1,51 @@ --- -title: Welcome to the Glossary -description: A compiled list of words and definitions to help you understand FRC programming terminology. +title: Glossary --- -## Why this exists. +{/* This file is auto-generated by scripts/generate-glossary.ts. Do not edit directly. */} -We know it can be hard learning each and every term thrown around in FRC programming, so we have compiled a list of words and definitions to aid you throughout your learning. +**CAN** -## Terms +Controller Area Network: typically yellow and green cable used to communicate with motor controllers and sensors, can be run in various topographies instead of each cable needing to connect to SystemCore -**PDH** +**Limit Switch** -: Power Distribution Hub. +Type of sensor that triggers when physically or magnetically hit. +Can be used to trigger actions on a rising or falling edge, or check state of a mechanism -**SparkMAX** +**Magnetic Encoder** -: Motor controller for REV motors. +An encoder that uses a receiver and a magnet to measure position and motion **Main Breaker** -: Switch for the robot. +Power switch for the robot -**PWM** - -: Pulse Width Modulation cable. - -**RIO** +**PDH** -: RoboRIO, brain of the robot. +Power Distribution Hub -**Blinkn** +**PWM** -: LED controller for REV. +Pulse Width Modulation: A communication spec used to communicate with motor controllers and sensors, needs to connect back to SystemCore -**Radio** +**Repository** -: Device that helps the robot communicate with the driver station. +A storage location for software packages, often used in version control systems like Git. +Repositories are just folders that contain files and subfolders, and they can be hosted on platforms like GitHub to facilitate collaboration and version tracking -**Limit Switch** +**Spark MAX** -: Type of sensor that acts as a soft limit when physically or magnetically hit. +Motor controller for REV motors -**Throughbore Encoder** +**SystemCore** -: An encoder that allows shafts to pass through its center to record position. +Main processor for robot code, contains various IO -**Magnetic Encoder** +**Talon FX** -: An encoder that uses magnetic fields to measure position or motion. +Motor controller for CTRE motors -**Repository** +**Throughbore Encoder** -: A storage location for software packages, often used in version control systems like Git. -Repositories are just folders that contain files and subfolders, and they can be hosted on platforms like GitHub to facilitate collaboration and version tracking. +An encoder that allows shafts to pass through its center to record angular position diff --git a/src/data/glossary.ts b/src/data/glossary.ts index bc16752..f05fcc9 100644 --- a/src/data/glossary.ts +++ b/src/data/glossary.ts @@ -4,6 +4,8 @@ * Add terms here to automatically highlight them across the site * with a dotted underline and hover tooltip. * + * Definitions should not have a period at the end + * * Format: * { * term: "TERM", // The word/abbreviation to match (case-insensitive) @@ -17,208 +19,58 @@ export interface GlossaryTerm { } export const glossaryTerms: GlossaryTerm[] = [ - // Vendors - { - term: 'WCP', - definition: 'West Coast Products', - }, - { - term: 'REV', - definition: 'REV Robotics', - }, - { - term: 'TTB', - definition: 'The Thrifty Bot', - }, - { - term: 'Redux', - definition: 'Redux Robotics', - }, - { - term: 'MCM', - definition: 'McMaster Carr', - }, - - // Intake styles - { - term: 'OTB', - definition: - '"Over the Bumper" - A style of intake where you lift the piece over the bumper', - }, - { - term: 'UTB', - definition: - '"Under the Bumper" - A style of intake where you move the piece under the bumper', - }, - - // Parts & Components - { - term: 'COTS', - definition: - 'Commercial Off the Shelf - Parts you can buy from a vendor', - }, - { - term: 'V4B', - definition: - '"Virtual 4 Bar" - Where a second degree of freedom is directly geared off a previous degree of freedom instead of being moved independently or by a linkage', - }, - { - term: 'C-C', - definition: '"Center to Center" distance', - }, - { - term: 'turnbuckle', - definition: - 'A threaded part that goes in between chain links to tension the chain', - }, - { - term: '4Bar', - definition: 'A type of linkage characterized by its 4 pivot points', - }, - { - term: 'Tube-Nut', - definition: - 'Also known as a "Star Nut" - Provides an easy way to put a thread in end of a hollow tube allowing you to bolt the tube to another part', - }, - { - term: 'Gusset', - definition: - 'Reinforcement plate, usually made of aluminum, used to strengthen connections between two tubes', - }, - - // Physics & Engineering concepts - { - term: 'COG', - definition: - 'Center of Gravity, also referred to as COM (Center of Mass)', - }, - { - term: 'Cantilever', - definition: "Horizontal element that's supported by one side only", - }, - { - term: 'Shear', - definition: - 'When forces are applied parallel to the plane of a material, causing breaking of fasteners due to excessive force and stress', - }, - { - term: 'Torque', - definition: 'Force that produces rotational movement', - }, - { - term: 'DP', - definition: - 'Diametral pitch - The number of teeth per inch of the pitch circle', - }, - { - term: 'Backlash', - definition: - "'Slop' in a power transmission system; can wiggle back and forth without engaging the whole system", - }, - - // Axle types - { - term: 'Deadaxle', - definition: - 'A type of axle setup where the axle is fixed in place and/or is not transferring the torque of the system through it', - }, - { - term: 'Liveaxle', - definition: - 'A type of axle setup where the main torque transfer is through the axle', - }, - { - term: 'Zombie-Axle', - definition: - 'Typically used on pivots - A zombie axle spins with the mechanism, but is transferring little to no torque through it. Commonly used to put an encoder on the pivot point', - }, - // Electronics { term: 'PDH', definition: 'Power Distribution Hub', }, { - term: 'SparkMAX', + term: 'Spark MAX', definition: 'Motor controller for REV motors', }, { - term: 'PWM', - definition: 'Pulse Width Modulation cable', - }, - { - term: 'RIO', - definition: 'roboRIO - The brain of the robot', + term: 'Talon FX', + definition: 'Motor controller for CTRE motors', }, { - term: 'Blinkin', - definition: 'LED controller for REV', + term: 'SystemCore', + definition: 'Main processor for robot code, contains various IO', }, { - term: 'Radio', + term: 'CAN', definition: - 'Device that helps the robot communicate with the driver station', - }, - - // Manufacturing & Materials - { - term: '3DP', - definition: 'Abbreviation for 3D printed or 3D printing', - }, - { - term: 'Poly', - definition: 'Abbreviation for polycarbonate', - }, - { - term: 'PC', - definition: 'Abbreviation for polycarbonate', + 'Controller Area Network: typically yellow and green cable used to communicate with motor controllers and sensors, can be run in various topographies instead of each cable needing to connect to SystemCore', }, { - term: 'Stripping', - definition: - 'Process of removing threads or bolt heads, often due to excessive force or wear', - }, - { - term: 'Tapping', + term: 'PWM', definition: - 'The process of creating threads in a hole using a tap tool', - }, - { - term: 'Billet', - definition: 'Component machined down from a solid block of material', + 'Pulse Width Modulation: A communication spec used to communicate with motor controllers and sensors, needs to connect back to SystemCore', }, - - // Robot structure { - term: 'Brainpan', - definition: 'Flipped electronics bellypan', + term: 'Main Breaker', + definition: 'Power switch for the robot', }, { - term: 'Bellypan', + term: 'Limit Switch', definition: - 'Plate for mounting electronics on the underside of your drivebase', + 'Type of sensor that triggers when physically or magnetically hit. Can be used to trigger actions on a rising or falling edge, or check state of a mechanism', }, { - term: 'Hardstop', + term: 'Throughbore Encoder', definition: - 'A physical limit designed to prevent a mechanism or component from moving beyond a certain point', + 'An encoder that allows shafts to pass through its center to record angular position', }, { - term: 'Softstop', + term: 'Magnetic Encoder', definition: - 'A software-based limit or control mechanism that restricts the movement of a mechanism or component to prevent it from exceeding certain parameters', + 'An encoder that uses a receiver and a magnet to measure position and motion', }, - // Design concepts - { - term: 'Packaging', - definition: - 'The way in which you fit parts of your robot together in a space', - }, + // Software { - term: 'Parametric', + term: 'Repository', definition: - 'Designed in a way that uses relationships between steps to maintain design intent', + 'A storage location for software packages, often used in version control systems like Git. Repositories are just folders that contain files and subfolders, and they can be hosted on platforms like GitHub to facilitate collaboration and version tracking', }, ]; diff --git a/src/plugins/remark-glossary.ts b/src/plugins/remark-glossary.ts index d47722e..804732d 100644 --- a/src/plugins/remark-glossary.ts +++ b/src/plugins/remark-glossary.ts @@ -1,5 +1,6 @@ import { visit } from 'unist-util-visit'; import type { Root, Text } from 'mdast'; +import type { VFile } from 'vfile'; import { glossaryTerms } from '../data/glossary'; const sortedTerms = [...glossaryTerms].sort( @@ -21,7 +22,9 @@ function escapeRegex(str: string): string { } export function remarkGlossary() { - return (tree: Root) => { + return (tree: Root, file: VFile) => { + if (file.path?.endsWith('glossary.mdx')) return; + visit(tree, 'text', (node: Text, index, parent) => { if (!parent || index === undefined) return; @@ -63,7 +66,7 @@ export function remarkGlossary() { newNodes.push({ type: 'html', - value: `${escapeHtml(matchedTerm)}`, + value: `${escapeHtml(matchedTerm)}`, }); lastIndex = matchEnd; diff --git a/src/styles/global.css b/src/styles/global.css index d5cfaed..51912f1 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -302,7 +302,7 @@ abbr.glossary-term:hover { } abbr.glossary-term::after { - content: attr(title); + content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%;