Skip to content

Commit

Permalink
feat: add footer
Browse files Browse the repository at this point in the history
* Add footer with links to GitHub, LinkedIn, Facebook, and X profiles.

* Add FontAwesome Free 6.5.2 Web SVG icons.

* Add custom version of parcel-transformer-elm-svg-modules.
  • Loading branch information
nisavid committed May 30, 2024
1 parent 2481969 commit f2eaac3
Show file tree
Hide file tree
Showing 2,053 changed files with 2,431 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .parcelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// vim: ft=json5
{
"extends": "@parcel/config-default",
"transformers": {
"*.elm": [
"./parcel-transformer-elm-svg-modules.cjs",
"...",
],
},
"resolvers": [
"@parcel/resolver-glob",
"...",
Expand Down
3 changes: 2 additions & 1 deletion elm.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"type": "application",
"source-directories": [
"src"
"src",
"elm-stuff/svg-modules"
],
"elm-version": "0.19.1",
"dependencies": {
Expand Down
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
"@html-eslint/eslint-plugin": "^0.24.1",
"@html-eslint/parser": "^0.24.1",
"@parcel/config-default": "^2.12.0",
"@parcel/diagnostic": "^2.12.0",
"@parcel/packager-raw-url": "^2.12.0",
"@parcel/plugin": "^2.12.0",
"@parcel/resolver-glob": "^2.12.0",
"@parcel/transformer-elm": "^2.12.0",
"@parcel/transformer-jsonld": "^2.12.0",
Expand All @@ -93,6 +95,7 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-tsdoc": "^0.3.0",
"firebase-tools": "^13.10.2",
"glob": "^8.1.0",
"globals": "^15.3.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
Expand All @@ -106,6 +109,7 @@
"prettier-plugin-elm": "^0.11.0",
"prettier-plugin-tailwindcss": "^0.5.14",
"process": "^0.11.10",
"svg2elm": "^1.2.4",
"svgo": "^3.3.2",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.5",
Expand All @@ -124,6 +128,23 @@
"nesting": true
}
},
"elmSvgModules": [
{
"inputSvgs": "src/assets/fontawesome/brands/*.svg",
"outputModuleName": "FontAwesome.Brands",
"outputModuleDir": "elm-stuff/svg-modules"
},
{
"inputSvgs": "src/assets/fontawesome/regular/*.svg",
"outputModuleName": "FontAwesome.Regular",
"outputModuleDir": "elm-stuff/svg-modules"
},
{
"inputSvgs": "src/assets/fontawesome/solid/*.svg",
"outputModuleName": "FontAwesome.Solid",
"outputModuleDir": "elm-stuff/svg-modules"
}
],
"targets": {
"default": {
"distDir": "dist",
Expand Down
131 changes: 131 additions & 0 deletions parcel-transformer-elm-svg-modules.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* This file is based on the upstream transformer code from
* https://github.com/ChristophP/parcel-transformer-elm-svg-modules/raw/main/src/ElmSvgModulesTransformer.js
*
* Original Author: Christoph “Deedo” Pölt
*
* This local version addresses an issue in `svg2elm` whereby each SVG comment
* is transcribed as a blank Elm list item (more precisely, an Elm comment
* followed by a comma) in the generated Elm modules, which results in invalid
* Elm code.
*
* Changes:
*
* 1. Added a function to strip the commas following comments.
*
* 2. Applied the comment-following-comma-stripping function to the generated
* module code.
*
* TODO: Fix the bug upstream in `svg2elm` and remove this local version.
*
* TODO: Alternatively or additionally, reimplement this transformer to adhere
* to the intended design of Parcel transformers. Presently, it's applied
* to `*.elm` assets, but all it does with them is to invalidate them
* in the build cache whenever the generated Elm SVG modules get updated;
* the actual transformation—from SVG images to Elm modules—is performed
* as a side effect, and the generated Elm modules apparently do not get
* put through the transformer pipeline. Instead, this transformer should
* be implemented so as to apply to `*.svg` assets and transform them to the
* corresponding `*.elm` files—just as any normal transformer plugin would—
* and apply the cache invalidation for non-generated Elm modules
* as a side effect.
*/

const ThrowableDiagnostic = require("@parcel/diagnostic");
const { Transformer } = require("@parcel/plugin");

const { generateModule } = require("svg2elm");
const glob = require("glob");
const fs = require("fs").promises;
const path = require("path");
const { promisify } = require("util");

const { md } = ThrowableDiagnostic;
const asyncGlob = promisify(glob);

const settle = (promise) =>
Promise.allSettled([promise]).then(([{ value, reason }]) => [reason, value]);

function stripCommentFollowingCommas(code) {
return code.replace(/(\{-.*?-}),/gs, "$1");
}

module.exports = new Transformer({
async loadConfig({ config }) {
const { contents } = await config.getConfig(["package.json"]);

return contents.elmSvgModules;
},
async transform({ asset, config, logger }) {
const generate = async ({
inputSvgs,
outputModuleName = "Icons",
outputModuleDir = "src",
}) => {
const elmModulePath = outputModuleName
.replaceAll(".", path.sep)
.concat(".elm");
const resolvedModulePath = path.join(outputModuleDir, elmModulePath);
await fs.mkdir(path.dirname(resolvedModulePath), { recursive: true });

logger.info({
message: `Writing module to: ${resolvedModulePath} for ${inputSvgs}`,
});

// glob for svgs
const [globErr, filePaths] = await settle(asyncGlob(inputSvgs, {}));
if (globErr) {
throw new ThrowableDiagnostic({
diagnostic: {
message: `Failed to resolve file path for ${outputModuleName}`,
stack: globErr.stack,
},
});
}

logger.verbose({ message: `Found SVGs ${filePaths.join(", ")}` });

// generate module code
const [genErr, moduleCode] = await settle(
generateModule(outputModuleName, filePaths),
);

if (genErr) {
throw new ThrowableDiagnostic({
diagnostic: {
message: `Failed to generate ${outputModuleName}`,
stack: genErr.stack,
},
});
}

// set up invalidations
asset.invalidateOnFileCreate({ glob: inputSvgs });
filePaths.forEach((filePath) => {
asset.invalidateOnFileChange(filePath);
});

// Strip commas following comments from the generated module code
const cleanedModuleCode = stripCommentFollowingCommas(moduleCode);

// write generated Elm module to disk
const finalCode = `-- THIS MODULE IS GENERATED. DON'T EDIT BY HAND.\n\n${cleanedModuleCode}`;

const content = await fs
.readFile(resolvedModulePath, "utf-8")
.catch(() => "");

// only write module if code is new or has changed
if (content === "" || content !== finalCode) {
await fs.writeFile(resolvedModulePath, finalCode);
}
};

await Promise.allSettled(config.map(generate));

logger.info({ message: md`Generated ${config.length} module(s)` });

// Return the asset
return [asset];
},
});
Loading

0 comments on commit f2eaac3

Please sign in to comment.