Code Monkey home page Code Monkey logo

fontawesome-subset's People

Contributors

it-can avatar omacranger avatar sr258 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fontawesome-subset's Issues

Make font-awesome free dependency optional

Hello,

I found this project to make a font-awesome subset (nice project btw) and want to use it to amek a font-awesome pro subset. When I install this project as dependency it automatically downloads font-awesome free as well, while I don't need it.

Could font-awesome free moved from the dependencies to the optional dependencies?

Regards.

Custom icon

Hello,

I use the pro version with FontAwesome Kits, but I want to switch to self hosting fonts to improve performance. Subsetter software is easy to use but don't provide feature to add custom icon.

Any plan to add feature for support custom icons with fontawesome-subset ?

Cédric

Include a script for auto-subsetting all the icons in your project

I'm using your library (THANK YOU!) and made a script so that in dev we could use the regular fontawesome without having to worry about which icons are or aren't in the subset, and when we build the script discovers all the icons in use and auto-generates a subset.

I think with some improvements could be valuable to anyone who uses this project. Namely, the fact that grep isn't available on all systems should be accounted for.

Script

fa-subset.zip

Since you can't do conditional imports in SCSS, in dev mode we generate a file that just includes the fontawesome lib as normal.

In prod the generated SCSS file references the subsetted font files.

package.json scripts

We use Webpack Encore so something like this worked for us

"scripts": {
    "dev": "npm run fa-subset && encore dev",
    "build": "npm run fa-subset && encore production --progress",
    "fa-subset": "node scripts/fa-subset/index.mjs"
}

In SCSS

// $env is set in webpack.config.js via sass-loader's `additionalOptions` config property
@if not variable-exists(env) or $env == "development" {
    // Use regular fontawesome-pro in dev for doubleplusgood DX
    $fa-font-path: "~@fortawesome/fontawesome-pro/webfonts";
} @else {
    // Use auto-generated subset in production for doubleplusgood UX
    $fa-font-path: "/build/fontawesome/webfonts";
}

// Use self-hosted, subsetted fontawesome
@import "/build/fontawesome/fontawesome.scss";

@import "~@fortawesome/fontawesome-pro/scss/regular";
@import "~@fortawesome/fontawesome-pro/scss/solid";
@import "~@fortawesome/fontawesome-pro/scss/light";
@import "~@fortawesome/fontawesome-pro/scss/duotone";
@import "~@fortawesome/fontawesome-pro/scss/brands";

Error: Could not convert the given font.

Hi, I'm trying to use this package but encountering Error: Could not convert the given font..

Here is how to replicate it. First create these file on the same directory:

  • package.json
{
  "devDependencies": {
    "@fortawesome/fontawesome-free": "5.14.0",
    "fontawesome-subset": "^3.0.0"
  }
}
  • extract_font.js
const {fontawesomeSubset} = require("fontawesome-subset");

fontawesomeSubset([
    'envelope-o',
    'github',
    'linkedin',
    'facebook'
], 'output');

Now run:

npm i

added 111 packages, and audited 112 packages in 29s

5 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Then:

node extract_font.js
/Users/linus/myself/lamhoangtung.github.io/node_modules/fontawesome-subset/dist/index.js:115
        (0, fs_1.writeFileSync)(`${outputFile}.woff2`, ttf2woff2(ttf));
                                                       ^

Error: Could not convert the given font.
    at fontawesomeSubset (/Users/linus/myself/lamhoangtung.github.io/node_modules/fontawesome-subset/dist/index.js:115:56)
    at Object.<anonymous> (/Users/linus/myself/lamhoangtung.github.io/extract_font.js:3:1)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

Here you can see the Error: Could not convert the given font..

Also the output folder will be created with some of these files, but certainly not what we need.

tree output
output
├── fa-solid-900.eot
├── fa-solid-900.svg
├── fa-solid-900.ttf
└── fa-solid-900.woff

0 directories, 4 files

Btw, my node version are v16.13.1.

Are there anything that I'm doing wrong here ? How can I overcome this problem ? Thanks for checking by !

