diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecc6c32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +dist +.vscode +node_modules \ No newline at end of file diff --git a/bundler/README.md b/bundler/README.md new file mode 100644 index 0000000..c67f18a --- /dev/null +++ b/bundler/README.md @@ -0,0 +1,51 @@ +# CSS Bundling + +To get started, ensure you have a recent version of Nodejs (>= 18) installed run + +``` +npm install +``` + +from the `bundler/` directory (this directory). + +Then run + +``` +npx vite build +``` + +to test your installation. If all worked well, you should have a `dist/default` directory that contains bundled CSS in a subdirectory. + +## Usage + +Environmental variables control what options `vite` uses to package the CSS. + +- `PTX_VERSION` a string that will be used to set the subdirectory into which bundled assets are written (defaults to `version` in `package.json`) +- `PTX_MINIFY` a string `true` or `false` indicating whether to minify the CSS after it is bundled. +- `PTX_STYLE` a string corresponding to the name of a subdirectory of `src` indicating which CSS to bundle. For example `PTX_STYLE=prism` will bundle the CSS for prismjs into `dist/prism`. + +### Example + +To create a version 1.7 minified bundle of `oscarlevin`, run + +``` +PTX_VERSION=1.7 PTX_MINIFY=true PTX_STYLE=oscarlevin npx vite build +``` + +In `dist/oscarlevin/1.7/styles` should now be the bundled CSS, along with any other required assets (e.g., fonts). + +### Notes + +The bundler by default will create an `index.html` and `index.js` file. These files are a byproduct of the build process and can be ignored. + +## Development + +Each directory in `src/` contains a different build target. The `index.ts` file contains a list of import statements for the CSS that will +be bundled. If you want to extend an existing bundle, you may import the existing bundle with `import "../";` (no circular references, please!). + +To create a new target, copy an existing target and modify its `index.ts`. You can then set `PTX_STYLE=` to build the new target. + +### Notes + +Some assets are imported from `"../node_modules/..."`. These assets have been installed via the `npm install` command. If you find +additional assets that are needed, you can run `npm install `. diff --git a/bundler/package-lock.json b/bundler/package-lock.json new file mode 100644 index 0000000..727de7b --- /dev/null +++ b/bundler/package-lock.json @@ -0,0 +1,250 @@ +{ + "name": "bundler", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "bundler", + "version": "1.0.0", + "license": "GPL-3.0-or-later", + "dependencies": { + "@fontsource/dejavu-serif": "^5.0.7", + "@fontsource/material-symbols-outlined": "^5.0.16", + "@fontsource/open-sans": "^5.0.17", + "@fontsource/roboto-serif": "^5.0.8", + "@fortawesome/fontawesome-free": "^6.4.2", + "@types/node": "^20.8.8", + "prismjs": "^1.29.0", + "vite": "^4.5.0" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@fontsource/dejavu-serif": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@fontsource/dejavu-serif/-/dejavu-serif-5.0.7.tgz", + "integrity": "sha512-hi90XyjkmApkB38fyxwWuk85AxLLBGQ+yNZgIlSh/kBTBWYawOoVgolldA0+HHiEqsAnLDkFehQIEFqBL+yN8g==" + }, + "node_modules/@fontsource/material-symbols-outlined": { + "version": "5.0.16", + "resolved": "https://registry.npmjs.org/@fontsource/material-symbols-outlined/-/material-symbols-outlined-5.0.16.tgz", + "integrity": "sha512-Hwu3NKLdzpgyFiCXsKl6ZhhcvGmLKsZxTGo7zSiQrynw9vuxdrL5uEWkEBwnCNZUujpXUPfWuqk+KPNWfXZOZw==" + }, + "node_modules/@fontsource/open-sans": { + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/@fontsource/open-sans/-/open-sans-5.0.17.tgz", + "integrity": "sha512-4mIAJ/1B9pltG7NhxqReeu46L1+j/eAgwWmvjXh+FhsgcgsboQDrfn9wtUP2PWB7/JrMA4Hd9N/4qAN6kJSdyg==" + }, + "node_modules/@fontsource/roboto-serif": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto-serif/-/roboto-serif-5.0.8.tgz", + "integrity": "sha512-xRCeQOP3+iH23vGBe1nRR5zl+c4cxg2tq+r1cJ2bPd30TKqe3Q6kEBn3n9NC6LxN3P2A6w/PaT+bS1/mRqlgvg==" + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz", + "integrity": "sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/node": { + "version": "20.8.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz", + "integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==", + "dependencies": { + "undici-types": "~5.25.1" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, + "node_modules/vite": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + } +} diff --git a/bundler/package.json b/bundler/package.json new file mode 100644 index 0000000..c3078db --- /dev/null +++ b/bundler/package.json @@ -0,0 +1,29 @@ +{ + "name": "bundler", + "version": "1.0.0", + "description": "Bundle PreTeXt CSS", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/PreTeXtBook/CSS_core.git" + }, + "author": "", + "license": "GPL-3.0-or-later", + "bugs": { + "url": "https://github.com/PreTeXtBook/CSS_core/issues" + }, + "homepage": "https://github.com/PreTeXtBook/CSS_core#readme", + "dependencies": { + "@fontsource/dejavu-serif": "^5.0.7", + "@fontsource/material-symbols-outlined": "^5.0.16", + "@fontsource/open-sans": "^5.0.17", + "@fontsource/roboto-serif": "^5.0.8", + "@fortawesome/fontawesome-free": "^6.4.2", + "@types/node": "^20.8.8", + "prismjs": "^1.29.0", + "vite": "^4.5.0" + } +} diff --git a/bundler/src/all/index.html b/bundler/src/all/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/all/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/all/index.ts b/bundler/src/all/index.ts new file mode 100644 index 0000000..ae36943 --- /dev/null +++ b/bundler/src/all/index.ts @@ -0,0 +1,6 @@ +import "../default"; +import "../prism"; +import "../fontawesome"; +import "../fonts"; + +export default {}; diff --git a/bundler/src/default/index.html b/bundler/src/default/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/default/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/default/index.ts b/bundler/src/default/index.ts new file mode 100644 index 0000000..301762a --- /dev/null +++ b/bundler/src/default/index.ts @@ -0,0 +1,11 @@ +import "../../../pretext.css"; +import "../../../pretext_add_on.css"; +import "../../../shell_default.css"; +import "../../../banner_default.css"; +import "../../../navbar_default.css"; +import "../../../toc_default.css"; +import "../../../style_default.css"; +import "../../../colors_blue_red.css"; +import "../../../setcolors.css"; + +export default {}; diff --git a/bundler/src/fontawesome/index.html b/bundler/src/fontawesome/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/fontawesome/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/fontawesome/index.ts b/bundler/src/fontawesome/index.ts new file mode 100644 index 0000000..e8a6a16 --- /dev/null +++ b/bundler/src/fontawesome/index.ts @@ -0,0 +1,3 @@ +import "../../node_modules/@fortawesome/fontawesome-free/css/all.css"; + +export default {}; diff --git a/bundler/src/fonts/fonts.css b/bundler/src/fonts/fonts.css new file mode 100644 index 0000000..7f1811c --- /dev/null +++ b/bundler/src/fonts/fonts.css @@ -0,0 +1,15 @@ +.material-symbols-outlined { + font-family: "Material Symbols Outlined"; + font-weight: normal; + font-style: normal; + font-size: 24px; + line-height: 1; + letter-spacing: normal; + text-transform: none; + display: inline-block; + white-space: nowrap; + word-wrap: normal; + direction: ltr; + -moz-font-feature-settings: "liga"; + -moz-osx-font-smoothing: grayscale; +} diff --git a/bundler/src/fonts/index.html b/bundler/src/fonts/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/fonts/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/fonts/index.ts b/bundler/src/fonts/index.ts new file mode 100644 index 0000000..abd53c6 --- /dev/null +++ b/bundler/src/fonts/index.ts @@ -0,0 +1,11 @@ +// To install a new font, run `npm install @fontsource/ +// See https://fontsource.org/docs/getting-started/install +import "@fontsource/material-symbols-outlined"; +import "@fontsource/dejavu-serif"; +import "@fontsource/roboto-serif"; +import "@fontsource/open-sans"; + +// Extra styles for particular fonts. +import "./fonts.css" + +export default {}; diff --git a/bundler/src/oscarlevin/index.html b/bundler/src/oscarlevin/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/oscarlevin/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/oscarlevin/index.ts b/bundler/src/oscarlevin/index.ts new file mode 100644 index 0000000..8a6a946 --- /dev/null +++ b/bundler/src/oscarlevin/index.ts @@ -0,0 +1,4 @@ +import "../default"; +import "../../../style_oscarlevin.css"; + +export default {}; diff --git a/bundler/src/prism/index.html b/bundler/src/prism/index.html new file mode 100644 index 0000000..ad13b68 --- /dev/null +++ b/bundler/src/prism/index.html @@ -0,0 +1,12 @@ + + + + + + CSS Bundler + + +
+ + + diff --git a/bundler/src/prism/index.ts b/bundler/src/prism/index.ts new file mode 100644 index 0000000..d9ed6b4 --- /dev/null +++ b/bundler/src/prism/index.ts @@ -0,0 +1,5 @@ +import "../../node_modules/prismjs/themes/prism.css"; +import "../../node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css"; +import "../../node_modules/prismjs/plugins/line-highlight/prism-line-highlight.css"; + +export default {}; diff --git a/bundler/vite.config.ts b/bundler/vite.config.ts new file mode 100644 index 0000000..207d684 --- /dev/null +++ b/bundler/vite.config.ts @@ -0,0 +1,58 @@ +import { defineConfig } from "vite"; +import * as path from "node:path"; +import * as fs from "node:fs"; + +import packageJson from "./package.json"; +const __dirname = path.dirname(new URL(import.meta.url).pathname); + +const VERSION = process.env.PTX_VERSION ?? packageJson.version; +const MINIFY = makeBoolean(process.env.PTX_MINIFY) ?? false; +let STYLE = process.env.PTX_STYLE ?? "default"; + +const root = path.join(__dirname, "src", STYLE); +const outDir = path.join(__dirname, "dist", STYLE, VERSION); + +// If the root directory doesn't exist, throw an error. +if (!fs.existsSync(root)) { + console.warn( + `The directory ./src/${STYLE} does not exist. Make sure the PTX_STYLE variable is set to be the name of a subdirectory of ./src.` + ); + process.exit(1); +} + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [], + root, + base: "./", + build: { + outDir, + cssMinify: MINIFY, + emptyOutDir: true, + rollupOptions: { + output: { + entryFileNames: `[name]-${VERSION}.js`, + chunkFileNames: `[name]-${VERSION}.js`, + assetFileNames: `styles/[name].[ext]`, + }, + }, + }, +}); + +/** + * Make the string `val` into a boolean. + */ +function makeBoolean(val: string | undefined): boolean | undefined { + if (val === undefined) { + return undefined; + } + const normalized = val.trim().toLowerCase(); + switch (normalized) { + case "": + case "n": + case "no": + case "false": + return false; + } + return true; +}