├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── Dockerfile ├── FiraCode.glyphs ├── LEEME.md ├── LEIAME.md ├── LICENSE ├── Makefile ├── README.md ├── README_CN.md ├── README_JA.md ├── classes ├── ClosingBracket.fea ├── Digit.fea ├── DigitTosf.fea ├── HexDigit.fea ├── OpeningBracket.fea └── Tall.fea ├── clojure ├── fira_code │ ├── calt.clj │ ├── checks.clj │ ├── classes.clj │ ├── coll.clj │ ├── features.clj │ ├── files.clj │ ├── glyphs.clj │ ├── main.clj │ ├── not_space.clj │ ├── spacers.clj │ └── time.clj └── user.clj ├── deps.edn ├── distr ├── README.txt ├── fira_code.css └── specimen.html ├── docs └── calt_performance.md ├── extras ├── arrows.png ├── arrows_es.png ├── arrows_pt.png ├── character_variants.png ├── character_variants_es.png ├── character_variants_pt.png ├── console.png ├── console_es.png ├── console_pt.png ├── download.png ├── download_es.png ├── download_pt.png ├── ligature_variants.png ├── ligature_variants_es.png ├── ligature_variants_pt.png ├── ligatures.png ├── ligatures_es.png ├── ligatures_pt.png ├── logo.svg ├── math.png ├── math_es.png ├── math_pt.png ├── progress.gif ├── progress.png ├── progress_es.gif ├── progress_pt.gif ├── samples.png ├── samples2.png ├── showcases.txt ├── sponsor.png ├── sponsor_es.png ├── sponsor_pt.png ├── texture.png ├── typographics.png ├── typographics_es.png └── typographics_pt.png ├── features ├── calt │ ├── center.fea │ ├── conj_disj.fea │ ├── cross.fea │ ├── dashes.fea │ ├── equal_arrows.fea │ ├── fi_fl.fea │ ├── greek.fea │ ├── hyphen_arrows.fea │ ├── match_case.fea │ ├── numbersigns.fea │ └── underscores.fea ├── cv01.fea ├── cv02.fea ├── cv03.fea ├── cv04.fea ├── cv05.fea ├── cv06.fea ├── cv07.fea ├── cv08.fea ├── cv09.fea ├── cv10.fea ├── cv11.fea ├── cv12.fea ├── cv13.fea ├── cv14.fea ├── cv15.fea ├── cv16.fea ├── cv17.fea ├── cv18.fea ├── cv19.fea ├── cv20.fea ├── cv21.fea ├── cv22.fea ├── cv23.fea ├── cv24.fea ├── cv25.fea ├── cv26.fea ├── cv27.fea ├── cv28.fea ├── cv29.fea ├── cv30.fea ├── cv31.fea ├── cv32.fea ├── onum.fea ├── ss01.fea ├── ss02.fea ├── ss03.fea ├── ss04.fea ├── ss05.fea ├── ss06.fea ├── ss07.fea ├── ss08.fea ├── ss09.fea ├── ss10.fea └── zero.fea ├── googlefonts-qa ├── METADATA.pb ├── README.md ├── checks │ ├── FiraCode-Light.checks.md │ └── static │ │ ├── FiraCode-Bold.checks.md │ │ ├── FiraCode-Light.checks.md │ │ ├── FiraCode-Medium.checks.md │ │ ├── FiraCode-Regular.checks.md │ │ └── FiraCode-Retina.checks.md ├── gfonts-description.html ├── notes │ ├── QA-notes.md │ ├── assets │ │ ├── 2019-03-27-13-35-37.png │ │ ├── 2019-03-27-13-38-30.png │ │ ├── 2019-03-27-13-39-56.png │ │ ├── 2019-03-27-13-40-23.png │ │ ├── 2019-03-27-13-41-12.png │ │ ├── 2019-03-27-13-46-21.png │ │ ├── 2019-03-27-13-47-09.png │ │ ├── 2019-03-27-13-47-20.png │ │ ├── 2019-03-27-13-48-03.png │ │ ├── 2019-03-27-13-50-55.png │ │ ├── 2019-03-27-13-51-17.png │ │ ├── 2019-03-27-13-52-23.png │ │ ├── 2019-03-27-13-53-17.png │ │ ├── 2019-03-28-13-39-03.png │ │ ├── 2019-03-28-13-40-08.png │ │ ├── 2019-03-28-13-41-49.png │ │ ├── 2019-03-28-13-42-04.png │ │ ├── 2019-03-28-13-44-06.png │ │ ├── 2019-03-28-13-47-00.png │ │ ├── 2019-03-28-13-48-15.png │ │ ├── 2019-03-28-13-49-19.png │ │ ├── 2019-03-28-13-50-14.png │ │ ├── 2019-03-28-13-50-54.png │ │ ├── 2019-03-28-13-51-24.png │ │ ├── 2019-03-28-13-51-49.png │ │ ├── 2019-03-28-13-53-22.png │ │ ├── 2019-03-28-13-56-45.png │ │ ├── 2019-03-28-13-58-48.png │ │ ├── 2019-03-28-13-58-57.png │ │ ├── 2019-03-28-14-01-13.png │ │ ├── 2019-03-28-14-03-53.png │ │ ├── 2019-03-28-14-04-50.png │ │ ├── 2019-03-28-14-10-07.png │ │ ├── 2019-03-28-14-11-13.png │ │ ├── 2019-03-28-14-13-00.png │ │ ├── 2019-03-28-14-13-32.png │ │ ├── 2019-03-28-14-17-52.png │ │ ├── 2019-03-28-14-18-46.png │ │ ├── 2019-03-28-14-20-11.png │ │ ├── 2019-03-28-14-21-39.png │ │ ├── 2019-03-28-14-24-45.png │ │ ├── 2019-03-28-14-25-49.png │ │ ├── 2019-03-28-14-50-52.png │ │ ├── 2019-03-28-14-51-33.png │ │ ├── 2019-03-28-14-51-48.png │ │ ├── 2019-03-28-14-52-48.png │ │ ├── 2019-03-28-14-53-56.png │ │ ├── 2019-03-28-14-54-14.png │ │ ├── 2019-03-28-14-56-15.png │ │ ├── 2019-03-28-14-56-24.png │ │ ├── 2019-03-28-14-58-50.png │ │ ├── 2019-03-28-15-00-36.png │ │ └── 2019-03-28-15-00-56.png │ └── outline-checks.md └── scripts │ ├── build.sh │ ├── get-version.py │ ├── move-check.sh │ ├── requirements.txt │ └── set-vertical-metrics.py ├── package.json └── script ├── bake_in_features.sh ├── bootstrap_linux.sh ├── bootstrap_macos.sh ├── build.sh ├── build_docker.sh ├── build_otf.sh ├── build_ttf.sh ├── build_variable.sh ├── build_woff.sh ├── build_woff2.sh ├── check ├── check_widths ├── clean.sh ├── common.py ├── everything ├── package.sh ├── progress.clj ├── release.py ├── repl.sh ├── update_glyphs.sh └── update_version.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [tonsky] 2 | patreon: tonsky 3 | custom: https://paypal.me/nikitaprokopov 4 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - '*' 5 | tags: 6 | - '[0-9]+.[0-9]+' 7 | paths: 8 | - '.github/workflows/**' 9 | - 'FiraCode.glyphs' 10 | - 'script/**' 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | container: tonsky/firacode:latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | - if: startsWith(github.ref, 'refs/tags/') 19 | run: python3 ./script/update_version.py 20 | - run: ./script/build.sh 21 | - run: echo "hash=$(git rev-parse --short $GITHUB_SHA)" >> $GITHUB_ENV 22 | - uses: actions/upload-artifact@v3 23 | with: 24 | name: Fira_Code_${{ env.hash }} 25 | path: distr 26 | - if: startsWith(github.ref, 'refs/tags/') 27 | run: python3 ./script/release.py 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | target 3 | clojure/*.edn 4 | .cpcache 5 | .repl-port 6 | master_ufo 7 | instance_ufo 8 | venv 9 | .DS_Store 10 | *.numbers 11 | 12 | distr/*/ 13 | 14 | *.glyphs 15 | !FiraCode.glyphs 16 | 17 | .idea 18 | .fleet 19 | *.iml 20 | *.glyphspackage -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of project authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS.txt file. 3 | # See the latter for an explanation. 4 | # 5 | # Names should be added to this file as: 6 | # Name or Organization 7 | 8 | Mozilla Foundation (https://www.mozilla.org/en-US/contact/) 9 | Telefonica S.A. 10 | Nikita Prokopov (niki@tonsky.me) github.com/tonsky 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3 2 | 3 | WORKDIR /opt 4 | 5 | RUN pip install --upgrade Pillow==5.4.1 idna==2.8 requests==2.21.0 urllib3==1.24.1 pycairo==1.20.1 gftools==0.7.4 fontmake==2.4.0 fontbakery==0.8.0 6 | RUN apt-get update && \ 7 | apt-get install -y ttfautohint && \ 8 | apt-get install -y woff2 && \ 9 | apt-get install -y sfnt2woff-zopfli -------------------------------------------------------------------------------- /LEEME.md: -------------------------------------------------------------------------------- 1 | ## Fira Code: la fuente monoespaciada con ligaduras gratuita para programación 2 | 3 | ![Fira Code](./extras/logo.svg) 4 | 5 | Leer en [English](./README.md) | [简体中文](./README_CN.md) | [日本語](./README_JA.md) | [Português brasileiro](./LEIAME.md) 6 | 7 | ### El problema 8 | 9 | Los programadores usamos muchos símbolos, frecuentemente codificados con varios caracteres. Para el cerebro humano, sucesiones como `->`, `<=` o `:=` son unidades lógicas individuales, incluso si requieren dos o más caracteres en pantalla. Nuestros ojos utilizan una cantidad no nula de energía para leer, analizar y unir caracteres mútiples en una sola unidad lógica. Idealmente, todos los lenguajes de programación deberían estar diseñados para representar los operadores con símbolos Unicode; pero ese no es el caso aún. 10 | 11 | ### La solución 12 | 13 | Fira Code es una fuente monoespaciada gratuita que contiene ligaduras para combinaciones multicaracter comunes en programación. Esta es simplemente una característica del renderizado de la fuente: el código subyacente permanece compatible con el estándar ASCII. Esto ayuda a leer y comprender más rápido el código. Para algunas sucesiones comunes, como `..` o `//`, las ligaduras nos permiten hacer correcciones en el espaciado. 14 | 15 | ### Descarga e instalación 16 | 17 | Fira_Code_v6.2.zip - Diciembre 6 de 2021 - 2.5 MB 18 | 19 | Recursos adicionales (en inglés): 20 | 21 | - [Cómo instalar](https://github.com/tonsky/FiraCode/wiki) 22 | - [Resolución de problemas](https://github.com/tonsky/FiraCode/wiki#troubleshooting) 23 | - [Noticias e información](https://twitter.com/FiraCode) 24 | 25 | ### Contribuyendo 26 | 27 | Contribuye 28 | 29 | Fira Code es un proyecto personal desarrollado en mi tiempo libre, sin financiamiento y con una enorme [lista de solicitudes](https://github.com/tonsky/FiraCode/issues). Si el resultado es de tu agrado, por favor considera apoyar a su desarrollo por medio de [GitHub Sponsors](https://github.com/sponsors/tonsky) o [Patreon](https://patreon.com/tonsky). ¡Cualquier ayuda cuenta! 30 | 31 | ### ¿Qué ofrece? 32 | 33 | Izquierda: ligaduras renderizadas en Fira Code. Derecha: las mismas secuencias de caracteres sin ligaduras. 34 | 35 | 36 | 37 | Fira Code viene con una gran variedad de flechas. Mejor aun, ¡estas pueden hacerse tan largas como se desee y se pueden combinar los fragmentos incial/medio/final de la forma que se quiera! 38 | 39 | 40 | 41 | Fira Code no solo se trata de las ligaduras. Algunos ajustes se han hecho a la puntuación y a pares de letras frecuentes. 42 | 43 | 44 | 45 | Fira Code viene con algunas variantes de caracteres, de manera que cada uno puede escoger lo que mejor le convenga. [Cómo activar (en inglés)](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) 46 | 47 | 48 | 49 | Algunas ligaduras pueden alterarse o activarse usando conjuntos estilísticos/variantes de caracteres: 50 | 51 | 52 | 53 | Siendo una fuente para programación, Fira Code tiene un soporte fantástico para dibujos ASCII/de cajas, powerline y otras formas de interfaz de usuario para terminal: 54 | 55 | 56 | 57 | Fira Code es la primera fuente para programación en ofrecer glifos dedicados al dibujo de barras de progreso: 58 | 59 | 60 | 61 | En acción: 62 | 63 | 64 | 65 | Esperamos que más fuentes adopten esta convención y definan sus propias versiones. 66 | 67 | La covertura del estándar Unicode hace de Fira Code una gran elección para la escritura matemática: 68 | 69 | 70 | 71 | ### ¿Cómo luce? 72 | 73 | 74 | 75 | 76 | ### Lista de compatibilidad con editores 77 | 78 | | Funciona | No funciona | 79 | |----------|-------------| 80 | | **Abricotine** | **Arduino IDE** | 81 | | **Android Studio** (2.3+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **Adobe Dreamweaver** | 82 | | **Anjuta** (excepto con EOF) | **Delphi IDE** | 83 | | **AppCode** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **Emacs** por sí solo ([solución alternativa](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | 84 | | **Atom** 1.1 o más nuevo ([instrucciones](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Godot** ([reporte](https://github.com/godotengine/godot/issues/9961)) | 85 | | **BBEdit** (14.6+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **IDLE** | 86 | | **Brackets** (con [este plugin](https://github.com/polo2ro/firacode-in-brackets)) | **KDevelop 4** | 87 | | **Chocolat** | **Monkey Studio IDE** | 88 | | **CLion** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **UltraEdit** | 89 | | **Cloud9** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | 90 | | **Coda 2** | 91 | | **CodeLite** | 92 | | **CodeRunner** | 93 | | **CotEditor** | 94 | | **Eclipse** | 95 | | **elementary Code** | 96 | | **Geany** (1.37+) | 97 | | **gEdit / Pluma** | 98 | | **GNOME Builder** | 99 | | **GoormIDE** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | 100 | | **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | 101 | | **IntelliJ IDEA** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | 102 | | **Kate, KWrite** | 103 | | **KDevelop 5+** | 104 | | **Komodo** | 105 | | **Leafpad** | 106 | | **LibreOffice** | 107 | | **LightTable** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | 108 | | **LINQPad** | 109 | | **MacVim** 7.4 o más nuevo ([instrucciones](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | 110 | | **Mancy** | 111 | | **MATLAB** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | 112 | | **Meld** | 113 | | **Mousepad** | 114 | | **NeoVim-gtk** | 115 | | **NetBeans** | 116 | | **Notepad** (Windows) | 117 | | **Notepad++** (con una [solución alternativa](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | 118 | | **Notepad3** ([instrucciones](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| 119 | | **Nova** | 120 | | **PhpStorm** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | 121 | | **PyCharm** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | 122 | | **QOwnNotes** (21.16.6+) | 123 | | **QtCreator** | 124 | | **Rider** | 125 | | **RStudio** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | 126 | | **RubyMine** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | 127 | | **Scratch** | 128 | | **Scribus** (1.5.3+) | 129 | | **SublimeText** (3146+) | 130 | | **Spyder IDE** (solamente con Qt5) | 131 | | **SuperCollider 3** | 132 | | **TeXShop** | 133 | | **TextAdept** (Linux, macOS) | 134 | | **TextEdit** | 135 | | **TextMate 2** | 136 | | **VimR** ([instrucciones](https://github.com/qvacua/vimr/wiki#ligatures)) | 137 | | **Visual Studio** (2015+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | 138 | | **Visual Studio Code** ([instrucciones](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | 139 | | **WebStorm** (2016.2+, [instrucciones](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | 140 | | **Xamarin Studio/Monodevelop** | 141 | | **Xcode** (8.0+, alternativamente con [este plugin](https://github.com/robertvojta/LigatureXcodePlugin)) | 142 | | **Xi** | 143 | | Probablemente: **Smultron, Vico** | En duda: **Code::Blocks IDE** | 144 | 145 | ### Lista de compatibilidad con terminales 146 | 147 | | Plataforma | Funciona | No funciona | 148 | |----------------|----------|-------------| 149 | | macOS | Hyper (ver [#3607](https://github.com/vercel/hyper/issues/3607))
iTerm 2
Kitty
Terminal.app
ZOC | Alacritty | 150 | | Windows | Hyper (ver [#3607](https://github.com/vercel/hyper/issues/3607))
Mintty
Token2Shell
Windows Terminal | Alacritty
Cmder
ConEmu
PuTTY
Windows Console
ZOC | 151 | | Linux | Hyper (ver [#3607](https://github.com/vercel/hyper/issues/3607))
Kitty
Konsole
QTerminal
Termux
st ([parche](https://st.suckless.org/patches/ligatures/)) | Alacritty
GNOME Terminal
Terminales basadas en libvte ([reporte](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)): mate-terminal
rxvt
terminology
xterm 152 | | ChromeOS | crosh ([instrucciones](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | | 153 | 154 | ### Soporte en el navegador web 155 | 156 | ```html 157 | 158 | 159 | ``` 160 | 161 | ```css 162 | /* CSS */ 163 | @import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); 164 | ``` 165 | 166 | ```css 167 | /* Especificar en el CSS */ 168 | code { font-family: 'Fira Code', monospace; } 169 | 170 | @supports (font-variation-settings: normal) { 171 | code { font-family: 'Fira Code VF', monospace; } 172 | } 173 | ``` 174 | 175 | - IE 10+, Edge Legacy: activar con `font-feature-settings: "calt";` 176 | - Firefox 177 | - Safari 178 | - Navegadores basados en Chromium (Chrome, Opera) 179 | - ACE 180 | - CodeMirror (activar con `font-variant-ligatures: contextual;`) 181 | 182 | ### Proyectos que usan Fira Code 183 | 184 | - [CodePen](https://codepen.io/) 185 | - [Blink Shell](http://www.blink.sh/) 186 | - [Klipse](http://app.klipse.tech/) 187 | - [IlyaBirman.net](http://ilyabirman.net/) 188 | - [EvilMartians.com](https://evilmartians.com/) 189 | - [Web Maker](https://webmakerapp.com/) 190 | - [FromScratch](https://fromscratch.rocks/) 191 | - [PEP20.org](https://pep20.org/) 192 | 193 | ### Alternativas 194 | 195 | Fuentes monoespaciadas con ligaduras gratuitas: 196 | 197 | - [Hasklig](https://github.com/i-tu/Hasklig) 198 | - [Monoid](http://larsenwork.com/monoid/) 199 | - [Fixedsys Excelsior](https://github.com/kika/fixedsys) 200 | - [Iosevka](https://be5invis.github.io/Iosevka/) 201 | - [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) 202 | - [Victor Mono](https://rubjo.github.io/victor-mono/) 203 | - [Cascadia Code](https://github.com/microsoft/cascadia-code) 204 | - [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) 205 | 206 | Fuentes monoespaciadas con ligaduras no gratuitas: 207 | 208 | - [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) 209 | - [Mono Lisa](https://www.monolisa.dev/) 210 | 211 | ### Compilando Fira Code localmente 212 | 213 | En caso que se quiera modificar el código en FiraCode.glyphs y compilar archivos OTF/TTF/WOFF propios, estas son las instrucciones que uso en macOS: 214 | 215 | ```bash 216 | # instalar las herramientas requeridas para la compilación 217 | ./script/bootstrap_macos.sh 218 | 219 | # compilar los archivos de la fuente 220 | ./script/build.sh 221 | 222 | # instalar los OTFs en ~/Library/Fonts 223 | cp distr/otf/*.otf ~/Library/Fonts 224 | ``` 225 | 226 | Alternativamnete, se puede compilar Fira Code usando Docker: 227 | 228 | ```bash 229 | # instalar las dependencias en un contenedor y compilar los archivos de la fuente 230 | make 231 | 232 | # comprimir los archivos de la fuente en dist/ a un zip 233 | make package 234 | ``` 235 | 236 | ### Créditos 237 | 238 | - Autor: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) 239 | - Basado en: [Fira Mono](https://github.com/mozilla/Fira) 240 | - Inspirado por: [Hasklig](https://github.com/i-tu/Hasklig) 241 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | build: 4 | docker run --rm -v ${PWD}:/opt tonsky/firacode:latest ./script/build.sh 5 | 6 | package: 7 | ./script/package.sh 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Fira Code: free monospaced font with programming ligatures 2 | 3 | ![Fira Code](./extras/logo.svg) 4 | 5 | Read in [Español](./LEEME.md) | [简体中文](./README_CN.md) | [日本語](./README_JA.md) | [Português brasileiro](./LEIAME.md) 6 | 7 | ### Problem 8 | 9 | Programmers use a lot of symbols, often encoded with several characters. For the human brain, sequences like `->`, `<=`, or `:=` are single logical tokens, even if they take two or three characters on the screen. Your eye spends a non-zero amount of energy to scan, parse and join multiple characters into a single logical one. Ideally, all programming languages should be designed with full-fledged Unicode symbols for operators, but that’s not the case yet. 10 | 11 | ### Solution 12 | 13 | Fira Code is a free monospaced font containing ligatures for common programming multi-character combinations. This is just a font rendering feature: underlying code remains ASCII-compatible. This helps to read and understand code faster. For some frequent sequences like `..` or `//`, ligatures allow us to correct spacing. 14 | 15 | ### Download & Install 16 | 17 | Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB 18 | 19 | Then: 20 | 21 | - [How to Install](https://github.com/tonsky/FiraCode/wiki) 22 | - [Troubleshooting](https://github.com/tonsky/FiraCode/wiki#troubleshooting) 23 | - [News & Updates](https://twitter.com/FiraCode) 24 | 25 | ### Sponsors 26 | 27 | Fira Code is a personal, free-time project with no funding and a huge [feature request backlog](https://github.com/tonsky/FiraCode/issues). If you love it, consider supporting its development via [GitHub Sponsors](https://github.com/sponsors/tonsky) or [Patreon](https://patreon.com/tonsky). Any help counts! 28 | 29 | ### What’s in the box? 30 | 31 | Left: ligatures as rendered in Fira Code. Right: same character sequences without ligatures. 32 | 33 | 34 | 35 | Fira Code comes with a huge variety of arrows. Even better: you can make them as long as you like and combine start/middle/end fragments however you want! 36 | 37 | 38 | 39 | Fira Code is not only about ligatures. Some fine-tuning is done for punctuation and frequent letter pairs. 40 | 41 | 42 | 43 | Fira Code comes with a few different character variants (`cv01`, `cv02`, etc), stylistic sets (`ss01`, `ss02`, etc), and other font features (`zero`, `onum`, `calt`, etc), so that everyone can choose what’s best for them. [How to enable](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) 44 | 45 | 46 | 47 | Some ligatures can be altered or enabled using stylistic sets/character variants: 48 | 49 | 50 | 51 | Being a programming font, Fira Code has fantastic support for ASCII/box drawing, powerline, and other forms of console UIs: 52 | 53 | 54 | 55 | Fira Code is the first programming font to offer dedicated glyphs to render progress bars: 56 | 57 | 58 | 59 | In action: 60 | 61 | 62 | 63 | We hope more programming fonts will adopt this convention and ship their own versions. 64 | 65 | Unicode coverage makes Fira Code a great choice for mathematical writing: 66 | 67 | 68 | 69 | ### How does it look? 70 | 71 | 72 | 73 | 74 | ### Editor compatibility list 75 | 76 | | Works | Doesn’t work | 77 | |-------|----------------| 78 | | **Arduino IDE** (2.0+,same instructions as [vscode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | **Adobe Dreamweaver** | 79 | | **Abricotine** | **Delphi IDE** | 80 | | **Android Studio** (2.3+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([workaround](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | 81 | | **Anjuta** (unless at the EOF) | **IDLE** | 82 | | **AppCode** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **KDevelop 4** | 83 | | **Atom** 1.1 or newer ([instructions](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Monkey Studio IDE** | 84 | | **BBEdit** (14.6+ [instructions](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **UltraEdit** (Windows) | 85 | | **Brackets** (with [this plugin](https://github.com/polo2ro/firacode-in-brackets)) | 86 | | **Chocolat** | 87 | | **CLion** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 88 | | **Cloud9** ([instructions](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | 89 | | **Coda 2** | 90 | | **CodeLite** | 91 | | **CodeRunner** | 92 | | **Comma** (Under: Preferences > Editor > Font) | 93 | | **CotEditor** | 94 | | **Eclipse** | 95 | | **EditPad** | 96 | | **elementary Code** | 97 | | **Geany** (1.37+) | 98 | | **gEdit / Pluma** | 99 | | **GNOME Builder** | 100 | | **Godot** | 101 | | **GoormIDE** ([instructions](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | 102 | | **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | 103 | | **IntelliJ IDEA** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 104 | | **Kate, KWrite** | 105 | | **KDevelop 5+** | 106 | | **Komodo** | 107 | | **Leafpad** | 108 | | **LibreOffice** | 109 | | **LightTable** ([instructions](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | 110 | | **LINQPad** | 111 | | **MacVim** 7.4 or newer ([instructions](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | 112 | | **Mancy** | 113 | | **MATLAB** ([instructions](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | 114 | | **Meld** | 115 | | **Mousepad** | 116 | | **NeoVim-gtk** | 117 | | **NetBeans** | 118 | | **Notepad** (Windows) | 119 | | **Notepad++** ([instructions](https://github.com/tonsky/FiraCode/issues/1555)) | 120 | | **Notepad3** ([instructions](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| 121 | | **Nova** | 122 | | **PhpStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 123 | | **PyCharm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 124 | | **QOwnNotes** (21.16.6+) | 125 | | **QtCreator** | 126 | | **Rider** | 127 | | **RStudio** ([instructions](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | 128 | | **RubyMine** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 129 | | **Scratch** | 130 | | **Scribus** (1.5.3+) | 131 | | **SublimeText** (3146+) | 132 | | **Spyder IDE** (only with Qt5) | 133 | | **SuperCollider 3** | 134 | | **TeXShop**| 135 | | **TextAdept** (Linux, macOS) | 136 | | **TextEdit** | 137 | | **TextMate 2** | 138 | | **UltraEdit (UEX)** (Linux) | 139 | | **VimR** ([instructions](https://github.com/qvacua/vimr/wiki#ligatures)) | 140 | | **Visual Studio** (2015+, [instructions](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | 141 | | **Visual Studio Code** ([instructions](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | 142 | | **WebStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 143 | | **Xamarin Studio/Monodevelop** | 144 | | **Xcode** (8.0+, otherwise [with plugin](https://github.com/robertvojta/LigatureXcodePlugin)) | 145 | | **Xi** | 146 | | Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | 147 | | **Zed** ([instructions](https://zed.dev/docs/configuring-zed#buffer-font-family)) | | 148 | 149 | ### Terminal compatibility list 150 | 151 | | Works | Doesn’t work | 152 | |-------|--------------| 153 | | crosh ([instructions](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | 154 | | Ghostty | Asbru Connection Manager | 155 | | Hyper (see [#3607](https://github.com/vercel/hyper/issues/3607)) | Cmder | 156 | | iTerm 2 | ConEmu | 157 | | Kitty | GNOME Terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/192)) | 158 | | Konsole | gtkterm ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 159 | | Mintty | guake ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 160 | | QTerminal | LXTerminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 161 | | st ([patch](https://st.suckless.org/patches/ligatures/)) | mate-terminal | 162 | | Tabby | PuTTY | 163 | | Terminal.app | rxvt | 164 | | Termux | sakura ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 165 | | Token2Shell | SecureCRT 166 | | Wez’s terminal | Terminator ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 167 | | Windows Terminal | terminology | 168 | | ZOC (macOS) | Tilix | 169 | | | Windows Console | 170 | | | xfce4-terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 171 | | | xterm | 172 | | | ZOC (Windows) | 173 | 174 | ### Browser support 175 | 176 | ```html 177 | 178 | 179 | ``` 180 | 181 | ```css 182 | /* CSS */ 183 | @import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); 184 | ``` 185 | 186 | ```css 187 | /* Specify in CSS */ 188 | code { font-family: 'Fira Code', monospace; } 189 | 190 | @supports (font-variation-settings: normal) { 191 | code { font-family: 'Fira Code VF', monospace; } 192 | } 193 | ``` 194 | 195 | - IE 10+, Edge Legacy: enable with `font-feature-settings: "calt";` 196 | - Firefox 197 | - Safari 198 | - Chromium-based browsers (Chrome, Opera) 199 | - ACE 200 | - CodeMirror (enable with `font-variant-ligatures: contextual;`) 201 | 202 | ### Projects using Fira Code 203 | 204 | - [CodePen](https://codepen.io/) 205 | - [Blink Shell](http://www.blink.sh/) 206 | - [Klipse](http://app.klipse.tech/) 207 | - [IlyaBirman.net](http://ilyabirman.net/) 208 | - [EvilMartians.com](https://evilmartians.com/) 209 | - [Web Maker](https://webmakerapp.com/) 210 | - [FromScratch](https://fromscratch.rocks/) 211 | - [PEP20.org](https://pep20.org/) 212 | 213 | ### Alternatives 214 | 215 | Free monospaced fonts with ligatures: 216 | 217 | - [Hasklig](https://github.com/i-tu/Hasklig) 218 | - [Monoid](http://larsenwork.com/monoid/) 219 | - [Fixedsys Excelsior](https://github.com/kika/fixedsys) 220 | - [Iosevka](https://be5invis.github.io/Iosevka/) 221 | - [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) 222 | - [Victor Mono](https://rubjo.github.io/victor-mono/) 223 | - [Cascadia Code](https://github.com/microsoft/cascadia-code) 224 | - [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) 225 | 226 | Paid monospaced fonts with ligatures: 227 | 228 | - [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) 229 | - [Mono Lisa](https://www.monolisa.dev/) 230 | 231 | ### Building Fira Code locally 232 | 233 | In case you want to alter FiraCode.glyphs and build OTF/TTF/WOFF files yourself, this is the setup I use on macOS: 234 | 235 | ```bash 236 | # install all required build tools 237 | ./script/bootstrap_macos.sh 238 | 239 | # build the font files 240 | ./script/build.sh 241 | 242 | # install OTFs to ~/Library/Fonts 243 | cp distr/otf/*.otf ~/Library/Fonts 244 | ``` 245 | 246 | Alternatively, you can build Fira Code using Docker: 247 | 248 | ```bash 249 | # install dependencies in a container and build the font files 250 | make 251 | 252 | # package the font files from dist/ into a zip 253 | make package 254 | ``` 255 | 256 | If you want to *permanently enable* certain style sets or character variations, maybe because your editor of choice does not allow you to toggle these individually, you can provide the desired features as a comma separated list to the build script via the `-f / --features` flag.
Default: none. 257 | 258 | To separate different versions of your font you can specify the desired font family name with the `-n / --family-name` flag. The special value 'features' will append a sorted, space separated list of enabled features to the default family name.
Default: "Fira Code" 259 | 260 | You can also limit the font weights that will be created with the `-w / --weights` option.
Default: "Light,Regular,Retina,Medium,SemiBold,Bold" 261 | 262 | ```bash 263 | # locally in your shell 264 | ./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" 265 | 266 | # or via a docker container (creates the family name 'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero') 267 | docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" 268 | 269 | # in Git Bash from Git for Windows, or any other MSYS2 based shell, you might need to disable path conversion 270 | MSYS2_ARG_CONV_EXCL="*" docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "ss02,ss03,ss04,ss05,ss06,ss07" 271 | ``` 272 | 273 | ### Credits 274 | 275 | - Author: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) 276 | - Based on: [Fira Mono](https://github.com/mozilla/Fira) 277 | - Inspired by: [Hasklig](https://github.com/i-tu/Hasklig) 278 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | ## Fira Code: 免费的编程连字等宽字体 2 | 3 | ![Fira Code](./extras/logo.svg) 4 | 5 | ### 问题 6 | 7 | 开发者们使用的多标记,通常都是用几个字符编码。对于人的大脑来说,像`->`、`<=`或`:=`这样的序列是单一的逻辑标记,即使它们在屏幕上显示两到三个字符。您的眼睛并非无消耗的来扫描、解析并将多个字符连接到一个逻辑字符中。理想情况下,所有编程语言都应该为操作符设计成熟的Unicode符号,但现在还不是这样。 8 | 9 | ### 解决方案 10 | 11 | Fira Code是一种免费的等宽字体,包含常用的编程语言中多种字符组合的连字。这只是一个字体呈现功能,底层代码仍然与ASCII兼容。这有助于更快地阅读和理解代码。对于一些常见的序列,如`..`或`//`,连字允许我们纠正间距。 12 | 13 | ### 下载和安装 14 | 15 | Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB 16 | 17 | 下一步: 18 | 19 | - [如何安装](https://github.com/tonsky/FiraCode/wiki) 20 | - [疑难解答](https://github.com/tonsky/FiraCode/wiki#troubleshooting) 21 | - [相关新闻](https://twitter.com/FiraCode) 22 | 23 | ### 赞助商 24 | 25 | Sponsor 26 | 27 | Fira Code 是个人的空闲时间进行的项目,缺乏资金但有大量的 [功能请求积压](https://github.com/tonsky/FiraCode/issues)。如果你也热爱这个项目, 请考虑通过 [GitHub Sponsors](https://github.com/sponsors/tonsky) 或 [Patreon](https://patreon.com/tonsky) 来支持它的发展。任何帮助都很重要! 28 | 29 | 非常感谢: 30 | 31 | 32 | 43 |
33 | 34 |
35 | WorkOS 36 |
37 | Your app, enterprise-ready. 38 |
39 | Start selling to enterprise customers with just a few lines of code. Add Single Sign-On (and more) in minutes instead of months. 40 |
41 |
42 |
44 | 45 | ### 字体里都有哪些特征? 46 | 47 | 左侧:Fira Code中呈现的连字。右侧:没有连字的相同字符序列。 48 | 49 | 50 | 51 | Fira Code 带有种类繁多的箭头。更棒的是:您可以随心所欲地制作它们,并根据需要组合开始/中间/结束片段! 52 | 53 | 54 | 55 | Fira Code 不仅与连字有关,还对标点符号和频繁的字母对进行了一些微调。 56 | 57 | 58 | 59 | Fira Code 带有各种各样的箭头,更棒的是,您可以随心所欲地制作它们,并且可以任意组合开始/中间/结束片段![如何启用](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) 60 | 61 | 62 | 63 | 可以使用样式集/字符变体更改或启用某些连字: 64 | 65 | 66 | 67 | 作为一种编程字体,Fira Code 对 ASCII/框绘图、powerline和其他形式的控制台 UI 具有出色的支持: 68 | 69 | 70 | 71 | Fira Code 是第一个提供专用字形来渲染进度条的编程字体: 72 | 73 | 74 | 75 | 在运行中: 76 | 77 | 78 | 79 | 我们希望更多的编程字体能够采用这个约定并发布自己的版本。 80 | 81 | Unicode 覆盖使 Fira Code 成为数学写作的绝佳选择: 82 | 83 | 84 | 85 | ### 它看起来怎样? 86 | 87 | 88 | 89 | 90 | ### 编辑器兼容性列表 91 | 92 | | 支持 | 不支持 | 93 | |-------|----------------| 94 | | **Abricotine** | **Arduino IDE** | 95 | | **Android Studio** (2.3+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **Adobe Dreamweaver** | 96 | | **Anjuta** (除非在 EOF) | **Delphi IDE** | 97 | | **AppCode** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([解决方法](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | **IDLE** | 98 | | **Atom** 1.1 或更新版本 ([说明](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **KDevelop 4** | 99 | | **BBEdit** (14.6+, [说明](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **Monkey Studio IDE** | 100 | | **Brackets** (使用 [此插件](https://github.com/polo2ro/firacode-in-brackets)) | 101 | | **Chocolat** | **UltraEdit** | 102 | | **CLion** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 103 | | **Cloud9** ([说明](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | 104 | | **Coda 2** | 105 | | **CodeLite** | 106 | | **CodeRunner** | 107 | | **Comma** (在 首选项 > 编辑器 > 字体 中) | 108 | | **CotEditor** | 109 | | **Eclipse** | 110 | | **elementary Code** | 111 | | **Geany** (1.37+) | 112 | | **gEdit / Pluma** | 113 | | **GNOME Builder** | 114 | | **Godot** | 115 | | **GoormIDE** ([说明](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | 116 | | **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | 117 | | **IntelliJ IDEA** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 118 | | **Kate, KWrite** | 119 | | **KDevelop 5+** | 120 | | **Komodo** | 121 | | **Leafpad** | 122 | | **LibreOffice** | 123 | | **LightTable** ([说明](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | 124 | | **LINQPad** | 125 | | **MacVim** 7.4 或更新版本 ([说明](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | 126 | | **Mancy** | 127 | | **MATLAB** ([说明](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | 128 | | **Meld** | 129 | | **Mousepad** | 130 | | **NeoVim-gtk** | 131 | | **NetBeans** | 132 | | **Notepad** (Windows) | 133 | | **Notepad++** ([解决方法](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | 134 | | **Notepad3** ([说明](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| 135 | | **Nova** | 136 | | **PhpStorm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 137 | | **PyCharm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 138 | | **QOwnNotes** (21.16.6+) | 139 | | **QtCreator** | 140 | | **Rider** | 141 | | **RStudio** ([说明](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | 142 | | **RubyMine** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 143 | | **Scratch** | 144 | | **Scribus** (1.5.3+) | 145 | | **SublimeText** (3146+) | 146 | | **Spyder IDE** (仅适用于 Qt5) | 147 | | **SuperCollider 3** | 148 | | **TeXShop**| 149 | | **TextAdept** (Linux, macOS) | 150 | | **TextEdit** | 151 | | **TextMate 2** | 152 | | **VimR** ([说明](https://github.com/qvacua/vimr/wiki#ligatures)) | 153 | | **Visual Studio** (2015+, [说明](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | 154 | | **Visual Studio Code** ([说明](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | 155 | | **WebStorm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 156 | | **Xamarin Studio/Monodevelop** | 157 | | **Xcode** (8.0+, 否则 [使用插件](https://github.com/robertvojta/LigatureXcodePlugin)) | 158 | | **Xi** | 159 | | Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | 160 | 161 | ### 终端兼容性列表 162 | 163 | | 支持 | 不支持 | 164 | |-------|--------------| 165 | | crosh ([说明](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | 166 | | Hyper (参见 [#3607](https://github.com/vercel/hyper/issues/3607)) | Cmder | 167 | | iTerm 2 | ConEmu | 168 | | Kitty | GNOME Terminal | 169 | | Konsole | gtkterm ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 170 | | Mintty | guake ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 171 | | QTerminal | LXTerminal ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 172 | | st ([补丁](https://st.suckless.org/patches/ligatures/)) | mate-terminal | 173 | | Terminal.app | PuTTY | 174 | | Termux | rxvt | 175 | | Token2Shell | sakura ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 176 | | Wez’s terminal | Terminator ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 177 | | Windows Terminal | terminology | 178 | | ZOC (macOS) | Windows Console | 179 | | | xfce4-terminal ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 180 | | | xterm | 181 | | | ZOC (Windows) | 182 | 183 | ### 浏览器支持 184 | 185 | ```html 186 | 187 | 188 | ``` 189 | 190 | ```css 191 | /* CSS */ 192 | @import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); 193 | ``` 194 | 195 | ```css 196 | /* Specify in CSS */ 197 | code { font-family: 'Fira Code', monospace; } 198 | 199 | @supports (font-variation-settings: normal) { 200 | code { font-family: 'Fira Code VF', monospace; } 201 | } 202 | ``` 203 | 204 | - IE 10+, Edge Legacy: 启用 `font-feature-settings: "calt";` 205 | - Firefox 206 | - Safari 207 | - Chromium-based browsers (Chrome, Opera) 208 | - ACE 209 | - CodeMirror (enable with `font-variant-ligatures: contextual;`) 210 | 211 | ### 使用 Fira Code的项目 212 | 213 | - [CodePen](https://codepen.io/) 214 | - [Blink Shell](http://www.blink.sh/) 215 | - [Klipse](http://app.klipse.tech/) 216 | - [IlyaBirman.net](http://ilyabirman.net/) 217 | - [EvilMartians.com](https://evilmartians.com/) 218 | - [Web Maker](https://webmakerapp.com/) 219 | - [FromScratch](https://fromscratch.rocks/) 220 | - [PEP20.org](https://pep20.org/) 221 | 222 | ### 备选方案 223 | 224 | 带连字的免费等宽字体: 225 | 226 | - [Hasklig](https://github.com/i-tu/Hasklig) 227 | - [Monoid](http://larsenwork.com/monoid/) 228 | - [Fixedsys Excelsior](https://github.com/kika/fixedsys) 229 | - [Iosevka](https://be5invis.github.io/Iosevka/) 230 | - [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) 231 | - [Victor Mono](https://rubjo.github.io/victor-mono/) 232 | - [Cascadia Code](https://github.com/microsoft/cascadia-code) 233 | - [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) 234 | 235 | 带连字的付费等宽字体: 236 | 237 | - [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) 238 | - [Mono Lisa](https://www.monolisa.dev/) 239 | 240 | ### 在本地构建 Fira Code 241 | 242 | 如果您想更改 FiraCode.glyphs 并自己构建 OTF / TTF / WOFF 文件,这是我在 macOS 上使用的设置: 243 | 244 | ```bash 245 | # 安装所有编译需要的工具 246 | ./script/bootstrap_macos.sh 247 | 248 | # 编译字体文件 249 | ./script/build.sh 250 | 251 | # 将otf文件安装到 ~/Library/Fonts 252 | cp distr/otf/*.otf ~/Library/Fonts 253 | ``` 254 | 255 | 或者,您可以使用 Docker 构建 Fira Code: 256 | 257 | ```bash 258 | # install dependencies in a container and build the font files 259 | make 260 | 261 | # package the font files from dist/ into a zip 262 | make package 263 | ``` 264 | 265 | 如果你想要*永久开启*某个特定的文体集或者字符变种,但你的编辑器有可能不允许你单独开启它们,你可以将你想要的功能作为一个用逗号分隔的列表,通过 `-f / --features` 标志来加入到编译脚本中。
默认:无。 266 | 267 | 要分隔不同的字体版本的话,你可以用 `-n / --family-name` 标志来指定你所需的字体系列名称。特殊值 'features' 将在默认的系列名称后面添加一个有序的、空格分隔的列表,列表内为已经启用的功能。
默认:"Fira Code" 268 | 269 | 你也可以用 `-w / --weights` 选项来限制将要被编译的字体的重量。
默认:"Light,Regular,Retina,Medium,SemiBold,Bold" 270 | 271 | ```bash 272 | # 在你本地的shell中 273 | ./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" 274 | 275 | # 或者通过一个docker容器 (创建系列名为:'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero') 276 | docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" 277 | ``` 278 | 279 | ### 制作人员 280 | 281 | - 作者: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) 282 | - 基于此项目: [Fira Mono](https://github.com/mozilla/Fira) 283 | - 灵感来源: [Hasklig](https://github.com/i-tu/Hasklig) 284 | - 翻译:墨抒颖[@moshuying](https://github.com/moshuying) 285 | -------------------------------------------------------------------------------- /README_JA.md: -------------------------------------------------------------------------------- 1 | ## Fira Code: プログラミング合字のフリー等幅フォント 2 | 3 | ![Fira Code](./extras/logo.svg) 4 | 5 | [English](./README.md) | [Español](./LEEME.md) | [简体中文](./README_CN.md) で読む | [Português brasileiro](./LEIAME.md) 6 | 7 | ### 問題点 8 | 9 | プログラマは多くの記号を使用し、しばしば数文字で符号化されます。人間の脳にとって`->`、`<=`、`:=`といったシーケンスは、たとえ画面上で 2 文字や 3 文字になったとしても、単一の論理トークンである。あなたの目は、複数の文字をスキャンし、解析し、1 つの論理的なものに結合するために、ゼロではない量のエネルギーを費やしているのです。理想を言えば、すべてのプログラミング言語が演算子のための本格的なユニコード記号を備えて設計されるべきですが、まだそうではありません。 10 | 11 | ### 解決法 12 | 13 | Fira Code は、一般的なプログラミングの複数文字の組み合わせのための合字を含む無料の等幅フォントです。これは単にフォントのレンダリング機能であり、基礎となるコードは ASCII 互換のままです。これによりコードをより速く読み、理解することができます。`...` や `//` のような頻度の高い文字列は、合字によって間隔を修正することができます。 14 | 15 | ### ダウンロードとインストール 16 | 17 | Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB 18 | 19 | 次は: 20 | 21 | - [インストール方法](https://github.com/tonsky/FiraCode/wiki) 22 | - [トラブルシューティング](https://github.com/tonsky/FiraCode/wiki#troubleshooting) 23 | - [ニュースとアップデート](https://twitter.com/FiraCode) 24 | 25 | ### スポンサー 26 | 27 | Fira Code は個人的なフリータイムのプロジェクトで、資金はなく膨大な[機能リクエストバックログ](https://github.com/tonsky/FiraCode/issues)を抱えています。もし気に入っていただけたなら、[GitHub Sponsors](https://github.com/sponsors/tonsky) または [Patreon](https://patreon.com/tonsky) で開発をサポートすることを検討してください。どんな支援でもかまいません! 28 | 29 | 大いに感謝します: 30 | 31 | 32 | 43 |
33 | 34 |
35 | WorkOS 36 |
37 | Your app, enterprise-ready. 38 |
39 | Start selling to enterprise customers with just a few lines of code. Add Single Sign-On (and more) in minutes instead of months. 40 |
41 |
42 |
44 | 45 | ### 何が入っているのでしょうか? 46 | 47 | 左: Fira Code で描画される合字。右: 合字のない同じ文字列。 48 | 49 | 50 | 51 | Fira Code には、膨大な種類の矢印が用意されています。さらに、好きな長さにしたり、始点・中間・終点の断片を自由に組み合わせたりすることができます! 52 | 53 | 54 | 55 | Fira Code は合字だけではありません。句読点や頻度の高い文字ペアについても、いくつかの微調整が行われています。 56 | 57 | 58 | 59 | Fira Code には、数種類の文字バリエーション(`cv01`、`cv02` など)、スタイルセット(`ss01`、`ss02` など)、その他のフォント機能(`zero`、`onum`、`calt` など)があり、誰もが自分に最適なものを選ぶことができます。[有効にする方法](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) 60 | 61 | 62 | 63 | 一部の合字は、スタイルセット/文字バリアントを使用して変更または有効にすることができます: 64 | 65 | 66 | 67 | プログラミング用フォントである Fira Code は、ASCII/ボックスドローイング、パワーライン、その他の形式のコンソール UI に素晴らしい対応をしています: 68 | 69 | 70 | 71 | Fira Code は、プログレスバーを描画するための専用グリフを提供する最初のプログラミングフォントです: 72 | 73 | 74 | 75 | 動作すると: 76 | 77 | 78 | 79 | より多くのプログラミング用フォントがこの規約を採用し、独自のバージョンを出荷することを望んでいます。 80 | 81 | ユニコード対応により、Fira Code は数学の記述に最適です: 82 | 83 | 84 | 85 | ### どのように見えるのでしょうか? 86 | 87 | 88 | 89 | 90 | ### エディタ互換性リスト 91 | 92 | | サポート | 非サポート | 93 | |-------|----------------| 94 | | **Arduino IDE** (2.0+,same instructions as [vscode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | **Adobe Dreamweaver** | 95 | | **Abricotine** | **Delphi IDE** | 96 | | **Android Studio** (2.3+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([回避方法](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | 97 | | **Anjuta** (unless at the EOF) | **IDLE** | 98 | | **AppCode** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **KDevelop 4** | 99 | | **Atom** 1.1 or newer ([説明](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Monkey Studio IDE** | 100 | | **BBEdit** (14.6+ [説明](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **UltraEdit** (Windows) | 101 | | **Brackets** (with [this plugin](https://github.com/polo2ro/firacode-in-brackets)) | 102 | | **Chocolat** | 103 | | **CLion** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 104 | | **Cloud9** ([説明](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | 105 | | **Coda 2** | 106 | | **CodeLite** | 107 | | **CodeRunner** | 108 | | **Comma** (Under: Preferences > Editor > Font) | 109 | | **CotEditor** | 110 | | **Eclipse** | 111 | | **elementary Code** | 112 | | **Geany** (1.37+) | 113 | | **gEdit / Pluma** | 114 | | **GNOME Builder** | 115 | | **Godot** | 116 | | **GoormIDE** ([説明](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | 117 | | **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | 118 | | **IntelliJ IDEA** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 119 | | **Kate, KWrite** | 120 | | **KDevelop 5+** | 121 | | **Komodo** | 122 | | **Leafpad** | 123 | | **LibreOffice** | 124 | | **LightTable** ([説明](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | 125 | | **LINQPad** | 126 | | **MacVim** 7.4 or newer ([説明](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | 127 | | **Mancy** | 128 | | **MATLAB** ([説明](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | 129 | | **Meld** | 130 | | **Mousepad** | 131 | | **NeoVim-gtk** | 132 | | **NetBeans** | 133 | | **Notepad** (Windows) | 134 | | **Notepad++** ([回避方法](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | 135 | | **Notepad3** ([説明](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| 136 | | **Nova** | 137 | | **PhpStorm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 138 | | **PyCharm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 139 | | **QOwnNotes** (21.16.6+) | 140 | | **QtCreator** | 141 | | **Rider** | 142 | | **RStudio** ([説明](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | 143 | | **RubyMine** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 144 | | **Scratch** | 145 | | **Scribus** (1.5.3+) | 146 | | **SublimeText** (3146+) | 147 | | **Spyder IDE** (Qt5 のみ) | 148 | | **SuperCollider 3** | 149 | | **TeXShop**| 150 | | **TextAdept** (Linux, macOS) | 151 | | **TextEdit** | 152 | | **TextMate 2** | 153 | | **UltraEdit (UEX)** (Linux) | 154 | | **VimR** ([説明](https://github.com/qvacua/vimr/wiki#ligatures)) | 155 | | **Visual Studio** (2015+, [説明](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | 156 | | **Visual Studio Code** ([説明](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | 157 | | **WebStorm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | 158 | | **Xamarin Studio/Monodevelop** | 159 | | **Xcode** (8.0+, それ以外は[プラグイン付き](https://github.com/robertvojta/LigatureXcodePlugin)) | 160 | | **Xi** | 161 | | Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | 162 | 163 | ### ターミナル互換性リスト 164 | 165 | | サポート | 非サポート | 166 | |-------|--------------| 167 | | crosh ([説明](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | 168 | | Hyper ([#3607](https://github.com/vercel/hyper/issues/3607) を確認) | Asbru Connection Manager | 169 | | iTerm 2 | Cmder | 170 | | Kitty | ConEmu | 171 | | Konsole | GNOME Terminal | 172 | | Mintty | gtkterm ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 173 | | QTerminal | guake ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 174 | | st ([パッチ](https://st.suckless.org/patches/ligatures/)) | LXTerminal ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 175 | | Tabby | mate-terminal | 176 | | Terminal.app | PuTTY | 177 | | Termux | rxvt | 178 | | Token2Shell | sakura ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 179 | | Wez’s terminal | SecureCRT 180 | | Windows Terminal | Terminator ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 181 | | ZOC (macOS) | terminology | 182 | | | Tilix | 183 | | | Windows Console | 184 | | | xfce4-terminal ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | 185 | | | xterm | 186 | | | ZOC (Windows) | 187 | 188 | ### ブラウザサポート 189 | 190 | ```html 191 | 192 | 193 | ``` 194 | 195 | ```css 196 | /* CSS */ 197 | @import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); 198 | ``` 199 | 200 | ```css 201 | /* Specify in CSS */ 202 | code { font-family: 'Fira Code', monospace; } 203 | 204 | @supports (font-variation-settings: normal) { 205 | code { font-family: 'Fira Code VF', monospace; } 206 | } 207 | ``` 208 | 209 | - IE 10+, Edge Legacy: `font-feature-settings: "calt";` で有効にします 210 | - Firefox 211 | - Safari 212 | - Chromium-based browsers (Chrome, Opera) 213 | - ACE 214 | - CodeMirror (`font-variant-ligatures: contextual;` で有効にします) 215 | 216 | ### Fira Code を使用したプロジェクト 217 | 218 | - [CodePen](https://codepen.io/) 219 | - [Blink Shell](http://www.blink.sh/) 220 | - [Klipse](http://app.klipse.tech/) 221 | - [IlyaBirman.net](http://ilyabirman.net/) 222 | - [EvilMartians.com](https://evilmartians.com/) 223 | - [Web Maker](https://webmakerapp.com/) 224 | - [FromScratch](https://fromscratch.rocks/) 225 | - [PEP20.org](https://pep20.org/) 226 | 227 | ### 代替品 228 | 229 | 合字のある無料等幅フォント: 230 | 231 | - [Hasklig](https://github.com/i-tu/Hasklig) 232 | - [Monoid](http://larsenwork.com/monoid/) 233 | - [Fixedsys Excelsior](https://github.com/kika/fixedsys) 234 | - [Iosevka](https://be5invis.github.io/Iosevka/) 235 | - [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) 236 | - [Victor Mono](https://rubjo.github.io/victor-mono/) 237 | - [Cascadia Code](https://github.com/microsoft/cascadia-code) 238 | - [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) 239 | 240 | 合字のある有償等幅フォント: 241 | 242 | - [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) 243 | - [Mono Lisa](https://www.monolisa.dev/) 244 | 245 | ### Fira Code をローカルでビルドする 246 | 247 | FiraCode.glyphs を変更し、OTF/TTF/WOFF ファイルを自分でビルドしたい場合、私が macOS で使用している設定は次のとおりです: 248 | 249 | ```bash 250 | # 必要なビルドツールをすべてインストール 251 | ./script/bootstrap_macos.sh 252 | 253 | # フォントファイルのビルド 254 | ./script/build.sh 255 | 256 | # OTF を ~/Library/Fonts にインストール 257 | cp distr/otf/*.otf ~/Library/Fonts 258 | ``` 259 | 260 | または、Docker を使用して Fira Code を構築することもできます: 261 | 262 | ```bash 263 | # コンテナ内に依存関係をインストールし、フォントファイルをビルド 264 | make 265 | 266 | # dist/ のフォントファイルを zip にまとめる 267 | make package 268 | ``` 269 | 270 | 特定のスタイルセットやキャラクタバリエーションを *永久的に* 有効にしたい場合、おそらくあなたの選んだエディタではこれらを個別に切り替えることができないため、`-f / --features` フラグでビルドスクリプトにカンマ区切りリストとして希望の機能を提供することができます。
デフォルト: なし。 271 | 272 | 異なるバージョンのフォントを分けるために、`-n / --family-name` フラグで希望のフォントファミリー名を指定することができます。特別な値 'features' を指定すると、有効な機能をソートしてスペースで区切ったリストをデフォルトのファミリー名に追加します。
デフォルト: "Fira Code" 273 | 274 | また、`-w / --weights` オプションで、作成されるフォントのウェイトを制限することができます。
デフォルト: "Light,Regular,Retina,Medium,SemiBold,Bold" 275 | 276 | ```bash 277 | # ローカルでシェル内 278 | ./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" 279 | 280 | # または Docker コンテナ経由(ファミリー名 'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero' を作成) 281 | docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" 282 | 283 | # Git for Windows の Git Bash やその他の MSYS2 ベースのシェルで使用する場合は、パス変換を無効にする必要があるかもしれません 284 | MSYS2_ARG_CONV_EXCL="*" docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "ss02,ss03,ss04,ss05,ss06,ss07" 285 | ``` 286 | 287 | ### クレジット 288 | 289 | - 作者: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) 290 | - 基にした: [Fira Mono](https://github.com/mozilla/Fira) 291 | - インスパイアされた: [Hasklig](https://github.com/i-tu/Hasklig) 292 | -------------------------------------------------------------------------------- /classes/ClosingBracket.fea: -------------------------------------------------------------------------------- 1 | bracketright braceright parenright -------------------------------------------------------------------------------- /classes/Digit.fea: -------------------------------------------------------------------------------- 1 | zero 2 | zero.zero 3 | one 4 | two 5 | twoTurned 6 | threeTurned 7 | three 8 | four 9 | five 10 | six 11 | seven 12 | eight 13 | nine -------------------------------------------------------------------------------- /classes/DigitTosf.fea: -------------------------------------------------------------------------------- 1 | zero.tosf 2 | zero.tosf.zero 3 | zero.zero.tosf 4 | one.tosf 5 | two.tosf 6 | three.tosf 7 | four.tosf 8 | five.tosf 9 | six.tosf 10 | seven.tosf 11 | eight.tosf 12 | nine.tosf -------------------------------------------------------------------------------- /classes/HexDigit.fea: -------------------------------------------------------------------------------- 1 | a b c d e f A B C D E F -------------------------------------------------------------------------------- /classes/OpeningBracket.fea: -------------------------------------------------------------------------------- 1 | bracketleft braceleft parenleft -------------------------------------------------------------------------------- /classes/Tall.fea: -------------------------------------------------------------------------------- 1 | @Uppercase zero one two twoTurned threeTurned three four five six seven eight nine @OpeningBracket @ClosingBracket bar -------------------------------------------------------------------------------- /clojure/fira_code/calt.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.calt 2 | (:require 3 | [clojure.string :as str] 4 | [fira-code.coll :as coll] 5 | [fira-code.glyphs :as glyphs] 6 | [fira-code.time :as time] 7 | [flatland.ordered.map :refer [ordered-map]])) 8 | 9 | 10 | ;; No ligature should follow those sequences 11 | (def ignore-prefixes 12 | [["parenleft" "question" "colon"] 13 | ;; #578 #624 Regexp lookahead/lookbehind 14 | ["parenleft" "question" "equal"] 15 | ["parenleft" "question" "less" "equal"] 16 | ["parenleft" "question" "exclam"] 17 | ["parenleft" "question" "less" "exclam"] 18 | ;; #850 PHP 38 | ["less" "bar" "greater"] 0 39 | 40 | ;; |||> ||> |> <| <|| <||| 41 | ["bar" "bar" "bar" "greater"] 1 42 | ["bar" "bar" "greater"] 1 43 | ["bar" "greater"] 1 44 | ["less" "bar" "bar" "bar"] 1 45 | ["less" "bar" "bar"] 1 46 | ["less" "bar"] 1 47 | 48 | ;; #346 We need << <<< >> >>> || ||| substituted before -- --- == === 49 | ;; so that `ignore [less greater bar] hyphen hyphen` would not trigger 50 | ["less" "less"] 2 51 | ["less" "less" "less"] 2 52 | ["greater" "greater"] 2 53 | ["greater" "greater" "greater"] 2 54 | ["bar" "bar"] 2 55 | ["bar" "bar" "bar"] 2}) 56 | 57 | 58 | (def ignores 59 | (coll/multimap-by str 60 | ["slash" "asterisk"] 61 | (str 62 | " ignore sub slash' asterisk slash;\n" 63 | " ignore sub asterisk slash' asterisk;\n") 64 | 65 | ["asterisk" "slash"] 66 | (str 67 | " ignore sub slash asterisk' slash;\n" 68 | " ignore sub asterisk' slash asterisk;\n") 69 | 70 | ["asterisk" "asterisk"] 71 | (str 72 | " ignore sub slash asterisk' asterisk;\n" 73 | " ignore sub asterisk' asterisk slash;\n") 74 | 75 | ["asterisk" "asterisk" "asterisk"] 76 | (str 77 | " ignore sub slash asterisk' asterisk asterisk;\n" 78 | " ignore sub asterisk' asterisk asterisk slash;\n") 79 | 80 | ;; #1061 81 | ["colon" "colon"] 82 | (str " ignore sub colon' colon [less greater];\n" 83 | " ignore sub [less greater] colon' colon;\n") 84 | 85 | ["colon" "colon" "colon"] 86 | (str " ignore sub colon' colon colon [less greater];\n" 87 | " ignore sub [less greater] colon' colon colon;\n") 88 | 89 | ;; #621 <||> 90 | ["less" "bar" "bar"] 91 | " ignore sub less' bar bar greater;\n" 92 | 93 | ["bar" "bar" "greater"] 94 | " ignore sub less bar' bar greater;\n" 95 | 96 | ;; #593 {|} 97 | ["braceleft" "bar"] 98 | " ignore sub braceleft' bar braceright;\n" 99 | 100 | ["bar" "braceright"] 101 | " ignore sub braceleft bar' braceright;\n" 102 | 103 | ;; #593 [|] 104 | ["bracketleft" "bar"] 105 | " ignore sub bracketleft' bar bracketright;\n" 106 | 107 | ["bar" "bracketright"] 108 | " ignore sub bracketleft bar' bracketright;\n" 109 | 110 | ;; #410 <*>> <+>> <$>> 111 | ["greater" "greater"] 112 | " ignore sub [asterisk plus dollar] greater' greater;\n" 113 | 114 | ;; #410 <*>>> <+>>> <$>>> 115 | ["greater" "greater" "greater"] 116 | " ignore sub [asterisk plus dollar] greater' greater greater;\n" 117 | 118 | ;; #410 <<*> <<+> <<$> 119 | ["less" "less"] 120 | " ignore sub less' less [asterisk plus dollar];\n" 121 | 122 | ;; #410 <<<*> <<<+> <<<$> 123 | ["less" "less" "less"] 124 | " ignore sub less' less less [asterisk plus dollar];\n" 125 | 126 | ;; #948 [==[ ]==] 127 | ;; #968 [== ==] 128 | ["equal" "equal"] 129 | (str " ignore sub bracketleft equal' equal;\n" 130 | " ignore sub equal' equal bracketright;\n") 131 | 132 | ;; #948 [===[ ]===] 133 | ;; #968 [=== ===] 134 | ["equal" "equal" "equal"] 135 | (str " ignore sub bracketleft equal' equal equal;\n" 136 | " ignore sub equal' equal equal bracketright;\n") 137 | 138 | ;; #346 =:= 139 | ["colon" "equal"] 140 | " ignore sub equal colon' equal;\n" 141 | 142 | ;; #346 =!= 143 | ["exclam" "equal"] 144 | " ignore sub equal exclam' equal;\n" 145 | ;; #346 =!== 146 | ["exclam" "equal" "equal"] 147 | " ignore sub equal exclam' equal equal;\n" 148 | 149 | ;; #346 =<= <=< <=> <=| <=: <=! <=/ 150 | ["less" "equal"] 151 | (str " ignore sub equal less' equal;\n" 152 | " ignore sub less' equal [less greater bar colon exclam slash];\n") 153 | 154 | ;; #548 >=< 155 | ;; #346 =>= >=> >=< >=| >=: >=! >=/ 156 | ["greater" "equal"] 157 | (str " ignore sub equal greater' equal;\n" 158 | " ignore sub greater' equal [less greater bar colon exclam slash];\n") 159 | 160 | ;; #346 >>->> >>=>> 161 | ;; #974 keep >>= 162 | ["greater" "greater"] 163 | (str " ignore sub [hyphen equal] greater' greater;\n" 164 | " ignore sub greater' greater hyphen;\n" 165 | " ignore sub greater' greater equal [equal less greater bar colon exclam slash];\n") 166 | 167 | ;; #346 <<-<< <<=<< 168 | ;; #974 keep <<= 169 | ["less" "less"] 170 | (str " ignore sub [hyphen equal] less' less;\n" 171 | " ignore sub less' less hyphen;\n" 172 | " ignore sub less' less equal [equal less greater bar colon exclam slash];\n") 173 | 174 | ;; #346 ||-|| ||=|| 175 | ;; #974 keep ||= 176 | ["bar" "bar"] 177 | (str " ignore sub [hyphen equal] bar' bar;\n" 178 | " ignore sub bar' bar hyphen;\n" 179 | " ignore sub bar' bar equal [equal less greater bar colon exclam slash];\n") 180 | 181 | ;; #816 //= 182 | ["slash" "slash"] 183 | (str " ignore sub equal slash' slash;\n" 184 | " ignore sub slash' slash equal;\n") 185 | 186 | ;; #346 <--> >--< |--| 187 | ["hyphen" "hyphen"] 188 | (str " ignore sub [less greater bar] hyphen' hyphen;\n" 189 | " ignore sub hyphen' hyphen [less greater bar];\n") 190 | 191 | ;; #346 <==> >==< |==| /==/ =:== =!== ==:= ==!= 192 | ["equal" "equal"] 193 | (str " ignore sub equal [colon exclam] equal' equal;\n" 194 | " ignore sub [less greater bar slash] equal' equal;\n" 195 | " ignore sub equal' equal [less greater bar slash] ;\n" 196 | " ignore sub equal' equal [colon exclam] equal;\n") 197 | 198 | ;; #346 <===> >===< |===| /===/ =:=== =!=== ===:= ===!= 199 | ["equal" "equal" "equal"] 200 | (str " ignore sub equal [colon exclam] equal' equal equal;\n" 201 | " ignore sub [less greater bar slash] equal' equal equal;\n" 202 | " ignore sub equal' equal equal [less greater bar slash];\n" 203 | " ignore sub equal' equal equal [colon exclam] equal;\n") 204 | )) 205 | 206 | 207 | ;; DO NOT generate ignores at all 208 | (def skip-ignores? #{ 209 | ;; #410 <<*>> <<+>> <<$>> 210 | ["less" "asterisk" "greater"] 211 | ["less" "plus" "greater"] 212 | ["less" "dollar" "greater"] 213 | }) 214 | 215 | 216 | ;; DO NOT generate ligature 217 | (def manual? #{ 218 | ;; /\ \/ 219 | ["slash" "backslash"] 220 | ["backslash" "slash"] 221 | }) 222 | 223 | 224 | (defn liga->rule 225 | "[f f i] => { [LIG LIG i] f_f_i.liga 226 | [LIG f i] LIG 227 | [ f f i] LIG }" 228 | [liga] 229 | (case (count liga) 230 | 2 (let [[a b] liga] 231 | (str/replace 232 | (str 233 | "lookup 1_2 {\n" 234 | (when-not (skip-ignores? liga) 235 | (str " ignore sub 1 1' 2;\n" 236 | " ignore sub 1' 2 2;\n")) 237 | (gen-ignore-prefixes liga) 238 | (get ignores liga) 239 | " sub 1.spacer 2' by 1_2.liga;\n" 240 | " sub 1' 2 by 1.spacer;\n" 241 | ; "sub 1 2 by 1_2.liga;" 242 | "} 1_2;") 243 | #"\d" {"1" a "2" b})) 244 | 3 (let [[a b c] liga] 245 | (str/replace 246 | (str 247 | "lookup 1_2_3 {\n" 248 | (when-not (skip-ignores? liga) 249 | (str " ignore sub 1 1' 2 3;\n" 250 | " ignore sub 1' 2 3 3;\n")) 251 | (gen-ignore-prefixes liga) 252 | (get ignores liga) 253 | " sub 1.spacer 2.spacer 3' by 1_2_3.liga;\n" 254 | " sub 1.spacer 2' 3 by 2.spacer;\n" 255 | " sub 1' 2 3 by 1.spacer;\n" 256 | ; "sub 1 2 3 by 1_2_3.liga;" 257 | "} 1_2_3;") 258 | #"\d" {"1" a "2" b "3" c})) 259 | 4 (let [[a b c d] liga] 260 | (str/replace 261 | (str 262 | "lookup 1_2_3_4 {\n" 263 | (when-not (skip-ignores? liga) 264 | (str " ignore sub 1 1' 2 3 4;\n" 265 | " ignore sub 1' 2 3 4 4;\n")) 266 | (gen-ignore-prefixes liga) 267 | (get ignores liga) 268 | " sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga;\n" 269 | " sub 1.spacer 2.spacer 3' 4 by 3.spacer;\n" 270 | " sub 1.spacer 2' 3 4 by 2.spacer;\n" 271 | " sub 1' 2 3 4 by 1.spacer;\n" 272 | ; "sub 1 2 3 4 by 1_2_3_4.liga;" 273 | "} 1_2_3_4;") 274 | #"\d" {"1" a "2" b "3" c "4" d})) 275 | 5 (let [[a b c d e] liga] 276 | (str/replace 277 | (str 278 | "lookup 1_2_3_4_5 {\n" 279 | (when-not (skip-ignores? liga) 280 | (str " ignore sub 1 1' 2 3 4 5;\n" 281 | " ignore sub 1' 2 3 4 4 5;\n")) 282 | (gen-ignore-prefixes liga) 283 | (get ignores liga) 284 | " sub 1.spacer 2.spacer 3.spacer 4.spacer 5' by 1_2_3_4_5.liga;\n" 285 | " sub 1.spacer 2.spacer 3.spacer 4' 5 by 4.spacer;\n" 286 | " sub 1.spacer 2.spacer 3' 4 5 by 3.spacer;\n" 287 | " sub 1.spacer 2' 3 4 5 by 2.spacer;\n" 288 | " sub 1' 2 3 4 5 by 1.spacer;\n" 289 | ; "sub 1 2 3 4 5 by 1_2_3_4_5.liga;" 290 | "} 1_2_3_4_5;") 291 | #"\d" {"1" a "2" b "3" c "4" d "5" e})) 292 | )) 293 | 294 | 295 | (defn compare-ligas [l1 l2] 296 | (let [p1 (priorities l1 Long/MAX_VALUE) 297 | p2 (priorities l2 Long/MAX_VALUE) 298 | pc (compare p1 p2) 299 | c1 (count l1) 300 | c2 (count l2) 301 | cc (compare c1 c2)] 302 | (cond 303 | (not= 0 pc) pc ;; lower priority first 304 | (not= 0 cc) (- cc) ;; longer first 305 | :else (compare l1 l2)))) ;; alphabetical 306 | 307 | 308 | (defn replace-calt [font ligas] 309 | (let [ligas' (->> ligas 310 | (remove manual?) 311 | (sort compare-ligas)) 312 | calt (->> ligas' 313 | (map liga->rule) 314 | (str/join "\n\n")) 315 | glyphs (map #(str (str/join "_" %) ".liga") ligas') 316 | counts (coll/group-by-to count count ligas')] 317 | 318 | (when-some [unused (not-empty (reduce dissoc ignores ligas'))] 319 | (println " WARN Unused ignores" (str/join " " (keys unused)))) 320 | 321 | (when-some [unused (not-empty (reduce disj skip-ignores? ligas'))] 322 | (println " WARN Unused skip-ignores?" (str/join " " unused))) 323 | 324 | (when-some [unused (not-empty (reduce disj manual? ligas))] 325 | (println " WARN Unused manual?" (str/join " " unused))) 326 | 327 | (println " generated calt:" 328 | ; (str/join " " glyphs) 329 | (str 330 | #_"(" (get counts 2) " pairs, " 331 | (get counts 3) " triples, " 332 | (get counts 4) " quadruples, " 333 | (count ligas') " total" #_")")) 334 | 335 | (glyphs/update-code font :features "calt" (constantly calt)))) 336 | -------------------------------------------------------------------------------- /clojure/fira_code/checks.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.checks 2 | (:require 3 | [clojure.string :as str] 4 | [fira-code.coll :as coll] 5 | [fira-code.glyphs :as glyphs])) 6 | 7 | (defn width-ok? [w] 8 | (#{"0" 0 1200} w)) 9 | 10 | (defn widths [font] 11 | (doseq [g (:glyphs font) 12 | :when (not= "0" (:export g)) 13 | :let [[w & _ :as ws] (mapv :width (:layers g))]] 14 | (when-not (apply = ws) 15 | (println (str "WARN glyph '" (:glyphname g) "' has different widths=" (pr-str ws)))) 16 | (when-not (width-ok? w) 17 | (println (str "WARN glyph '" (:glyphname g) "' has unexpected width=" (pr-str w))))) 18 | font) 19 | 20 | (defn -main [& args] 21 | (let [path (or (first args) "FiraCode.glyphs") 22 | font (glyphs/load path)] 23 | (widths font))) -------------------------------------------------------------------------------- /clojure/fira_code/classes.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.classes 2 | (:require 3 | [clojure.java.io :as io] 4 | [clojure.string :as str] 5 | [fira-code.glyphs :as glyphs] 6 | [fira-code.files :as files])) 7 | 8 | 9 | (defn fill-class [font file] 10 | (let [[_ name] (re-matches #"([^.]+)\.fea" (.getName file)) 11 | code (slurp file) 12 | class {:code (str/trim code) 13 | :name name}] 14 | (glyphs/set-class font name class))) 15 | 16 | 17 | (defn fill-all [font] 18 | (reduce fill-class font (files/find "classes" #"classes/[^/]+\.fea"))) 19 | -------------------------------------------------------------------------------- /clojure/fira_code/coll.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.coll) 2 | 3 | 4 | (defn index-of [pred xs] 5 | (let [res (reduce (fn [i x] (if (pred x) (reduced i) (inc i))) 0 xs)] 6 | (if (>= res (count xs)) 7 | -1 8 | res))) 9 | 10 | 11 | (defn group-by-to [key-fn value-fn xs] 12 | (reduce-kv 13 | (fn [m k vs] 14 | (assoc m k (value-fn vs))) 15 | {} 16 | (group-by key-fn xs))) 17 | 18 | 19 | (defn multimap-by [f & kvs] 20 | (reduce 21 | (fn [m [k v]] 22 | (if (contains? m k) 23 | (update m k f v) 24 | (assoc m k v))) 25 | {} (partition 2 kvs))) -------------------------------------------------------------------------------- /clojure/fira_code/features.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.features 2 | (:require 3 | [clojure.java.io :as io] 4 | [clojure.string :as str] 5 | [fira-code.glyphs :as glyphs] 6 | [fira-code.files :as files])) 7 | 8 | 9 | (defn append-calt [font] 10 | (let [features (->> (files/find "features/calt" #"features/calt/[^/]+\.fea") 11 | (map slurp) 12 | (map str/trim) 13 | (str/join "\n\n"))] 14 | (println " appending to feature calt" (glyphs/lines features) "lines") 15 | (glyphs/update-code font :features "calt" 16 | #(str % "\n\n" features)))) 17 | 18 | 19 | (defn fill-feature [font file] 20 | (let [[_ name] (re-matches #"([^.]+)\.fea" (.getName file)) 21 | code (slurp file) 22 | [_ notes code'] (re-matches #"(?s)#([^\n]+)\n(.*)" code) 23 | feature (cond-> {:code (str/trim (or code' code)) 24 | :name name} 25 | notes 26 | (assoc :notes (str/trim notes)))] 27 | (glyphs/set-feature font name feature))) 28 | 29 | 30 | (defn fill-features [font] 31 | (reduce fill-feature font (files/find "features" #"features/[^/]+\.fea"))) 32 | 33 | 34 | (defn fill-all [font] 35 | (-> font 36 | (append-calt) 37 | (fill-features))) -------------------------------------------------------------------------------- /clojure/fira_code/files.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.files 2 | (:refer-clojure :exclude [find]) 3 | (:require 4 | [clojure.java.io :as io] 5 | [clojure.string :as str])) 6 | 7 | 8 | (defn find [path re] 9 | (->> (file-seq (io/file path)) 10 | (next) ;; skip directory itself 11 | (filter #(re-matches re (.getPath %))) 12 | (sort-by #(.getPath %)))) -------------------------------------------------------------------------------- /clojure/fira_code/glyphs.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.glyphs 2 | (:refer-clojure :exclude [load]) 3 | (:require 4 | [clojure.java.io :as io] 5 | [clojure.string :as str] 6 | [fipp.edn :as fipp] 7 | [fira-code.coll :as coll] 8 | [flatland.ordered.map :refer [ordered-map]])) 9 | 10 | (def ^:dynamic *str) 11 | (def ^:dynamic *pos) 12 | 13 | (defn current-char [] (nth @*str @*pos)) 14 | 15 | (defn advance! [] (swap! *pos inc)) 16 | 17 | (declare parse-anything!) 18 | 19 | (defn skip-ws! [] 20 | (loop [] 21 | (case (current-char) 22 | \space (do (advance!) (recur)) 23 | \newline (do (advance!) (recur)) 24 | nil))) 25 | 26 | (defn parse-escaped-string! [] 27 | (skip-ws!) 28 | (when (= \" (current-char)) 29 | (let [sb (StringBuilder.)] 30 | (-> 31 | (loop [] 32 | (advance!) 33 | (let [ch (current-char)] 34 | (cond 35 | (= ch \\) (do (.append sb \\) (advance!) (.append sb (current-char)) (recur)) 36 | (= ch \") (do (advance!) (str sb)) 37 | :else (do (.append sb ch) (recur))))) 38 | (str/replace "\\012" "\n") 39 | (str/replace "\\\"" "\"") 40 | (str/replace "\\\\" "\\"))))) 41 | 42 | (defn parse-string! [] 43 | (skip-ws!) 44 | (let [sb (StringBuilder.)] 45 | (loop [] 46 | (let [ch (current-char)] 47 | (cond 48 | (#{\space \newline \{ \} \( \) \; \, \" \=} ch) sb 49 | :else (do (.append sb ch) (advance!) (recur))))) 50 | (let [res (str sb)] 51 | (cond 52 | (re-matches #"-?[1-9][0-9]*" res) (Integer/parseInt res) 53 | (re-matches #"-?[0-9]+\.[0-9]+" res) (Double/parseDouble res) 54 | (re-matches #"[a-zA-Z][a-zA-Z\.0-9]*" res) (keyword res) 55 | :else res)))) 56 | 57 | (defn expect [c] 58 | (assert (= c (current-char)) 59 | (str "Expected '" c 60 | "', found " (current-char) 61 | " at " @*pos 62 | " around here:\n" (subs @*str (max 0 (- @*pos 100)) (min (count @*str) (+ @*pos 100)))))) 63 | 64 | (defn parse-map! [] 65 | (skip-ws!) 66 | (when (= \{ (current-char)) 67 | (advance!) 68 | (loop [m (ordered-map)] 69 | (skip-ws!) 70 | (if (= \} (current-char)) 71 | (do (advance!) m) 72 | (let [k (or (parse-escaped-string!) (parse-string!)) 73 | _ (do (skip-ws!) (expect \=) (advance!)) 74 | v (parse-anything!) 75 | v (if (keyword? v) (name v) v) 76 | _ (do (skip-ws!) (expect \;) (advance!))] 77 | (recur (assoc m k v))))))) 78 | 79 | (defn parse-list! [] 80 | (skip-ws!) 81 | (when (= \( (current-char)) 82 | (advance!) 83 | (loop [l []] 84 | (skip-ws!) 85 | (if (= \) (current-char)) 86 | (do (advance!) l) 87 | (let [v (parse-anything!) 88 | _ (skip-ws!) 89 | _ (when (not= \) (current-char)) 90 | (expect \,) 91 | (advance!))] 92 | (recur (conj l v))))))) 93 | 94 | (defn parse-anything! [] 95 | (skip-ws!) 96 | (or 97 | (parse-map!) 98 | (parse-list!) 99 | (parse-escaped-string!) 100 | (parse-string!))) 101 | 102 | (defn parse [s] 103 | (binding [*str (atom s) 104 | *pos (atom 0)] 105 | (parse-anything!))) 106 | 107 | (def escapes {"\n" "\\012" 108 | "\"" "\\\"" 109 | "\\" "\\\\"}) 110 | 111 | (def escape-re #"[\n\"\\]") 112 | 113 | (defn- serialize-impl [form] 114 | (cond 115 | (string? form) (if (re-matches #"[a-zA-Z0-9._/]+" form) 116 | form 117 | (str \" (str/replace form escape-re escapes) \")) 118 | (keyword? form) (name form) 119 | (number? form) (str form) 120 | (instance? clojure.lang.MapEntry form) 121 | (str 122 | (serialize-impl (key form)) 123 | " = " 124 | (if (= ".appVersion" (key form)) ;; https://github.com/googlefonts/glyphsLib/issues/209 125 | (str \" (val form) \") 126 | (serialize-impl (val form))) 127 | ";") 128 | (sequential? form) (if (empty? form) 129 | "(\n)" 130 | (str "(\n" (str/join ",\n" (map serialize-impl form)) "\n)")) 131 | (map? form) (if (empty? form) 132 | "{\n}" 133 | (str "{\n" (str/join "\n" (map serialize-impl form)) "\n}")))) 134 | 135 | (defn serialize [font] 136 | (str (serialize-impl font) "\n")) 137 | 138 | ; (-> (slurp "FiraCode.glyphs") parse serialize (->> (spit "FiraCode_saved.glyphs"))) 139 | 140 | (defn load [path] 141 | (println (str "Parsing '" path "'...")) 142 | (parse (slurp path))) 143 | 144 | (defn save! [path font] 145 | (println (str "Saving '" path "'...")) 146 | (spit path (serialize font))) 147 | 148 | (defn -main [& args] 149 | (let [font (-> (slurp "FiraCode.glyphs") parse)] 150 | (with-open [os (io/writer "clojure/FiraCode.edn")] 151 | (binding [*out* os] 152 | (fipp/pprint font {:width 200}))))) 153 | 154 | 155 | (defn update-code [font key name f & args] 156 | (let [idx (coll/index-of #(= (:name %) name) (get font key))] 157 | (assert (>= idx 0) (str "Can’t find " key "[name=\"" name "\"], got " (str/join ", " (map :name (get font key))))) 158 | (apply update-in font [key idx :code] f args))) 159 | 160 | 161 | (defn lines [s] 162 | (inc (count (re-seq #"\n" s)))) 163 | 164 | 165 | (defn words [s] 166 | (count (re-seq #"[^\s]+" s))) 167 | 168 | 169 | (defn set-feature [font name feature] 170 | (let [idx (coll/index-of #(= (:name %) name) (:features font))] 171 | (if (pos? idx) 172 | (do 173 | (println " replacing feature" name "with" (lines (:code feature)) "lines") 174 | (assoc-in font [:features idx] feature)) 175 | (do 176 | (println " appending to feature" name (lines (:code feature)) "lines") 177 | (update font :features conj feature))))) 178 | 179 | 180 | (defn set-class [font name class] 181 | (let [idx (coll/index-of #(= (:name %) name) (:classes font))] 182 | (if (pos? idx) 183 | (do 184 | (println " replacing class" name "with" (words (:code class)) "entries") 185 | (assoc-in font [:classes idx] class)) 186 | (do 187 | (println " appending to class" name (words (:code class)) "entries") 188 | (update font :classes conj class))))) 189 | 190 | 191 | (def weights 192 | {:Light "B67F0F2D-EC95-4CB8-966E-23AE86958A69" 193 | :Regular "UUID0" 194 | :Bold "4B7A3BAF-EAD8-4024-9BEA-BB1DE86CFCFA"}) 195 | 196 | 197 | (defn layer [l] 198 | { :id (condp = (:layerId l) 199 | (:Light weights) "Light" 200 | (:Regular weights) "Regular" 201 | (:Bold weights) "Bold" 202 | (:layerId l)) 203 | :width (:width l) }) 204 | 205 | (defn save-not600 [] 206 | (let [font (-> (slurp "FiraCode.glyphs") parse)] 207 | (with-open [os (io/writer "clojure/FiraCode_not600.edn")] 208 | (binding [*out* os] 209 | (let [glyphs (for [glyph (:glyphs font) 210 | :when (->> (:layers glyph) 211 | (filter #(contains? (set (vals weights)) (:layerId %))) 212 | (every? #(= 600 (:width %))) 213 | (not))] 214 | {:glyphname (:glyphname glyph) 215 | :layers (mapv layer (:layers glyph))})] 216 | (doseq [glyph glyphs] 217 | (fipp/pprint glyph {:width 200})) 218 | (count glyphs)))))) 219 | 220 | ;; (-main) 221 | ;; (save-not600) 222 | ;; (-> (slurp "FiraCode.glyphs") parse keys) 223 | ;; -------------------------------------------------------------------------------- /clojure/fira_code/main.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.main 2 | (:require 3 | [clojure.string :as str] 4 | [fira-code.calt :as calt] 5 | [fira-code.coll :as coll] 6 | [fira-code.checks :as checks] 7 | [fira-code.classes :as classes] 8 | [fira-code.features :as features] 9 | [fira-code.glyphs :as glyphs] 10 | [fira-code.not-space :as not-space] 11 | [fira-code.spacers :as spacers] 12 | [fira-code.time :as time] 13 | [flatland.ordered.map :refer [ordered-map]])) 14 | 15 | 16 | (defn -main [& args] 17 | (let [path (or (first args) "FiraCode.glyphs") 18 | font (glyphs/load path) 19 | ligas (for [g (:glyphs font) 20 | :let [name (:glyphname g)] 21 | :when (str/ends-with? name ".liga") 22 | :when (not= "0" (:export g)) 23 | :let [[_ liga] (re-matches #"([A-Za-z_]+)\.liga" name)]] 24 | (str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ] 25 | font' (-> font 26 | (calt/replace-calt ligas) 27 | (classes/fill-all) 28 | (features/fill-all) 29 | (spacers/add-spacers ligas) 30 | (not-space/regen-not-space) 31 | (checks/widths))] 32 | (glyphs/save! path font') 33 | (println))) -------------------------------------------------------------------------------- /clojure/fira_code/not_space.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.not-space 2 | (:require 3 | [clojure.string :as str] 4 | [fira-code.glyphs :as glyphs])) 5 | 6 | 7 | (defn regen-not-space [font] 8 | (let [not-spaces (->> (:glyphs font) 9 | (remove #(re-find #"^\.|space$|space\." (:glyphname %))) 10 | (remove #(= "0" (:export %))) 11 | (map :glyphname) 12 | (sort))] 13 | (println " regenerated NotSpace:" (count not-spaces) "glyphs") 14 | (glyphs/update-code font :classes "NotSpace" (constantly (str/join " " not-spaces))))) -------------------------------------------------------------------------------- /clojure/fira_code/spacers.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.spacers 2 | (:require 3 | [clojure.string :as str] 4 | [fira-code.glyphs :as glyphs] 5 | [fira-code.time :as time] 6 | [flatland.ordered.map :refer [ordered-map]])) 7 | 8 | 9 | (defn spacer [name] 10 | (ordered-map 11 | :color 3, 12 | :glyphname name, 13 | :lastChange (time/now-str), 14 | :layers 15 | [(ordered-map :layerId (:Light glyphs/weights), :width 1200) 16 | (ordered-map :layerId (:Bold glyphs/weights), :width 1200)])) 17 | 18 | 19 | (defn add-spacers [font ligas] 20 | (let [needed (->> (into #{} cat ligas) 21 | (map #(str % ".spacer"))) 22 | existing (->> (:glyphs font) 23 | (map :glyphname) 24 | (filter #(str/ends-with? % ".spacer"))) 25 | new (->> (remove (set existing) needed) 26 | (sort-by str/lower-case))] 27 | (if-not (empty? new) 28 | (do 29 | (println " added glyphs: " (str/join " " new)) 30 | (update font :glyphs #(into % (map spacer new)))) 31 | font))) -------------------------------------------------------------------------------- /clojure/fira_code/time.clj: -------------------------------------------------------------------------------- 1 | (ns fira-code.time 2 | (:import 3 | [java.time LocalDateTime ZoneId] 4 | [java.time.format DateTimeFormatter])) 5 | 6 | 7 | (def ^ZoneId UTC (ZoneId/of "UTC")) 8 | 9 | 10 | (defn now-str [] 11 | (.format 12 | (DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss +0000") 13 | (LocalDateTime/now UTC))) 14 | -------------------------------------------------------------------------------- /clojure/user.clj: -------------------------------------------------------------------------------- 1 | (ns user 2 | (:require 3 | [clojure.core.server :as server] 4 | [clojure.java.io :as io] 5 | [clojure.tools.namespace.repl :as ns] 6 | [clojure.tools.namespace.track :as track])) 7 | 8 | (ns/disable-reload!) 9 | 10 | (ns/set-refresh-dirs "clojure") 11 | 12 | (def *reloaded 13 | (atom nil)) 14 | 15 | (add-watch #'ns/refresh-tracker ::watch 16 | (fn [_ _ old new] 17 | (when (empty? (::track/load new)) 18 | (reset! *reloaded (::track/load old))))) 19 | 20 | (defn after-reload [] 21 | (let [cnt (count @*reloaded)] 22 | (str "Reloaded " cnt " namespace" (when (> cnt 1) "s")))) 23 | 24 | (defn reload [] 25 | (set! *warn-on-reflection* true) 26 | ; (set! *unchecked-math* :warn-on-boxed) 27 | (let [res (ns/refresh :after 'user/after-reload)] 28 | (if (instance? Throwable res) 29 | (throw res) 30 | res))) 31 | 32 | (def p-lock 33 | (Object.)) 34 | 35 | (defn p-pos [] 36 | (let [trace (->> (Thread/currentThread) 37 | (.getStackTrace) 38 | (seq)) 39 | el ^StackTraceElement (nth trace 4)] 40 | (str "[" (clojure.lang.Compiler/demunge (.getClassName el)) " " (.getFileName el) ":" (.getLineNumber el) "]"))) 41 | 42 | (defn p-impl [position form res] 43 | (let [form (clojure.walk/postwalk 44 | (fn [form] 45 | (if (and 46 | (list? form) 47 | (= 'user/p-impl (first form))) 48 | (clojure.lang.TaggedLiteral/create 'p (nth form 3)) 49 | form)) 50 | form)] 51 | (locking p-lock 52 | (println (str position " #p " form " => " (pr-str res)))) 53 | res)) 54 | 55 | (defn p [form] 56 | `(p-impl (p-pos) '~form ~form)) 57 | 58 | (defn -main [& args] 59 | ;; setup repl 60 | (let [args (apply array-map args) 61 | port (or 62 | (some-> (get args "--port") parse-long) 63 | (+ 1024 (rand-int 64512))) 64 | file (io/file ".repl-port")] 65 | (println "Started Server Socket REPL on port" port) 66 | (spit file port) 67 | (.deleteOnExit file) 68 | (server/start-server 69 | {:name "repl" 70 | :port port 71 | :accept 'clojure.core.server/repl 72 | :server-daemon false}))) 73 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["clojure"] 2 | :deps {org.clojure/clojure {:mvn/version "1.11.1"} 3 | org.flatland/ordered {:mvn/version "1.5.7"} 4 | fipp/fipp {:mvn/version "0.6.18"} 5 | org.clojure/tools.namespace {:mvn/version "1.3.0"}}} 6 | -------------------------------------------------------------------------------- /distr/fira_code.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Fira Code'; 3 | src: url('woff2/FiraCode-Light.woff2') format('woff2'), 4 | url('woff/FiraCode-Light.woff') format('woff'); 5 | font-weight: 300; 6 | font-style: normal; 7 | } 8 | 9 | @font-face { 10 | font-family: 'Fira Code'; 11 | src: url('woff2/FiraCode-Regular.woff2') format('woff2'), 12 | url('woff/FiraCode-Regular.woff') format('woff'); 13 | font-weight: 400; 14 | font-style: normal; 15 | } 16 | 17 | @font-face { 18 | font-family: 'Fira Code'; 19 | src: url('woff2/FiraCode-Medium.woff2') format('woff2'), 20 | url('woff/FiraCode-Medium.woff') format('woff'); 21 | font-weight: 500; 22 | font-style: normal; 23 | } 24 | 25 | @font-face { 26 | font-family: 'Fira Code'; 27 | src: url('woff2/FiraCode-SemiBold.woff2') format('woff2'), 28 | url('woff/FiraCode-SemiBold.woff') format('woff'); 29 | font-weight: 600; 30 | font-style: normal; 31 | } 32 | 33 | @font-face { 34 | font-family: 'Fira Code'; 35 | src: url('woff2/FiraCode-Bold.woff2') format('woff2'), 36 | url('woff/FiraCode-Bold.woff') format('woff'); 37 | font-weight: 700; 38 | font-style: normal; 39 | } 40 | 41 | @font-face { 42 | font-family: 'Fira Code VF'; 43 | src: url('woff2/FiraCode-VF.woff2') format('woff2-variations'), 44 | url('woff/FiraCode-VF.woff') format('woff-variations'); 45 | /* font-weight requires a range: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#Using_a_variable_font_font-face_changes */ 46 | font-weight: 300 700; 47 | font-style: normal; 48 | } 49 | -------------------------------------------------------------------------------- /distr/specimen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Fira Code Specimen 7 | 8 | 9 | 28 | 35 | 36 | 37 |
# Fira Code Light 38 | 39 | take = (n, [x, ...xs]:list) --> 40 | | n <= 0 => [] 41 | | empty list => [] 42 | | otherwise => [x] ++ take n-1, xs 43 | 44 | last3 = reverse >> take 3 >> reverse
45 | 46 | 47 |
# Fira Code Regular 48 | 49 | take = (n, [x, ...xs]:list) --> 50 | | n <= 0 => [] 51 | | empty list => [] 52 | | otherwise => [x] ++ take n-1, xs 53 | 54 | last3 = reverse >> take 3 >> reverse
55 | 56 | 57 |
# Fira Code Medium 58 | 59 | take = (n, [x, ...xs]:list) --> 60 | | n <= 0 => [] 61 | | empty list => [] 62 | | otherwise => [x] ++ take n-1, xs 63 | 64 | last3 = reverse >> take 3 >> reverse
65 | 66 | 67 |
# Fira Code SemiBold 68 | 69 | take = (n, [x, ...xs]:list) --> 70 | | n <= 0 => [] 71 | | empty list => [] 72 | | otherwise => [x] ++ take n-1, xs 73 | 74 | last3 = reverse >> take 3 >> reverse
75 | 76 | 77 |
# Fira Code Bold 78 | 79 | take = (n, [x, ...xs]:list) --> 80 | | n <= 0 => [] 81 | | empty list => [] 82 | | otherwise => [x] ++ take n-1, xs 83 | 84 | last3 = reverse >> take 3 >> reverse
85 | 86 |
# Fira Code Variable 87 | 88 | 400 89 | 90 | take = (n, [x, ...xs]:list) --> 91 | | n <= 0 => [] 92 | | empty list => [] 93 | | otherwise => [x] ++ take n-1, xs 94 | 95 | last3 = reverse >> take 3 >> reverse
96 | -------------------------------------------------------------------------------- /docs/calt_performance.md: -------------------------------------------------------------------------------- 1 | # Time to shape text with different calt code 2 | 3 | Baseline: 4 | 5 | ``` 6 | sub 1 2 3 4 by 1_2_3_4.liga; 7 | ``` 8 | 9 | Spacers: 10 | 11 | ``` 12 | sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; 13 | sub 1.spacer 2.spacer 3' 4 by 3.spacer; 14 | sub 1.spacer 2' 3 4 by 2.spacer; 15 | sub 1' 2 3 4 by 1.spacer; 16 | ``` 17 | 18 | Lookups: 19 | 20 | ``` 21 | lookup 1_2_3_4 { 22 | sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; 23 | sub 1.spacer 2.spacer 3' 4 by 3.spacer; 24 | sub 1.spacer 2' 3 4 by 2.spacer; 25 | sub 1' 2 3 4 by 1.spacer; 26 | } 1_2_3_4; 27 | ``` 28 | 29 | Ignores: 30 | 31 | ``` 32 | lookup 1_2_3_4 { 33 | ignore sub 1 1' 2 3 4; 34 | ignore sub 1' 2 3 4 4; 35 | sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; 36 | sub 1.spacer 2.spacer 3' 4 by 3.spacer; 37 | sub 1.spacer 2' 3 4 by 2.spacer; 38 | sub 1' 2 3 4 by 1.spacer; 39 | } 1_2_3_4; 40 | ``` 41 | 42 | Benchmark: 43 | 44 | ``` 45 | time hb-shape -n 100000 distr/ttf/FiraCode-Regular.ttf "Hello +++ /// !== <-> world" 46 | ``` 47 | 48 | Setup: 49 | 50 | ``` 51 | HarfBuzz 2.6.4 52 | 3,2 GHz 6-Core Intel Core i7 53 | MacOS 10.15.3 54 | ``` 55 | 56 | Results: 57 | 58 | ``` 59 | Baseline 0.407s 60 | Spacers 1.415s 61 | Lookups 2.080s 62 | Ignores 2.656s 63 | ``` -------------------------------------------------------------------------------- /extras/arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/arrows.png -------------------------------------------------------------------------------- /extras/arrows_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/arrows_es.png -------------------------------------------------------------------------------- /extras/arrows_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/arrows_pt.png -------------------------------------------------------------------------------- /extras/character_variants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/character_variants.png -------------------------------------------------------------------------------- /extras/character_variants_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/character_variants_es.png -------------------------------------------------------------------------------- /extras/character_variants_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/character_variants_pt.png -------------------------------------------------------------------------------- /extras/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/console.png -------------------------------------------------------------------------------- /extras/console_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/console_es.png -------------------------------------------------------------------------------- /extras/console_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/console_pt.png -------------------------------------------------------------------------------- /extras/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/download.png -------------------------------------------------------------------------------- /extras/download_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/download_es.png -------------------------------------------------------------------------------- /extras/download_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/download_pt.png -------------------------------------------------------------------------------- /extras/ligature_variants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligature_variants.png -------------------------------------------------------------------------------- /extras/ligature_variants_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligature_variants_es.png -------------------------------------------------------------------------------- /extras/ligature_variants_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligature_variants_pt.png -------------------------------------------------------------------------------- /extras/ligatures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligatures.png -------------------------------------------------------------------------------- /extras/ligatures_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligatures_es.png -------------------------------------------------------------------------------- /extras/ligatures_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/ligatures_pt.png -------------------------------------------------------------------------------- /extras/math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/math.png -------------------------------------------------------------------------------- /extras/math_es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/math_es.png -------------------------------------------------------------------------------- /extras/math_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/math_pt.png -------------------------------------------------------------------------------- /extras/progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/progress.gif -------------------------------------------------------------------------------- /extras/progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/progress.png -------------------------------------------------------------------------------- /extras/progress_es.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/progress_es.gif -------------------------------------------------------------------------------- /extras/progress_pt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/progress_pt.gif -------------------------------------------------------------------------------- /extras/samples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/samples.png -------------------------------------------------------------------------------- /extras/samples2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonsky/FiraCode/7c5fc86cfe1e4d17778ed7100fb6bd108dc5236f/extras/samples2.png -------------------------------------------------------------------------------- /extras/showcases.txt: -------------------------------------------------------------------------------- 1 | .= ..= := ::= =:= __ 2 | == != === !== =/= =!= 3 | 4 | <-< <<- <-- <- <-> -> --> ->> >-> 5 | <=< <== <<->> <=> => ==> =>> >=> 6 | >>- >- <~> -< -<< =<< 7 | <-| <=| /\ \/ |-> |=> 8 | <~~ <~ ~~ ~> ~~> 9 | 10 | <<< << <= <> >= >> >>> 11 | {. {| [| |] |} .} 12 | <:> >:< >:> <:< :>: :<: :> :< >: <: 13 | <||| <|| <| <|> |> ||> |||> 14 | 15 | <$ <$> $> 16 | <+ <+> +> 17 | <* <*> *> 18 | 19 | \n \\ /* */ /// // 20 | --> /> 21 | 0xF www Fl Tl Il fi fj 22 | 23 | ;; :: ::: !! ?? %% && 24 | || .. ... ..< .? ?. 25 | -- --- ++ +++ ** *** 26 | 27 | =~ !~ ~- -~ ~@ 28 | ^= ?= /= /== 29 | -| _|_ |- ||- 30 | #! #= ## ### #### 31 | #{ #[ ]# #( #? #_ #_( 32 | 33 | # Context-aware alignment 34 | 35 | fii fjj 36 | a*b a*A B*b A*B *a *A a* A* 37 | a-b a-A B-b A-B -a -A a- A- 38 | a+b a+A B+b A+B +a +A a+ A+ 39 | a:b a:A B:b A:B :a :A a: A: 40 | 41 | # Powerline 42 | 43 |        44 | 45 | # Stylistic sets 46 | 47 | r 0 123456789 & && $ <$ <$> $> @ <= >= 48 | 49 | # Unicode 50 | 51 |        52 | ⌀ ⌃ ⌄ ⌅ ⌆ ⌘ ⌤ ⌥ ⎇ ⎋ ⏏ ⎈ ✓ ⌂ ⇪ ⌧ ⌫ ⌦ ⌨ ⏎ � 53 | ☐ ☑ ☒ ■ □ ▢ ▣ ▤ ▦ ▧ ▨ ▩ ◧ ◨ ◩ ◪ ◫ ◰ ◱ ◲ ◳ 54 | ⊜ 🄍 🄎 🄏 🅭 🅮 🅯 🆭 55 | ⟲ ⟳ ⟰ ⟱ ⟴ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ↩ ↪ ⇞ ⇟ ⇤ ⇥ ↰ ↱ ↲ ↳ ❰ ❱ 56 |             57 | 58 | ≢ ẞ ᐅ ᐊ ∴ ∵ ⎈ ‖ ∧ ∨ ⊢ ⊣ ⊤ ⊥ ⊦ ⊧ ⊨ ⊩ ⊪ ⊫ ⊬ ⊭ ⊮ ⊯ 59 | ⟲ ⟳ ⟰ ⟱ ⟴ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ 60 | ↩ ⇞ ⇟ ⇤ ⇥ ⌀ ⌃ ⌄ ⌅ ⌆ ⌘ ⌤ ⌥ ⎇ ⎋ ⏏ ✓ ☐ ☑ ☒ ▤ ▦ ▧ ▨ ▩ 61 | ␆ ␈ ␇ ␣ ␢ ␘ ␍ ␐ ␡ ␥ ␔ ␑ ␓ ␒ ␙ ␃ ␄ ␗ ␅ ␛ ␜ ␌ ␝ ␉ ␊ ␕ ␤ ␀ ␞ ␏ ␎ ␠ ␁ ␂ ␚ ␦ ␖ ␟ ␋ 62 | ℂ ℍ ℕ ℙ ℚ ℝ ℤ 𝔹 ∀ ∃ ∄ ∅ ⊂ ⊃ ⊄ ⊅ ⊆ ⊇ ⊈ ⊉ ⊊ ⊋ ∈ ∉ ∊ ∋ ∌ ∍ ∪ ∩ 63 | ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ 「a」 「a」 64 | 65 | # Box drawing 66 | 67 | ╭╌╌╌╌╮ ╭┄┄┄┄╮ ╭┈┈┈┈╮ 68 | ╎ ╏ ┆ ┇ ┊ ┋ 69 | ╎ ╏ ┆ ┇ ┊ ┋ 70 | ╰╍╍╍╍╯ ╰┅┅┅┅╯ ╰┉┉┉┉╯ 71 | 72 | ┌─┬─┐ ╔╦═╗ ┏━┳┓ ╒═╤═╗ ╭─┰─╮ ○ ○ ◆ ◆ 73 | ├─┼─┤ ╠╬═╣ ┣━╋┫ ├─┼─╢ ┝━╋━┥ ╲ ╱ ╳ 74 | └─┴─┘ ╚╩═╝ ┗━┻┛ ╘═╧═╝ ╰─┸─╯ ■ ◆ ◆ 75 | 76 | # Blocks 77 | 78 | |███ | 50% 79 | 80 | ▖ ▗ ▙ ▚ ▛ ▜ ▞ ▟ 81 | 82 | ▁▂▃▄▅▆▇█▀▔ 83 | ▏ 84 | ▎ 85 | ▍ 86 | ▌ 87 | ▋ 88 | ▊ 89 | ▉ 90 | ▐ 91 | ▕ 92 | 93 | # Multi-line brackets 94 | 95 | ⎛ 1 ⎞ ⎡ a ⎤ ⎧ x ⎫ 96 | ⎜ 2 ⎟ ⎢ b ⎥ ⎪ y ⎪ 97 | ⎜ 3 ⎟ ⎢ c ⎥ ⎨ z ⎬ 98 | ⎜ 4 ⎟ ⎢ d ⎥ ⎪ y ⎪ 99 | ⎝ 5 ⎠ ⎣ e ⎦ ⎩ x ⎭ 100 | 101 | # Stylistic sets 102 | 103 | cv01 a 104 | cv02 g 105 | cv03..06 i 106 | cv07..10 l 107 | ss01 r 108 | zero, cv11..13 0 109 | cv14 3 110 | onum 0123456789 111 | cv17 ~ 112 | ss05 @ 113 | ss04 $ 114 | cv18 % 115 | ss03 & 116 | cv15..16 * 117 | cv31 () 118 | cv29 {} 119 | cv30 | 120 | 121 | ss02 <= >= 122 | cv19..20 <= 123 | cv23 >= 124 | cv21..22 =< 125 | ss08 == === != !== 126 | cv24 /= 127 | ss09 >>= <<= ||= |= 128 | cv25 .- 129 | cv26 :- 130 | cv32 .= 131 | cv27 [] 132 | cv28 {. .} 133 | ss06 \\ 134 | ss07 =~ !~ 135 | ss10 Fl Tl fi fj fl ft 136 | 137 | # Arbitrary-length arrows #346 138 | 139 | <---------------------------------------------<< 140 | <- <-- <--- <---- ----> ---> --> -> 141 | >- >-- >--- >---- ----< ---< --< -< 142 | |- |-- |--- |---- ----| ---| --| -| 143 | <<- <<-- <<--- <<---- ---->> --->> -->> ->> 144 | >>- >>-- >>--- >>---- ----<< ---<< --<< -<< 145 | ||- ||-- ||--- ||---- ----|| ---|| --|| -|| 146 | ----- ----< ---<< ----> --->> ----| ---|| 147 | <---- <---< <--<< <---> <-->> <---| <--|| --<-- 148 | <<--- <<--< <<-<< <<--> <<->> <<--| <<-|| -<<- 149 | >---- >---< >--<< >---> >-->> >---| >--|| -->-- 150 | >>--- >>--< >>-<< >>--> >>->> >>--| >>-|| ->>- 151 | |---- |---< |--<< |---> |-->> |---| |--|| --|-- 152 | ||--- ||--< ||-<< ||--> ||->> ||--| ||-|| -||- 153 | |-<-<<->>->-|-||-| 154 | |--<--<<-->>-->--|--||--| 155 | |---<---<<--->>--->---|---||---| 156 | 157 | < -< --< ---< ----< 158 | <- -<- --<- ---<- ----<- 159 | <-- -<-- --<-- ---<-- ----<-- 160 | <--- -<--- --<--- ---<--- ----<--- 161 | <---- -<---- --<---- ---<---- ----<---- 162 | 163 | > -> --> ---> ----> 164 | >- ->- -->- --->- ---->- 165 | >-- ->-- -->-- --->-- ---->-- 166 | >--- ->--- -->--- --->--- ---->--- 167 | >---- ->---- -->---- --->---- ---->---- 168 | 169 | | -| --| ---| ----| 170 | |- -|- --|- ---|- ----|- 171 | |-- -|-- --|-- ---|-- ----|-- 172 | |--- -|--- --|--- ---|--- ----|--- 173 | |---- -|---- --|---- ---|---- ----|---- 174 | 175 | << -<< --<< ---<< ----<< 176 | <<- -<<- --<<- ---<<- ----<<- 177 | <<-- -<<-- --<<-- ---<<-- ----<<-- 178 | <<--- -<<--- --<<--- ---<<--- ----<<--- 179 | <<---- -<<---- --<<---- ---<<---- ----<<---- 180 | 181 | >> ->> -->> --->> ---->> 182 | >>- ->>- -->>- --->>- ---->>- 183 | >>-- ->>-- -->>-- --->>-- ---->>-- 184 | >>--- ->>--- -->>--- --->>--- ---->>--- 185 | >>---- ->>---- -->>---- --->>---- ---->>---- 186 | 187 | || -|| --|| ---|| ----|| 188 | ||- -||- --||- ---||- ----||- 189 | ||-- -||-- --||-- ---||-- ----||-- 190 | ||--- -||--- --||--- ---||--- ----||--- 191 | ||---- -||---- --||---- ---||---- ----||---- 192 | 193 | <<< -<<< --<<< ---<<< ----<<< 194 | <<<- -<<<- --<<<- ---<<<- ----<<<- 195 | <<<-- -<<<-- --<<<-- ---<<<-- ----<<<-- 196 | <<<--- -<<<--- --<<<--- ---<<<--- ----<<<--- 197 | <<<---- -<<<---- --<<<---- ---<<<---- ----<<<---- 198 | 199 | >>> ->>> -->>> --->>> ---->>> 200 | >>>- ->>>- -->>>- --->>>- ---->>>- 201 | >>>-- ->>>-- -->>>-- --->>>-- ---->>>-- 202 | >>>--- ->>>--- -->>>--- --->>>--- ---->>>--- 203 | >>>---- ->>>---- -->>>---- --->>>---- ---->>>---- 204 | 205 | ||| -||| --||| ---||| ----||| 206 | |||- -|||- --|||- ---|||- ----|||- 207 | |||-- -|||-- --|||-- ---|||-- ----|||-- 208 | |||--- -|||--- --|||--- ---|||--- ----|||--- 209 | |||---- -|||---- --|||---- ---|||---- ----|||---- 210 | 211 | # Equal-based arrows 212 | 213 | <====================================================<< 214 | <= <== <=== <==== ====> ===> ==> => 215 | >= >== >=== >==== ====< ===< ==< =< 216 | |= |== |=== |==== ====| ===| ==| =| 217 | <<= <<== <<=== <<==== ====>> ===>> ==>> =>> 218 | >>= >>== >>=== >>==== ====<< ===<< ==<< =<< 219 | ||= ||== ||=== ||==== ====|| ===|| ==|| =|| 220 | ===== ====< ===<< ====> ===>> ====| ===|| ====/ 221 | <==== <===< <==<< <===> <==>> <===| <==|| <===/ ==<== 222 | <<=== <<==< <<=<< <<==> <<=>> <<==| <<=|| <<==/ =<<= 223 | >==== >===< >==<< >===> >==>> >===| >==|| >===/ ==>== 224 | >>=== >>==< >>=<< >>==> >>=>> >>==| >>=|| >>==/ =>>= 225 | |==== |===< |==<< |===> |==>> |===| |==|| |===/ ==|== 226 | ||=== ||==< ||=<< ||==> ||=>> ||==| ||=|| ||==/ =||= 227 | /==== /===< /==<< /===> /==>> /===| /==|| /===/ ==/== 228 | |=<=<<=>>=>=|=||=/=:=!=| 229 | |==<==<<==>>==>==|==||==/==:==!==| 230 | |===<===<<===>>===>===|===||===/===:===!===| 231 | 232 | < =< ==< ===< ====< 233 | <= =<= ==<= ===<= ====<= 234 | <== =<== ==<== ===<== ====<== 235 | <=== =<=== ==<=== ===<=== ====<=== 236 | <==== =<==== ==<==== ===<==== ====<==== 237 | 238 | > => ==> ===> ====> 239 | >= =>= ==>= ===>= ====>= 240 | >== =>== ==>== ===>== ====>== 241 | >=== =>=== ==>=== ===>=== ====>=== 242 | >==== =>==== ==>==== ===>==== ====>==== 243 | 244 | | =| ==| ===| ====| 245 | |= =|= ==|= ===|= ====|= 246 | |== =|== ==|== ===|== ====|== 247 | |=== =|=== ==|=== ===|=== ====|=== 248 | |==== =|==== ==|==== ===|==== ====|==== 249 | 250 | / =/ ==/ ===/ ====/ 251 | /= =/= ==/= ===/= ====/= 252 | /== =/== ==/== ===/== ====/== 253 | /=== =/=== ==/=== ===/=== ====/=== 254 | /==== =/==== ==/==== ===/==== ====/==== 255 | 256 | : =: ==: ===: ====: 257 | := =:= ==:= ===:= ====:= 258 | :== =:== ==:== ===:== ====:== 259 | :=== =:=== ==:=== ===:=== ====:=== 260 | :==== =:==== ==:==== ===:==== ====:==== 261 | 262 | ! =! ==! ===! ====! 263 | != =!= ==!= ===!= ====!= 264 | !== =!== ==!== ===!== ====!== 265 | !=== =!=== ==!=== ===!=== ====!=== 266 | !==== =!==== ==!==== ===!==== ====!==== 267 | 268 | << =<< ==<< ===<< ====<< 269 | <<= =<<= ==<<= ===<<= ====<<= 270 | <<== =<<== ==<<== ===<<== ====<<== 271 | <<=== =<<=== ==<<=== ===<<=== ====<<=== 272 | <<==== =<<==== ==<<==== ===<<==== ====<<==== 273 | 274 | >> =>> ==>> ===>> ====>> 275 | >>= =>>= ==>>= ===>>= ====>>= 276 | >>== =>>== ==>>== ===>>== ====>>== 277 | >>=== =>>=== ==>>=== ===>>=== ====>>=== 278 | >>==== =>>==== ==>>==== ===>>==== ====>>==== 279 | 280 | || =|| ==|| ===|| ====|| 281 | ||= =||= ==||= ===||= ====||= 282 | ||== =||== ==||== ===||== ====||== 283 | ||=== =||=== ==||=== ===||=== ====||=== 284 | ||==== =||==== ==||==== ===||==== ====||==== 285 | 286 | // =// ==// ===// ====// 287 | //= =//= ==//= ===//= ====//= 288 | //== =//== ==//== ===//== ====//== 289 | //=== =//=== ==//=== ===//=== ====//=== 290 | //==== =//==== ==//==== ===//==== ====//==== 291 | 292 | :: =:: ==:: ===:: ====:: 293 | ::= =::= ==::= ===::= ====::= 294 | ::== =::== ==::== ===::== ====::== 295 | ::=== =::=== ==::=== ===::=== ====::=== 296 | ::==== =::==== ==::==== ===::==== ====::==== 297 | 298 | !! =!! ==!! ===!! ====!! 299 | !!= =!!= ==!!= ===!!= ====!!= 300 | !!== =!!== ==!!== ===!!== ====!!== 301 | !!=== =!!=== ==!!=== ===!!=== ====!!=== 302 | !!==== =!!==== ==!!==== ===!!==== ====!!==== 303 | 304 | <<< =<<< ==<<< ===<<< ====<<< 305 | <<<= =<<<= ==<<<= ===<<<= ====<<<= 306 | <<<== =<<<== ==<<<== ===<<<== ====<<<== 307 | <<<=== =<<<=== ==<<<=== ===<<<=== ====<<<=== 308 | <<<==== =<<<==== ==<<<==== ===<<<==== ====<<<==== 309 | 310 | >>> =>>> ==>>> ===>>> ====>>> 311 | >>>= =>>>= ==>>>= ===>>>= ====>>>= 312 | >>>== =>>>== ==>>>== ===>>>== ====>>>== 313 | >>>=== =>>>=== ==>>>=== ===>>>=== ====>>>=== 314 | >>>==== =>>>==== ==>>>==== ===>>>==== ====>>>==== 315 | 316 | ||| =||| ==||| ===||| ====||| 317 | |||= =|||= ==|||= ===|||= ====|||= 318 | |||== =|||== ==|||== ===|||== ====|||== 319 | |||=== =|||=== ==|||=== ===|||=== ====|||=== 320 | |||==== =|||==== ==|||==== ===|||==== ====|||==== 321 | 322 | /// =/// ==/// ===/// ====/// 323 | ///= =///= ==///= ===///= ====///= 324 | ///== =///== ==///== ===///== ====///== 325 | ///=== =///=== ==///=== ===///=== ====///=== 326 | ///==== =///==== ==///==== ===///==== ====///==== 327 | 328 | ::: =::: ==::: ===::: ====::: 329 | :::= =:::= ==:::= ===:::= ====:::= 330 | :::== =:::== ==:::== ===:::== ====:::== 331 | :::=== =:::=== ==:::=== ===:::=== ====:::=== 332 | :::==== =:::==== ==:::==== ===:::==== ====:::==== 333 | 334 | !!! =!!! ==!!! ===!!! ====!!! 335 | !!!= =!!!= ==!!!= ===!!!= ====!!!= 336 | !!!== =!!!== ==!!!== ===!!!== ====!!!== 337 | !!!=== =!!!=== ==!!!=== ===!!!=== ====!!!=== 338 | !!!==== =!!!==== ==!!!==== ===!!!==== ====!!!==== 339 | 340 | # Underscore lines 341 | 342 | _ __ ___ ____ 343 | _|_ __|_ _|__ __|__ 344 | _| |_ _||_ __| ___| |__ |___ 345 | 346 | # Numbersign lines 347 | 348 | # ## ### #### ##### ###### 349 | 350 | # Progress bars 351 | 352 | [...........] [-----------]  353 | [#..........] [>----------]  354 | [##.........] [=>---------]  355 | [###........] [==>--------]  356 | [####.......] [===>-------]  357 | [#####......] [====>------]  358 | [######.....] [=====>-----]  359 | [#######....] [======>----]  360 | [########...] [=======>---]  361 | [#########..] [========>--]  362 | [##########.] [=========>-]  363 | [###########] [==========>]  364 | 365 | # Sanity check 366 | 367 | - -- --- |> <| ||> <|| |||> <|||