Compatibility with Yarn and Plug'n'Play mode

Hi,

We are currently using fontawesome-subset in our project, where the package manager is Yarn version 1. I am trying to migrate to Yarn modern version and to enable the Plug'n'Play mode, which basically removes the node_modules folder and uses the .yarn folder instead. Now when I try to run the script to generate the subset, I get the following error message:

Unable to find either the Free or Pro FontAwesome files in node_modules folder. Double-check that you have your preferred fontawesome package as a dependency in package.json and rerun the installation.

I understand the script is checking for existence of Font-Awesome in node_modules

    if (!(existsSync("node_modules/@fortawesome/fontawesome-free") || existsSync("node_modules/@fortawesome/fontawesome-pro"))) {

This should be done differently for Yarn Modern version, although I am not completely sure what would be the best way. Could you possibly look into this?

Many thanks for your help!

Woff, EOT, SVG fonts dropped

Hi,

I see WOFF, EOT, SVG are not produced in version 4, but were in version 3.
May I ask what was behind that decision ? is it just about modern browser support ?

TTF and WOFF2 are great, but I need to add WOFF for some (unfortunate) IE11 legacy support for a project.
I've added the targetFormat - is that enough ? or do I have to do something else ?
Are you planning to make the targetFormats configurable via arguments in the function - this would be great :)

diff --git a/node_modules/fontawesome-subset/dist/index.js b/node_modules/fontawesome-subset/dist/index.js
index e80b450..84a37aa 100644
--- a/node_modules/fontawesome-subset/dist/index.js
+++ b/node_modules/fontawesome-subset/dist/index.js
@@ -14,6 +14,7 @@ const subset_font_1 = __importDefault(require("subset-font"));
 const yaml_1 = __importDefault(require("yaml"));
 const utils_1 = require("./utils");
 const OUTPUT_FORMATS = [
+    { targetFormat: "woff", fileExt: "woff" },
     { targetFormat: "woff2", fileExt: "woff2" },
     { targetFormat: "sfnt", fileExt: "ttf" },
 ];

Task manager?

Hi,
Could you please provide an example for "Run via your favorite task manager" ?

I'm new to this and I'm not even sure if you mean Webpack or Grunt or something else.

An example you're using would be welcome.

Thanks!

a code for generating all.css

hoping that this will save time to the one after me, here's my code for generating the all.css files only with the necessary stuff like font-awsome subsetter app does :)

//sets is the same as the object you pass to fontawesomeSubset

const all_icons = Object.values(sets).flat(1);

const vars = fs.readFileSync('node_modules/@fortawesome/fontawesome-pro/scss/_variables.scss', 'utf8').split('\n')
	.filter(l => l.startsWith('$fa-var-'))
	.map(l => l.match(/\$fa-var-([^:]+): \\([^:]+);/).slice(1, 3)); //[ico, code]

const css = [];
css.push(`/*!
 * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com
 * License - https://fontawesome.com/license (Commercial License)
 */
.fa, .fab, .fad, .fal, .far, .fas {
	-moz-osx-font-smoothing: grayscale;
	-webkit-font-smoothing: antialiased;
	display: inline-block;
	font-style: normal;
	font-variant: normal;
	text-rendering: auto;
	line-height: 1
}

.fa-lg {
	font-size: 1.33333em;
	line-height: .75em;
	vertical-align: -.0667em
}

.fa-xs {
	font-size: .75em
}

.fa-sm {
	font-size: .875em
}

.fa-1x {
	font-size: 1em
}

.fa-2x {
	font-size: 2em
}

.fa-3x {
	font-size: 3em
}

.fa-4x {
	font-size: 4em
}

.fa-5x {
	font-size: 5em
}

.fa-6x {
	font-size: 6em
}

.fa-7x {
	font-size: 7em
}

.fa-8x {
	font-size: 8em
}

.fa-9x {
	font-size: 9em
}

.fa-10x {
	font-size: 10em
}

.fa-fw {
	text-align: center;
	width: 1.25em
}

.fa-ul {
	list-style-type: none;
	margin-left: 2.5em;
	padding-left: 0
}

.fa-ul > li {
	position: relative
}

.fa-li {
	left: -2em;
	position: absolute;
	text-align: center;
	width: 2em;
	line-height: inherit
}

.fa-border {
	border: .08em solid #eee;
	border-radius: .1em;
	padding: .2em .25em .15em
}

.fa-pull-left {
	float: left
}

.fa-pull-right {
	float: right
}

.fa.fa-pull-left, .fab.fa-pull-left, .fal.fa-pull-left, .far.fa-pull-left, .fas.fa-pull-left {
	margin-right: .3em
}

.fa.fa-pull-right, .fab.fa-pull-right, .fal.fa-pull-right, .far.fa-pull-right, .fas.fa-pull-right {
	margin-left: .3em
}

.fa-spin {
	-webkit-animation: fa-spin 2s linear infinite;
	animation: fa-spin 2s linear infinite
}

.fa-pulse {
	-webkit-animation: fa-spin 1s steps(8) infinite;
	animation: fa-spin 1s steps(8) infinite
}

@-webkit-keyframes fa-spin {
	0% {
		-webkit-transform: rotate(0deg);
		transform: rotate(0deg)
	}
	to {
		-webkit-transform: rotate(1turn);
		transform: rotate(1turn)
	}
}

@keyframes fa-spin {
	0% {
		-webkit-transform: rotate(0deg);
		transform: rotate(0deg)
	}
	to {
		-webkit-transform: rotate(1turn);
		transform: rotate(1turn)
	}
}

.fa-rotate-90 {
	-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
	-webkit-transform: rotate(90deg);
	transform: rotate(90deg)
}

.fa-rotate-180 {
	-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
	-webkit-transform: rotate(180deg);
	transform: rotate(180deg)
}

.fa-rotate-270 {
	-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
	-webkit-transform: rotate(270deg);
	transform: rotate(270deg)
}

.fa-flip-horizontal {
	-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
	-webkit-transform: scaleX(-1);
	transform: scaleX(-1)
}

.fa-flip-vertical {
	-webkit-transform: scaleY(-1);
	transform: scaleY(-1)
}

.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical, .fa-flip-vertical {
	-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"
}

.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {
	-webkit-transform: scale(-1);
	transform: scale(-1)
}

:root .fa-flip-both, :root .fa-flip-horizontal, :root .fa-flip-vertical, :root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270 {
	-webkit-filter: none;
	filter: none
}

.fa-stack {
	display: inline-block;
	height: 2em;
	line-height: 2em;
	position: relative;
	vertical-align: middle;
	width: 2.5em
}

.fa-stack-1x, .fa-stack-2x {
	left: 0;
	position: absolute;
	text-align: center;
	width: 100%
}

.fa-stack-1x {
	line-height: inherit
}

.fa-stack-2x {
	font-size: 2em
}

.fa-inverse {
	color: #fff
}
`);

css.push(...vars.filter(([ico]) => all_icons.includes(ico)).map(([ico, code]) => `.fa-${ico}:before{content:"\\${code}"}`));

css.push(`.sr-only {
	border: 0;
	clip: rect(0, 0, 0, 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px
}

.sr-only-focusable:active, .sr-only-focusable:focus {
	clip: auto;
	height: auto;
	margin: 0;
	overflow: visible;
	position: static;
	width: auto
}

@font-face {
	font-family: "Font Awesome 5 Brands";
	font-style: normal;
	font-weight: 400;
	font-display: block;
	src: url(../webfonts/fa-brands-400.eot);
	src: url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"), url(../webfonts/fa-brands-400.woff2) format("woff2"), url(../webfonts/fa-brands-400.woff) format("woff"), url(../webfonts/fa-brands-400.ttf) format("truetype"), url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")
}

.fab {
	font-family: "Font Awesome 5 Brands";
	font-weight: 400
}

@font-face {
	font-family: "Font Awesome 5 Duotone";
	font-style: normal;
	font-weight: 900;
	font-display: block;
	src: url(../webfonts/fa-duotone-900.eot);
	src: url(../webfonts/fa-duotone-900.eot?#iefix) format("embedded-opentype"), url(../webfonts/fa-duotone-900.woff2) format("woff2"), url(../webfonts/fa-duotone-900.woff) format("woff"), url(../webfonts/fa-duotone-900.ttf) format("truetype"), url(../webfonts/fa-duotone-900.svg#fontawesome) format("svg")
}

.fad {
	position: relative;
	font-family: "Font Awesome 5 Duotone";
	font-weight: 900
}

.fad:before {
	position: absolute;
	color: var(--fa-primary-color, inherit);
	opacity: 1;
	opacity: var(--fa-primary-opacity, 1)
}

.fad:after {
	color: var(--fa-secondary-color, inherit)
}

.fa-swap-opacity .fad:before, .fad.fa-swap-opacity:before, .fad:after {
	opacity: .4;
	opacity: var(--fa-secondary-opacity, .4)
}

.fa-swap-opacity .fad:after, .fad.fa-swap-opacity:after {
	opacity: 1;
	opacity: var(--fa-primary-opacity, 1)
}

.fad.fa-inverse {
	color: #fff
}

.fad.fa-stack-1x, .fad.fa-stack-2x {
	position: absolute
}

.fad.fa-fw:before, .fad.fa-stack-1x:before, .fad.fa-stack-2x:before {
	left: 50%;
	-webkit-transform: translateX(-50%);
	transform: translateX(-50%)
}
`);

css.push(...vars.filter(([ico]) => sets.duotone.includes(ico)).map(([ico, code]) => `.fad.fa-${ico}:after{content:"\\10${code}"}`));

css.push(`@font-face {
	font-family: "Font Awesome 5 Pro";
	font-style: normal;
	font-weight: 300;
	font-display: block;
	src: url(../webfonts/fa-light-300.eot);
	src: url(../webfonts/fa-light-300.eot?#iefix) format("embedded-opentype"), url(../webfonts/fa-light-300.woff2) format("woff2"), url(../webfonts/fa-light-300.woff) format("woff"), url(../webfonts/fa-light-300.ttf) format("truetype"), url(../webfonts/fa-light-300.svg#fontawesome) format("svg")
}

.fal {
	font-weight: 300
}

@font-face {
	font-family: "Font Awesome 5 Pro";
	font-style: normal;
	font-weight: 400;
	font-display: block;
	src: url(../webfonts/fa-regular-400.eot);
	src: url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"), url(../webfonts/fa-regular-400.woff2) format("woff2"), url(../webfonts/fa-regular-400.woff) format("woff"), url(../webfonts/fa-regular-400.ttf) format("truetype"), url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")
}

.fal, .far {
	font-family: "Font Awesome 5 Pro"
}

.far {
	font-weight: 400
}

@font-face {
	font-family: "Font Awesome 5 Pro";
	font-style: normal;
	font-weight: 900;
	font-display: block;
	src: url(../webfonts/fa-solid-900.eot);
	src: url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"), url(../webfonts/fa-solid-900.woff2) format("woff2"), url(../webfonts/fa-solid-900.woff) format("woff"), url(../webfonts/fa-solid-900.ttf) format("truetype"), url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")
}

.fa, .fas {
	font-family: "Font Awesome 5 Pro";
	font-weight: 900
}
`);

const cssStr = css.map(c => c.replaceAll("\n\n", "\n")).join("\n");

Free: mixing `fab` and `fas`?

Using Font Awesome 5 Free: how do I generate a set of the following icons:
fas fa-at, fab fa-twitter, far fa-circle
These are all part of Free, but use different prefixes (fas, fab, far).
This does not seem to work:

const fontawesomeSubset = require('fontawesome-subset');
fontawesomeSubset({
      regular: ['circle'],
      solid: ['at'],
      brand: ['twitter']
   },
   'output',
   {
      package: 'free'
   }
);

How can I accomplish this?

Version 6?

It appears version 6 no longer ships with the webfont svgs - just sprite sheets. Is that fatal for this project?

Improve feedback in case pro is not configured in options

I just got started using your awesome tool and simply tried to get

import { fontawesomeSubset } from "fontawesome-subset";

fontawesomeSubset(
    ["check", "square", "caret-up"],
    "sass/webfonts"
)

working. I installed FontAwesome Pro follolwing the instructions and got the feedback

Unable to find either the Free or Pro FontAwesome files in node_modules folder. Double-check that you have your preferred fontawesome package as a dependency in `package.json` and rerun the installation.

This is a bit confusing because it seems that if options are omitted the fallback is free and the FontAwesome Free installation is not found while the Pro installation is present and correct. Adding

{ package: "pro" }

Afaik the feedback could be improved by pointing out that using pro requires the package property set. My proposal:

Unable to find either the Free or Pro FontAwesome files in node_modules folder. Double-check that you have your preferred fontawesome package as a dependency in `package.json` and rerun the installation. You need to specify `package: "pro"` in `fontawesomeSubset` arguments in case you're using FontAwesome Pro.

Or maybe that's not how it's supposed to work and there's a bug in the auto-detection of free/pro or you want to implement such a detection right away.

experienced with 4.3.0

FA v5.10.2 Duotone some icons fail to subset

Some duotone icons fail subsetting. For example:

  fontawesomeSubset({
    duotone: ['sort']  
  },
  'sass/webfonts',
  {
      package: 'pro'
  });

Results in:

/node_modules/svg2ttf/lib/svg.js:18
    if (pathElem.hasAttribute('d')) {
                 ^
TypeError: Cannot read properties of undefined (reading 'hasAttribute')
    at getGlyph (/node_modules/svg2ttf/lib/svg.js:18:18)
    at /node_modules/svg2ttf/lib/svg.js:160:17
    at /node_modules/lodash/lodash.js:4943:15
    at Function.forEach (/node_modules/lodash/lodash.js:9410:14)
    at Object.load (/node_modules/svg2ttf/lib/svg.js:159:5)
    at svg2ttf (/node_modules/svg2ttf/index.js:22:21)
    at fontawesomeSubset (node_modules/fontawesome-subset/dist/index.js:101:48)

Looking at Line 99 in index.js

const svgContentsNew = svgFile.replace(new RegExp(`(<glyph glyph-name="(${glyphsToRemove.join("|")})".*?\\/>)`, "gms"), "").replace(/>\s+</gms, "><");

svgContentsNew for this svg outputs 2 glyphs, "sort-primary" and "sort-secondary". I believe svg2ttf fails on some duotone icons because one of the glyphs have no "d" attribute. Here's a sample of the output:

<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" ><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><metadata>
Created by FontForge 20201107 at Wed Aug  4 12:24:16 2021
 By Robert Madole
Copyright (c) Font Awesome
</metadata><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><defs><font id="FontAwesome5Duotone-Solid"><font-face 
    font-family="Font Awesome 5 Duotone Solid"/><missing-glyph /><glyph glyph-name="sort-primary" unicode="&#xf0dc;"/><glyph glyph-name="sort-secondary" unicode="&#x10f0dc;" d="..." /></font></defs></svg>

Edit: Removed some icon specific stuff, I shouldn't have pasted the full icon output here due to license restrictions.

Auto Subsetting

Could you add a way to make the src directories or files instead of manually adding your icon names?

On a big project this is quite difficult to maintain currently

Duotone

How can I add doutone on webfonts generation ?

Invalid regular expression flags

**Using Gulp. I'm possibly doing something wrong.

From my Gulpfile**

const fontawesomeSubset = require('fontawesome-subset');

function fa() { fontawesomeSubset(['home'], './web/dist/webfonts/fasubset'); }
My commands

c:\ gulp fa

I get the following error:

c:\ node_modules\fontawesome-subset\dist\index.js:84
var svgContentsNew = svgFile.replace(new RegExp("(<glyph glyph-name="(" + glyphsToRemove.join("|") + ")".*?\/>)", "gms"), "").replace(/>\s+</gms, "><");
^

SyntaxError: Invalid regular expression flags
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:607:28)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at Object. (c:\gulpfile.js:12:29)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.