diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..7f6ca67ac1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +on: + push: + branches: + - '*' + tags: + - '[0-9]+.[0-9]+' + paths: + - '.github/workflows/**' + - 'FiraCode.glyphs' + - 'requirements.txt' + - 'script/**' + +jobs: + build: + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Dependencies + run: ./script/bootstrap_linux.sh + - if: startsWith(github.ref, 'refs/tags/') + run: python3 ./script/update_version.py + - run: ./script/build.sh + - run: echo "hash=$(git rev-parse --short $GITHUB_SHA)" >> $GITHUB_ENV + - uses: actions/upload-artifact@v4 + with: + name: Fira_Code_${{ env.hash }} + path: distr + - if: startsWith(github.ref, 'refs/tags/') + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPOSITORY: ${{ github.repository }} + run: python3 ./script/release.py diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..da01dde127 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,26 @@ +on: + push: + branches: + - master + paths: + - 'Dockerfile' + - 'requirements.txt' + - 'script/bootstrap_linux.sh' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: docker/setup-qemu-action@v4 + - uses: docker/setup-buildx-action@v4 + - uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - uses: docker/build-push-action@v7 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: tonsky/firacode:latest diff --git a/.gitignore b/.gitignore index 510cfdf89c..eeba389e4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,21 @@ *.zip -FiraCode_liga.glyphs -FiraCode_mess.glyphs target clojure/*.edn -FiraCode\ (Autosaved).glyphs -.cpcache \ No newline at end of file +.cpcache +.repl-port +master_ufo +instance_ufo +venv +.DS_Store +*.numbers + +distr/*/ + +*.glyphs +!FiraCode.glyphs + +.idea +.fleet +*.iml +*.glyphspackage +.vibe \ No newline at end of file diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000..987e29c41c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,10 @@ +# This is the official list of project authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS.txt file. +# See the latter for an explanation. +# +# Names should be added to this file as: +# Name or Organization + +Mozilla Foundation (https://www.mozilla.org/en-US/contact/) +Telefonica S.A. +Nikita Prokopov (niki@tonsky.me) github.com/tonsky diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a4844dcb7..1541226b45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,205 @@ All notable changes to this project will be documented in this file. +### 7.0 + +- Fixed overlap in U+2573 ╳ #1414 + +### 6.2 + +- Fixed monospaced property #1325 + +### 6.1 + +- Fixed hinting settings to match Glyphs export #1315 + +### 6.0 + +Unicode: + +- Fixed height of `∑` U+2211 N-ARY SUMMATION #1083 +- Added U+2241..U+224B `≁ ≂ ≃ ≄ ≅ ≆ ≇ ≉ ≊ ≋` #1090 +- Added new enclosed characters from Unicode 13 U+0229C `⊜`, U+1F10D `🄍`, U+1F10E `🄎`, U+1F10F `🄏`, U+1F16D `🅭`, U+1F16E `🅮`, U+1F16F `🅯`, U+1F1AD `🆭` #1070 +- Redrew U+27F0..U+27FF Supplemental Arrows-A to be strict monospace `⟲⟳⟴⟵⟶⟷⟸⟹⟺⟻⟼⟽⟾⟿` #1109 #1123 +- Added U+220E End of Proof `∎` #1115 +- Added U+FFFD Replacement Character `�` #1137, thanks @gjvnq +- Added U+EE00..U+EE0B Progress Bar `` #1182 +- Added U+2237 Proportion `∷` #1219 +- Added U+21AA Rightwards Arrow with Hook `↪` #1307 + +Changed: + +- Fixed weird look of `::<` `::>` `<::` `>::` #1145 +- `---` now makes a line #1190 + +Removed: + +- C-style compound assignment `>>=` `<<=` `||=` `|=` are not combined with equal sign by default. Old behavior is moved into `ss09` #974 +- Restored short `|` by default, long one moved to `cv30` #843 #1160 +- Moved `.-` into `cv25` #670 #860 #1103 +- Moved `.=` into `cv32` #670 +- Removed named “Retina” instance from FiraCode-VF.ttf (you can still get it by setting `wght=450`) #1318 + +Added (variants): + +- Alternative `a` `cv01` #949 +- Alternative `g` `cv02` #886 +- Alternative `i` `cv03`-`cv06` +- Alternative `l` `cv07`-`cv10` #899 +- Alternative `0` `cv11`-`cv13` +- Alternative `3` `cv14` +- Top-aligned `*` `cv15` +- Hexagonal `*` `cv16` #708 #1134 +- Top-aligned `~` `cv17` +- Alternative `%` `cv18` +- `<=` with a horizontal bar `cv19` +- `<=` as an arrow `cv20` #34 #696 #858 +- `=<` as less than or equal `cv21` #34 +- `=<` as less than or equal with horizontal bar `cv22` #34 +- `>=` with a horizontal bar `cv23` +- `/=` as not equals `cv24` #125 +- Added `:-` to `cv26` #790 +- Returned `[]` as `cv27` +- Returned `{. .}` as `cv28` #875 #635 #409 #279 #264 #214 +- Alternative `{}` `cv29` +- Returned full ligatures for `Fl` `Tl` `fi` `fj` `fl` `ft` as `ss10` +- Alternative `()` `cv31` #1198 + +#### 5.2 (June 12, 2020) + +- Fixed hinting problems caused by build_ttf #1075 + +#### 5.1 (June 10, 2020) + +- Fixed monospace property broken by adding threeemdash #1073 + +#### 5.0 (June 8, 2020) + +- Fixed Box drawing diagonal lines U+2571 `╱` U+2572 `╲` U+2573 `╳` #929 +- Added U+2236 Ratio `∶` #926 +- Added U+2E3A 2-em dash `⸺`, U+2E3B 3-em dash `⸻` #1019 +- Fixed arrows next to lowercase letters #1049 #1059 +- Vertically-aligned colons, greater/less signs #980 #1061 +- Make U+2388 Helm Symbol `⎈` single-width #1036 +- Disable `=/` because of conflicts with paths `PATH=/...` #1056 +- Fixed STAT table in FiraCode-VF.ttf #770 #1054 +- Added `//=` `=//` `=//=` #816 +- Added U+21B0..U+21B3 `↰ ↱ ↲ ↳`, U+2770..U+2771 `❰ ❱` #1032 +- Fixed U+27F8 `⟸` U+27F9 `⟹` U+27FA `⟺` U+27FD `⟽` U+27FE `⟾` U+27FF `⟿` that were broken in v4 #1067 +- Added `ss08` that adds gaps to `==` `===` `!=` `!==` #187 #383 +- Removed OTF from distr to avoid confusion #939 + +#### 4.0 (May 18, 2020) + +Removed 44 individual arrow ligatures, replaced with four universal, combinative substitutions. 100-150% faster shaping performance, infinite amount of arrow combinations. + +- Arbitrary-long combinative hyphen-based arrows #346 #494 #713 #826 #968 #983 #1029 +- Arbitrary-long combinative equal-based arrows #229 #234 #346 #494 #698 #826 #919 #931 #946 #948 #968 #1016 #1018 #1022 +- Arbitrary-long underscores #120 #269 #346 #494 +- Arbitrary-long numbersign sequences #1014 +- Fixed descender in U+040F `Џ` +- Undid #995 and properly fixed U+04CB `Ӌ`, U+04CC `ӌ` #1001 and U+0449 `щ` #1007 +- Added `|||` to prevent partial ligatures in `|||-|||` `|||=|||` #346 + +#### 3.1 (April 15, 2020) + +- Fixed width of Germandbls, cornerbracketleft, cornerbracketleft, negativeAcknowledge-control, cornerbracketleft.half, cornerbracketright.half [#1000] +- Fixed misplaced descenders on U+04B3 `ҳ` U+04CB `Ӌ` and U+04CC `ӌ` [#995] +- Fixed U+03F4 `ϴ` [#996] +- Fixed U+0314 COMBINING REVERSED COMMA ABOVE [#997] + +#### 3.0 (April 9, 2020) + +- Disabled ligatures in progress bars `[-> [--> [---> [=> [==> [===>` [#968] +- Added set letters U+2102 `ℂ` U+210D `ℍ` U+2115 `ℕ` U+2119 `ℙ` U+211A `ℚ` U+211D `ℝ` U+2124 `ℤ` and U+1D539 `𝔹` [#841] +- Removed `?:` [#970] +- Added missing set operations U+2200 `∀` U+2203..U+2205 `∃ ∄ ∅` U+2207 `∇` U+2282..U+228B `⊂ ⊃ ⊄ ⊅ ⊆ ⊇ ⊈ ⊉ ⊊ ⊋` U+2208..U+220# `∈ ∉ ∊ ∋ ∌ ∍` U+222A `∪` [#822] +- Added U+300C U+300D Corner brackets `「」` and U+FF62 U+FF63 Halfwidth Corner brackets `「」` [#940] +- Added `<<->>` [#919] +- Disabled `fl` `Fl` `Tl` ligatures, adjusted `l` height in combination with `[F T I f]` instead [#902] +- Added U+25A4..25A9 Squares with fill `▤▥▦▧▨▩` [#450] +- Slightly tuned multiple ampersands in `ss03` [#831] +- Fixed horizontal bar height in ` + +``` + +```css +/* CSS */ +@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); +``` + +```css +/* Especificar en el CSS */ +code { font-family: 'Fira Code', monospace; } + +@supports (font-variation-settings: normal) { + code { font-family: 'Fira Code VF', monospace; } +} +``` + +- IE 10+, Edge Legacy: activar con `font-feature-settings: "calt";` +- Firefox +- Safari +- Navegadores basados en Chromium (Chrome, Opera) +- ACE +- CodeMirror (activar con `font-variant-ligatures: contextual;`) + +### Proyectos que usan Fira Code + +- [CodePen](https://codepen.io/) +- [Blink Shell](http://www.blink.sh/) +- [Klipse](http://app.klipse.tech/) +- [IlyaBirman.net](http://ilyabirman.net/) +- [EvilMartians.com](https://evilmartians.com/) +- [FromScratch](https://fromscratch.rocks/) +- [PEP20.org](https://pep20.org/) + +### Alternativas + +Fuentes monoespaciadas con ligaduras gratuitas: + +- [Hasklig](https://github.com/i-tu/Hasklig) +- [Monoid](http://larsenwork.com/monoid/) +- [Fixedsys Excelsior](https://github.com/kika/fixedsys) +- [Iosevka](https://be5invis.github.io/Iosevka/) +- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) +- [Victor Mono](https://rubjo.github.io/victor-mono/) +- [Cascadia Code](https://github.com/microsoft/cascadia-code) +- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) + +Fuentes monoespaciadas con ligaduras no gratuitas: + +- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) +- [Mono Lisa](https://www.monolisa.dev/) + +### Compilando Fira Code localmente + +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: + +```bash +# instalar las herramientas requeridas para la compilación +./script/bootstrap_macos.sh + +# compilar los archivos de la fuente +./script/build.sh + +# instalar los OTFs en ~/Library/Fonts +cp distr/otf/*.otf ~/Library/Fonts +``` + +Alternativamnete, se puede compilar Fira Code usando Docker: + +```bash +# instalar las dependencias en un contenedor y compilar los archivos de la fuente +make + +# comprimir los archivos de la fuente en dist/ a un zip +make package +``` + +### Créditos + +- Autor: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) +- Basado en: [Fira Mono](https://github.com/mozilla/Fira) +- Inspirado por: [Hasklig](https://github.com/i-tu/Hasklig) diff --git a/LEIAME.md b/LEIAME.md new file mode 100644 index 0000000000..76368bce60 --- /dev/null +++ b/LEIAME.md @@ -0,0 +1,271 @@ +## Fira Code: uma fonte monoespaçada gratuita com ligaduras de programação +![Fira Code](./extras/logo.svg) + +Leia em: [English](./README.md) | [Español](./LEEME.md) | [简体中文](./README_CN.md) | [日本語](./README_JA.md) + +### Problema + +Os programadores usam muitos símbolos, frequentemente codificados com vários caracteres. Para a mente humana, sequências como `->`, `<=` ou `:=` são tokens lógicos únicos, mesmo que ocupem dois ou três caracteres na tela. Seus olhos gastam uma quantidade quase nula de energia para escanear, analisar e unir vários caracteres num único caractere lógico. Idealmente, todas as linguagens de programação deveriam ser projetadas com símbolos Unicode completos para operadores, mas este ainda não é o caso. + +### Solução + +Fira Code é uma fonte monoespaçada gratuita que contém ligaduras para combinações comuns de vários caracteres na programação. É apenas um recurso de renderização de fonte: o código subjacente permanece compatível com ASCII. Isso ajuda com a ler e entender o código mais rapidamente. Para algumas sequências frequentes, como `..` ou `//`, as ligaduras nos permitem corrigir o espaçamento. + +### Baixar e instalar + +Fira_Code_v6.2.zip - 6 de dezembro de 2021 - 2.5 MB + +E então, consulte: + +- [Como instalar](https://github.com/tonsky/FiraCode/wiki) +- [Solução de problemas](https://github.com/tonsky/FiraCode/wiki#troubleshooting) +- [Novidades e atualizações](https://twitter.com/FiraCode) + +### O que o acompanha? + +À esquerda: as ligaduras conforme renderizadas no Fira Code. À direita: as mesmas sequências de caracteres sem ligaduras. + + + +Fira Code vem com uma grande variedade de setas. Melhor ainda: você pode deixá-las do tamanho que quiser e combinar os fragmentos de início, meio e fim como preferir! + + + +Fira Code não é só sobre ligaduras. A pontuação e pares de letras frequentes também contam com alguns ajustes finos. + + + +Fira Code vem com algumas variantes de caracteres diferentes (`cv01`, `cv02` etc.), conjuntos de estilo (`ss01`, `ss02` etc.) e outros recursos de fonte (`zero`, `onum`, `calt` etc.) para que todos possam escolher o que é melhor para si. [Veja como habilitar](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets). + + + +Algumas ligaduras podem ser alteradas ou habilitadas usando conjuntos de estilo ou variantes de caracteres: + + + +Por ser uma fonte de programação, o Fira Code possui um suporte fantástico para desenhar ASCII ou caixas, *powerline* e outras formas de IU do console: + + + +Fira Code é a primeira fonte de programação a oferecer glifos dedicados para renderizar barras de progresso: + + + +Em ação: + + + +Esperamos que mais fontes de programação adotem esta convenção e lancem suas próprias versões. + +A cobertura Unicode torna o Fira Code uma ótima escolha para escrita matemática: + + + +### Como se parece? + + + + +### Lista de editores compatíveis + +| Funciona | Não funciona | +|----------|--------------| +| **Arduino IDE** (2.0+, segue as mesmas
instruções do [vscode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | **Adobe Dreamweaver** | +| **Abricotine** | **Delphi IDE** | +| **Android Studio** (2.3+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([solução alternativa](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | +| **Anjuta** (a menos que no EOF) | **IDLE** | +| **AppCode** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **KDevelop 4** | +| **Atom** 1.1 ou mais recente ([instruções](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Monkey Studio IDE** | +| **BBEdit** (14.6+ [instruções](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **UltraEdit** (Windows) | +| **Brackets** (com [este plugin](https://github.com/polo2ro/firacode-in-brackets)) | +| **Chocolat** | +| **CLion** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Cloud9** ([instruções](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | +| **Coda 2** | +| **CodeLite** | +| **CodeRunner** | +| **Comma** (Em: Preferências > Editor > Fonte) | +| **CotEditor** | +| **Eclipse** | +| **EditPad** | +| **elementary Code** | +| **Geany** (1.37+) | +| **gEdit / Pluma** | +| **GNOME Builder** | +| **Godot** | +| **GoormIDE** ([instruções](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | +| **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | +| **IntelliJ IDEA** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Kate, KWrite** | +| **KDevelop 5+** | +| **Komodo** | +| **Leafpad** | +| **LibreOffice** | +| **LightTable** ([instruções](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | +| **LINQPad** | +| **MacVim** 7.4 ou mais recente ([instruções](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | +| **Mancy** | +| **MATLAB** ([instruções](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | +| **Meld** | +| **Mousepad** | +| **NeoVim-gtk** | +| **NetBeans** | +| **Notepad** (Windows) | +| **Notepad++** ([instruções](https://github.com/tonsky/FiraCode/issues/1555)) | +| **Notepad3** ([instruções](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| +| **Nova** | +| **PhpStorm** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **PyCharm** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **QOwnNotes** (21.16.6+) | +| **QtCreator** | +| **Rider** | +| **RStudio** ([instruções](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | +| **RubyMine** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Scratch** | +| **Scribus** (1.5.3+) | +| **SublimeText** (3146+) | +| **Spyder IDE** (apenas com Qt5) | +| **SuperCollider 3** | +| **TeXShop**| +| **TextAdept** (Linux, macOS) | +| **TextEdit** | +| **TextMate 2** | +| **UltraEdit (UEX)** (Linux) | +| **VimR** ([instruções](https://github.com/qvacua/vimr/wiki#ligatures)) | +| **Visual Studio** (2015+, [instruções](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | +| **Visual Studio Code** ([instruções](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | +| **WebStorm** (2016.2+, [instruções](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Xamarin Studio/Monodevelop** | +| **Xcode** (8.0+, caso contrário, [com plugin](https://github.com/robertvojta/LigatureXcodePlugin)) | +| **Xi** | +| Provavelmente funciona: **Smultron, Vico** | Em questão: **Code::Blocks IDE** | + +### Lista de terminais compatíveis + +| Funciona | Não funciona | +|----------|--------------| +| crosh ([instruções](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | +| Ghostty | Asbru Connection Manager | +| Hyper (veja [#3607](https://github.com/vercel/hyper/issues/3607)) | Cmder | +| iTerm 2 | ConEmu | +| Kitty | GNOME Terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/192)) | +| Konsole | gtkterm ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Mintty | guake ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| QTerminal | LXTerminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| st ([correção](https://st.suckless.org/patches/ligatures/)) | mate-terminal | +| Tabby | PuTTY | +| Terminal.app | rxvt | +| Termux | sakura ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Token2Shell | SecureCRT +| Wez’s terminal | Terminator ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Windows Terminal | terminology | +| ZOC (macOS) | Tilix | +| | Windows Console | +| | xfce4-terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| | xterm | +| | ZOC (Windows) | + +### Suporte com navegadores + +```html + + +``` + +```css +/* CSS */ +@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); +``` + +```css +/* Especifique em CSS */ +code { font-family: 'Fira Code', monospace; } + +@supports (font-variation-settings: normal) { + code { font-family: 'Fira Code VF', monospace; } +} +``` + +- IE 10+, Edge Legacy: habilite com `font-feature-settings: "calt";` +- Firefox +- Safari +- Navegadores baseados em Chromium (Chrome, Opera) +- ACE +- CodeMirror (habilite com `font-variant-ligatures: contextual;`) + +### Projetos usando Fira Code + +- [CodePen](https://codepen.io/) +- [Blink Shell](http://www.blink.sh/) +- [Klipse](http://app.klipse.tech/) +- [IlyaBirman.net](http://ilyabirman.net/) +- [EvilMartians.com](https://evilmartians.com/) +- [FromScratch](https://fromscratch.rocks/) +- [PEP20.org](https://pep20.org/) + +### Alternativas + +Fontes monoespaçadas gratuitas com ligaduras: + +- [Hasklig](https://github.com/i-tu/Hasklig) +- [Monoid](http://larsenwork.com/monoid/) +- [Fixedsys Excelsior](https://github.com/kika/fixedsys) +- [Iosevka](https://be5invis.github.io/Iosevka/) +- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) +- [Victor Mono](https://rubjo.github.io/victor-mono/) +- [Cascadia Code](https://github.com/microsoft/cascadia-code) +- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) + +Fontes monoespaçadas pagas com ligaduras: + +- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) +- [Mono Lisa](https://www.monolisa.dev/) + +### Construir o Fira Code localmente + +Caso deseje alterar os FiraCode.glyphs e construir você mesmo os arquivos OTF/TTF/WOFF, essa é a configuração que eu uso no macOS: + +```bash +# instala todas as ferramentas necessárias para construir +./script/bootstrap_macos.sh + +# constrói os arquivos de fonte +./script/build.sh + +# instala os OTFs em ~/Library/Fonts +cp distr/otf/*.otf ~/Library/Fonts +``` + +De forma alternativa, você pode construir o Fira Code usando o Docker: + +```bash +# instala as dependências num contêiner e constrói os arquivos de fonte +make + +# compacta os arquivos de fonte do dist/ em um zip +make package +``` + +Se você quiser *habilitar permanentemente* certos conjuntos de estilos ou variações de caracteres, talvez porque o editor de sua escolha não permita que você os alterne individualmente, você pode fornecer os recursos desejados em uma lista separada por vírgulas para o script de compilação por meio da flag `-f / --features`.
Padrão: nenhum. + +Para separar diferentes versões da sua fonte, você pode especificar o nome da família da fonte desejada com a flag `-n / --family-name`. O valor especial 'features' adicionará uma lista de recursos habilitados ordenada e separada por espaços ao nome da família padrão.
Padrão: "Fira Code" + +Você também pode limitar a espessura da fonte que será criada com a opção `-w / --weights`.
Padrão: "Light,Regular,Retina,Medium,SemiBold,Bold" + +```bash +# localmente no seu shell +./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" + +# ou por meio de um contêiner docker (cria um nome de família 'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero') +docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" + +# no Git Bash do Git for Windows, ou qualquer outro shell baseado em MSYS2, talvez seja necessário desabilitar a conversão de caminho +MSYS2_ARG_CONV_EXCL="*" docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "ss02,ss03,ss04,ss05,ss06,ss07" +``` + +### Créditos + +- Autor: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) +- Baseado em: [Fira Mono](https://github.com/mozilla/Fira) +- Inspirado por: [Hasklig](https://github.com/i-tu/Hasklig) +- Traduzido por: Kauan Farias [@kau19an](https://github.com/kau19an) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 1c6fccfe7c..805e0b38b5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,13 +1,4 @@ -Copyright (c) 2014, Nikita Prokopov http://tonsky.me -with Reserved Font Name Fira Code. - -Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ -with Reserved Font Name Fira Sans. - -Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ -with Reserved Font Name Fira Mono. - -Copyright (c) 2014, Telefonica S.A. +Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode) This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..d0509e7300 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: build + +build: + docker run --rm -v ${PWD}:/opt tonsky/firacode:latest ./script/build.sh + +package: + ./script/package.sh diff --git a/README.md b/README.md index 60c57485f8..3d7ef4a4ad 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,104 @@ -## Fira Code: monospaced font with programming ligatures +## Fira Code: free monospaced font with programming ligatures - +![Fira Code](./extras/logo.svg) + +Read in [Español](./LEEME.md) | [简体中文](./README_CN.md) | [日本語](./README_JA.md) | [Português brasileiro](./LEIAME.md) ### Problem -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. +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. ### Solution -#### [Download v1.206](https://github.com/tonsky/FiraCode/releases/download/1.206/FiraCode_1.206.zip) · [How to install](https://github.com/tonsky/FiraCode/wiki) · [Troubleshooting](https://github.com/tonsky/FiraCode/wiki#troubleshooting) · [News & updates](https://twitter.com/FiraCode) +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. + +### Download & Install - +Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB -Fira Code is an extension of the Fira Mono font containing a set of 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. +Then: - +- [How to Install](https://github.com/tonsky/FiraCode/wiki) +- [Troubleshooting](https://github.com/tonsky/FiraCode/wiki#troubleshooting) +- [News & Updates](https://twitter.com/FiraCode) -### Code examples +### What’s in the box? -Ruby: +Left: ligatures as rendered in Fira Code. Right: same character sequences without ligatures. - + -JavaScript: +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! - + -PHP: +Fira Code is not only about ligatures. Some fine-tuning is done for punctuation and frequent letter pairs. - + -Erlang: +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) - + -Elixir: +Some ligatures can be altered or enabled using stylistic sets/character variants: - + -Go: +Being a programming font, Fira Code has fantastic support for ASCII/box drawing, powerline, and other forms of console UIs: - + -LiveScript: +Fira Code is the first programming font to offer dedicated glyphs to render progress bars: - + -Clojure: +In action: - + -Swift: +We hope more programming fonts will adopt this convention and ship their own versions. Implementation detail: there is no way for programs to detect whether a font has progress bar glyphs at U+EE00, so they need to decide what to output without knowing if it will be rendered properly or not. We propose a new environment variable, `UNICODE_PROGRESS_BAR=true`, to use as a heuristic. If present, it’s safe to assume U+EE00..EE0B will be rendered properly. - +Unicode coverage makes Fira Code a great choice for mathematical writing: + -### Terminal support +### How does it look? -| Works | Doesn’t work | -| ------------------ | ------------------ | -| **Butterfly** | **Alacritty** | -| **Hyper.app** | **cmd.exe** | -| **iTerm 2** ([3.1+](https://gitlab.com/gnachman/iterm2/issues/3568#note_13118332)) | **Cmder** | -| **Kitty** | **ConEmu** | -| **Konsole** | **GNOME Terminal** | -| **mintty** ([2.8.3+](https://github.com/mintty/mintty/issues/601))| **mate-terminal** | -| **QTerminal** | **PuTTY** | -| **Terminal.app** | **rxvt** | -| **Termux** | **ZOC** (Windows) | -| **Token2Shell/MD** | **gtkterm, guake, LXTerminal, sakura, Terminator, xfce4-terminal,** and other libvte-based terminals ([bug report](https://bugzilla.gnome.org/show_bug.cgi?id=584160)) | -| **upterm** | -| **ZOC** (macOS) | + + -### Editor support +### Editor compatibility list | Works | Doesn’t work | -| ----- | -------------- | -| **Abricotine** | **Arduino IDE** | -| **Android Studio** (2.3+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **Adobe Dreamweaver** | -| **Anjuta** (unless at the EOF) | **Delphi IDE** | -| **AppCode** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **Eclipse** (Win, [vote here](https://bugs.eclipse.org/bugs/show_bug.cgi?id=398656)) | -| **Atom** 1.1 or newer ([instructions](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | Standalone **Emacs** ([workaround](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | -| **BBEdit/TextWrangler** (v. 11 only, [instructions](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **gVim** (Windows [workaround](https://github.com/tonsky/FiraCode/issues/462)) | -| **Brackets** (with [this plugin](https://github.com/polo2ro/firacode-in-brackets)) | **IDLE** | -| **Chocolat** | **KDevelop 4** | -| **CLion** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | **Monkey Studio IDE** | -| **Cloud9** ([instructions](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | | -| **Coda 2** | | -| **CodeLite** | | -| **Eclipse** (Mac 4.7+, Linux) | | -| **elementary Code** | | -| **Geany** | +|-------|----------------| +| **Arduino IDE** (2.0+,same instructions as [vscode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | **Adobe Dreamweaver** | +| **Abricotine** | **Delphi IDE** | +| **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)) | +| **Anjuta** (unless at the EOF) | **IDLE** | +| **AppCode** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **KDevelop 4** | +| **Atom** 1.1 or newer ([instructions](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Monkey Studio IDE** | +| **BBEdit** (14.6+ [instructions](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **UltraEdit** (Windows) | +| **Brackets** (with [this plugin](https://github.com/polo2ro/firacode-in-brackets)) | +| **Chocolat** | +| **CLion** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Cloud9** ([instructions](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | +| **Coda 2** | +| **CodeLite** | +| **CodeRunner** | +| **Comma** (Under: Preferences > Editor > Font) | +| **CotEditor** | +| **Eclipse** | +| **EditPad** | +| **elementary Code** | +| **Geany** (1.37+) | | **gEdit / Pluma** | | **GNOME Builder** | -| **IntelliJ IDEA** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | +| **Godot** | +| **GoormIDE** ([instructions](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | +| **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | +| **IntelliJ IDEA** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | | **Kate, KWrite** | +| **KDevelop 5+** | | **Komodo** | | **Leafpad** | | **LibreOffice** | @@ -102,47 +106,89 @@ Swift: | **LINQPad** | | **MacVim** 7.4 or newer ([instructions](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | | **Mancy** | +| **MATLAB** ([instructions](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | | **Meld** | | **Mousepad** | | **NeoVim-gtk** | | **NetBeans** | -| **Notepad** (Win) | -| **Notepad++** (with a [workaround](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | -| **PhpStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | -| **PyCharm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | +| **Notepad** (Windows) | +| **Notepad++** ([instructions](https://github.com/tonsky/FiraCode/issues/1555)) | +| **Notepad3** ([instructions](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| +| **Nova** | +| **PhpStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **PyCharm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **QOwnNotes** (21.16.6+) | | **QtCreator** | | **Rider** | | **RStudio** ([instructions](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | -| **RubyMine** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | +| **RubyMine** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | | **Scratch** | +| **Scribus** (1.5.3+) | | **SublimeText** (3146+) | | **Spyder IDE** (only with Qt5) | | **SuperCollider 3** | -| **TextAdept** (Linux, Mac) | +| **TeXShop**| +| **TextAdept** (Linux, macOS) | | **TextEdit** | | **TextMate 2** | +| **UltraEdit (UEX)** (Linux) | | **VimR** ([instructions](https://github.com/qvacua/vimr/wiki#ligatures)) | -| **Visual Studio 2015** | -| **Visual Studio 2017** | +| **Visual Studio** (2015+, [instructions](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | | **Visual Studio Code** ([instructions](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | -| **WebStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/Intellij-products-instructions)) | +| **WebStorm** (2016.2+, [instructions](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | | **Xamarin Studio/Monodevelop** | | **Xcode** (8.0+, otherwise [with plugin](https://github.com/robertvojta/LigatureXcodePlugin)) | +| **Xi** | | Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | +| **Zed** ([instructions](https://zed.dev/docs/reference/all-settings#buffer-font-family)) | | + +### Terminal compatibility list + +| Works | Doesn’t work | +|-------|--------------| +| crosh ([instructions](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | +| Ghostty | Asbru Connection Manager | +| Hyper (see [#3607](https://github.com/vercel/hyper/issues/3607)) | Cmder | +| iTerm 2 | ConEmu | +| Kitty | GNOME Terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/192)) | +| Konsole | gtkterm ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Mintty | guake ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| QTerminal | LXTerminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| st ([patch](https://st.suckless.org/patches/ligatures/)) | mate-terminal | +| Tabby | PuTTY | +| Terminal.app | rxvt | +| Termux | sakura ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Token2Shell | SecureCRT +| Wez’s terminal | Terminator ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Windows Terminal | terminology | +| ZOC (macOS) | Tilix | +| | Windows Console | +| | xfce4-terminal ([ticket](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| | xterm | +| | ZOC (Windows) | ### Browser support ```html - + ``` ```css /* CSS */ -@import url(https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css); +@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); ``` -- IE 10+, Edge: enable with `font-feature-settings: "calt" 1;` +```css +/* Specify in CSS */ +code { font-family: 'Fira Code', monospace; } + +@supports (font-variation-settings: normal) { + code { font-family: 'Fira Code VF', monospace; } +} +``` + +- IE 10+, Edge Legacy: enable with `font-feature-settings: "calt";` - Firefox - Safari - Chromium-based browsers (Chrome, Opera) @@ -151,26 +197,73 @@ Swift: ### Projects using Fira Code -- All [JetBrains products](https://www.jetbrains.com/) - [CodePen](https://codepen.io/) - [Blink Shell](http://www.blink.sh/) - [Klipse](http://app.klipse.tech/) - [IlyaBirman.net](http://ilyabirman.net/) - [EvilMartians.com](https://evilmartians.com/) -- [Web Maker](https://webmakerapp.com/) - [FromScratch](https://fromscratch.rocks/) - [PEP20.org](https://pep20.org/) ### Alternatives -Other monospaced fonts with ligatures: +Free monospaced fonts with ligatures: + +- [Hasklig](https://github.com/i-tu/Hasklig) +- [Monoid](http://larsenwork.com/monoid/) +- [Fixedsys Excelsior](https://github.com/kika/fixedsys) +- [Iosevka](https://be5invis.github.io/Iosevka/) +- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) +- [Victor Mono](https://rubjo.github.io/victor-mono/) +- [Cascadia Code](https://github.com/microsoft/cascadia-code) +- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) + +Paid monospaced fonts with ligatures: + +- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) +- [Mono Lisa](https://www.monolisa.dev/) + +### Building Fira Code locally + +In case you want to alter FiraCode.glyphs and build OTF/TTF/WOFF files yourself, this is the setup I use on macOS: + +```bash +# install all required build tools +./script/bootstrap_macos.sh + +# build the font files +./script/build.sh -- [Hasklig](https://github.com/i-tu/Hasklig) (free) -- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) (€59) -- [Monoid](http://larsenwork.com/monoid/) (free) -- [Fixedsys Excelsior](https://github.com/kika/fixedsys) (free) -- [Iosevka](https://be5invis.github.io/Iosevka/) (free) -- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) (free) +# install OTFs to ~/Library/Fonts +cp distr/otf/*.otf ~/Library/Fonts +``` + +Alternatively, you can build Fira Code using Docker: + +```bash +# install dependencies in a container and build the font files +make + +# package the font files from dist/ into a zip +make package +``` + +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. + +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" + +You can also limit the font weights that will be created with the `-w / --weights` option.
Default: "Light,Regular,Retina,Medium,SemiBold,Bold" + +```bash +# locally in your shell +./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" + +# or via a docker container (creates the family name 'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero') +docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" + +# in Git Bash from Git for Windows, or any other MSYS2 based shell, you might need to disable path conversion +MSYS2_ARG_CONV_EXCL="*" docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "ss02,ss03,ss04,ss05,ss06,ss07" +``` ### Credits diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000000..72ac63ee54 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,261 @@ +## Fira Code: 免费的编程连字等宽字体 + +![Fira Code](./extras/logo.svg) + +### 问题 + +开发者们使用的多标记,通常都是用几个字符编码。对于人的大脑来说,像`->`、`<=`或`:=`这样的序列是单一的逻辑标记,即使它们在屏幕上显示两到三个字符。您的眼睛并非无消耗的来扫描、解析并将多个字符连接到一个逻辑字符中。理想情况下,所有编程语言都应该为操作符设计成熟的Unicode符号,但现在还不是这样。 + +### 解决方案 + +Fira Code是一种免费的等宽字体,包含常用的编程语言中多种字符组合的连字。这只是一个字体呈现功能,底层代码仍然与ASCII兼容。这有助于更快地阅读和理解代码。对于一些常见的序列,如`..`或`//`,连字允许我们纠正间距。 + +### 下载和安装 + +Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB + +下一步: + +- [如何安装](https://github.com/tonsky/FiraCode/wiki) +- [疑难解答](https://github.com/tonsky/FiraCode/wiki#troubleshooting) +- [相关新闻](https://twitter.com/FiraCode) + +### 字体里都有哪些特征? + +左侧:Fira Code中呈现的连字。右侧:没有连字的相同字符序列。 + + + +Fira Code 带有种类繁多的箭头。更棒的是:您可以随心所欲地制作它们,并根据需要组合开始/中间/结束片段! + + + +Fira Code 不仅与连字有关,还对标点符号和频繁的字母对进行了一些微调。 + + + +Fira Code 带有各种各样的箭头,更棒的是,您可以随心所欲地制作它们,并且可以任意组合开始/中间/结束片段![如何启用](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) + + + +可以使用样式集/字符变体更改或启用某些连字: + + + +作为一种编程字体,Fira Code 对 ASCII/框绘图、powerline和其他形式的控制台 UI 具有出色的支持: + + + +Fira Code 是第一个提供专用字形来渲染进度条的编程字体: + + + +在运行中: + + + +我们希望更多的编程字体能够采用这个约定并发布自己的版本。 + +Unicode 覆盖使 Fira Code 成为数学写作的绝佳选择: + + + +### 它看起来怎样? + + + + +### 编辑器兼容性列表 + +| 支持 | 不支持 | +|-------|----------------| +| **Abricotine** | **Arduino IDE** | +| **Android Studio** (2.3+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **Adobe Dreamweaver** | +| **Anjuta** (除非在 EOF) | **Delphi IDE** | +| **AppCode** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([解决方法](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | **IDLE** | +| **Atom** 1.1 或更新版本 ([说明](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **KDevelop 4** | +| **BBEdit** (14.6+, [说明](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **Monkey Studio IDE** | +| **Brackets** (使用 [此插件](https://github.com/polo2ro/firacode-in-brackets)) | +| **Chocolat** | **UltraEdit** | +| **CLion** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Cloud9** ([说明](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | +| **Coda 2** | +| **CodeLite** | +| **CodeRunner** | +| **Comma** (在 首选项 > 编辑器 > 字体 中) | +| **CotEditor** | +| **Eclipse** | +| **elementary Code** | +| **Geany** (1.37+) | +| **gEdit / Pluma** | +| **GNOME Builder** | +| **Godot** | +| **GoormIDE** ([说明](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | +| **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | +| **IntelliJ IDEA** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Kate, KWrite** | +| **KDevelop 5+** | +| **Komodo** | +| **Leafpad** | +| **LibreOffice** | +| **LightTable** ([说明](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | +| **LINQPad** | +| **MacVim** 7.4 或更新版本 ([说明](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | +| **Mancy** | +| **MATLAB** ([说明](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | +| **Meld** | +| **Mousepad** | +| **NeoVim-gtk** | +| **NetBeans** | +| **Notepad** (Windows) | +| **Notepad++** ([解决方法](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | +| **Notepad3** ([说明](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| +| **Nova** | +| **PhpStorm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **PyCharm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **QOwnNotes** (21.16.6+) | +| **QtCreator** | +| **Rider** | +| **RStudio** ([说明](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | +| **RubyMine** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Scratch** | +| **Scribus** (1.5.3+) | +| **SublimeText** (3146+) | +| **Spyder IDE** (仅适用于 Qt5) | +| **SuperCollider 3** | +| **TeXShop**| +| **TextAdept** (Linux, macOS) | +| **TextEdit** | +| **TextMate 2** | +| **VimR** ([说明](https://github.com/qvacua/vimr/wiki#ligatures)) | +| **Visual Studio** (2015+, [说明](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | +| **Visual Studio Code** ([说明](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | +| **WebStorm** (2016.2+, [说明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Xamarin Studio/Monodevelop** | +| **Xcode** (8.0+, 否则 [使用插件](https://github.com/robertvojta/LigatureXcodePlugin)) | +| **Xi** | +| Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | + +### 终端兼容性列表 + +| 支持 | 不支持 | +|-------|--------------| +| crosh ([说明](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | +| Hyper (参见 [#3607](https://github.com/vercel/hyper/issues/3607)) | Cmder | +| iTerm 2 | ConEmu | +| Kitty | GNOME Terminal | +| Konsole | gtkterm ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Mintty | guake ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| QTerminal | LXTerminal ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| st ([补丁](https://st.suckless.org/patches/ligatures/)) | mate-terminal | +| Terminal.app | PuTTY | +| Termux | rxvt | +| Token2Shell | sakura ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Wez’s terminal | Terminator ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Windows Terminal | terminology | +| ZOC (macOS) | Windows Console | +| | xfce4-terminal ([需求](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| | xterm | +| | ZOC (Windows) | + +### 浏览器支持 + +```html + + +``` + +```css +/* CSS */ +@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); +``` + +```css +/* Specify in CSS */ +code { font-family: 'Fira Code', monospace; } + +@supports (font-variation-settings: normal) { + code { font-family: 'Fira Code VF', monospace; } +} +``` + +- IE 10+, Edge Legacy: 启用 `font-feature-settings: "calt";` +- Firefox +- Safari +- Chromium-based browsers (Chrome, Opera) +- ACE +- CodeMirror (enable with `font-variant-ligatures: contextual;`) + +### 使用 Fira Code的项目 + +- [CodePen](https://codepen.io/) +- [Blink Shell](http://www.blink.sh/) +- [Klipse](http://app.klipse.tech/) +- [IlyaBirman.net](http://ilyabirman.net/) +- [EvilMartians.com](https://evilmartians.com/) +- [FromScratch](https://fromscratch.rocks/) +- [PEP20.org](https://pep20.org/) + +### 备选方案 + +带连字的免费等宽字体: + +- [Hasklig](https://github.com/i-tu/Hasklig) +- [Monoid](http://larsenwork.com/monoid/) +- [Fixedsys Excelsior](https://github.com/kika/fixedsys) +- [Iosevka](https://be5invis.github.io/Iosevka/) +- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) +- [Victor Mono](https://rubjo.github.io/victor-mono/) +- [Cascadia Code](https://github.com/microsoft/cascadia-code) +- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) + +带连字的付费等宽字体: + +- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) +- [Mono Lisa](https://www.monolisa.dev/) + +### 在本地构建 Fira Code + +如果您想更改 FiraCode.glyphs 并自己构建 OTF / TTF / WOFF 文件,这是我在 macOS 上使用的设置: + +```bash +# 安装所有编译需要的工具 +./script/bootstrap_macos.sh + +# 编译字体文件 +./script/build.sh + +# 将otf文件安装到 ~/Library/Fonts +cp distr/otf/*.otf ~/Library/Fonts +``` + +或者,您可以使用 Docker 构建 Fira Code: + +```bash +# install dependencies in a container and build the font files +make + +# package the font files from dist/ into a zip +make package +``` + +如果你想要*永久开启*某个特定的文体集或者字符变种,但你的编辑器有可能不允许你单独开启它们,你可以将你想要的功能作为一个用逗号分隔的列表,通过 `-f / --features` 标志来加入到编译脚本中。
默认:无。 + +要分隔不同的字体版本的话,你可以用 `-n / --family-name` 标志来指定你所需的字体系列名称。特殊值 'features' 将在默认的系列名称后面添加一个有序的、空格分隔的列表,列表内为已经启用的功能。
默认:"Fira Code" + +你也可以用 `-w / --weights` 选项来限制将要被编译的字体的重量。
默认:"Light,Regular,Retina,Medium,SemiBold,Bold" + +```bash +# 在你本地的shell中 +./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" + +# 或者通过一个docker容器 (创建系列名为:'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero') +docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" +``` + +### 制作人员 + +- 作者: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) +- 基于此项目: [Fira Mono](https://github.com/mozilla/Fira) +- 灵感来源: [Hasklig](https://github.com/i-tu/Hasklig) +- 翻译:墨抒颖[@moshuying](https://github.com/moshuying) diff --git a/README_JA.md b/README_JA.md new file mode 100644 index 0000000000..d5c2345d43 --- /dev/null +++ b/README_JA.md @@ -0,0 +1,270 @@ +## Fira Code: プログラミング合字のフリー等幅フォント + +![Fira Code](./extras/logo.svg) + +[English](./README.md) | [Español](./LEEME.md) | [简体中文](./README_CN.md) で読む | [Português brasileiro](./LEIAME.md) + +### 問題点 + +プログラマは多くの記号を使用し、しばしば数文字で符号化されます。人間の脳にとって`->`、`<=`、`:=`といったシーケンスは、たとえ画面上で 2 文字や 3 文字になったとしても、単一の論理トークンである。あなたの目は、複数の文字をスキャンし、解析し、1 つの論理的なものに結合するために、ゼロではない量のエネルギーを費やしているのです。理想を言えば、すべてのプログラミング言語が演算子のための本格的なユニコード記号を備えて設計されるべきですが、まだそうではありません。 + +### 解決法 + +Fira Code は、一般的なプログラミングの複数文字の組み合わせのための合字を含む無料の等幅フォントです。これは単にフォントのレンダリング機能であり、基礎となるコードは ASCII 互換のままです。これによりコードをより速く読み、理解することができます。`...` や `//` のような頻度の高い文字列は、合字によって間隔を修正することができます。 + +### ダウンロードとインストール + +Fira_Code_v6.2.zip - December 6, 2021 - 2.5 MB + +次は: + +- [インストール方法](https://github.com/tonsky/FiraCode/wiki) +- [トラブルシューティング](https://github.com/tonsky/FiraCode/wiki#troubleshooting) +- [ニュースとアップデート](https://twitter.com/FiraCode) + +### 何が入っているのでしょうか? + +左: Fira Code で描画される合字。右: 合字のない同じ文字列。 + + + +Fira Code には、膨大な種類の矢印が用意されています。さらに、好きな長さにしたり、始点・中間・終点の断片を自由に組み合わせたりすることができます! + + + +Fira Code は合字だけではありません。句読点や頻度の高い文字ペアについても、いくつかの微調整が行われています。 + + + +Fira Code には、数種類の文字バリエーション(`cv01`、`cv02` など)、スタイルセット(`ss01`、`ss02` など)、その他のフォント機能(`zero`、`onum`、`calt` など)があり、誰もが自分に最適なものを選ぶことができます。[有効にする方法](https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets) + + + +一部の合字は、スタイルセット/文字バリアントを使用して変更または有効にすることができます: + + + +プログラミング用フォントである Fira Code は、ASCII/ボックスドローイング、パワーライン、その他の形式のコンソール UI に素晴らしい対応をしています: + + + +Fira Code は、プログレスバーを描画するための専用グリフを提供する最初のプログラミングフォントです: + + + +動作すると: + + + +より多くのプログラミング用フォントがこの規約を採用し、独自のバージョンを出荷することを望んでいます。 + +ユニコード対応により、Fira Code は数学の記述に最適です: + + + +### どのように見えるのでしょうか? + + + + +### エディタ互換性リスト + +| サポート | 非サポート | +|-------|----------------| +| **Arduino IDE** (2.0+,same instructions as [vscode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | **Adobe Dreamweaver** | +| **Abricotine** | **Delphi IDE** | +| **Android Studio** (2.3+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | Standalone **Emacs** ([回避方法](https://github.com/tonsky/FiraCode/wiki/Emacs-instructions)) | +| **Anjuta** (unless at the EOF) | **IDLE** | +| **AppCode** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | **KDevelop 4** | +| **Atom** 1.1 or newer ([説明](https://github.com/tonsky/FiraCode/wiki/Atom-instructions)) | **Monkey Studio IDE** | +| **BBEdit** (14.6+ [説明](https://github.com/tonsky/FiraCode/wiki/BBEdit-instructions)) | **UltraEdit** (Windows) | +| **Brackets** (with [this plugin](https://github.com/polo2ro/firacode-in-brackets)) | +| **Chocolat** | +| **CLion** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Cloud9** ([説明](https://github.com/tonsky/FiraCode/wiki/Cloud9-Instructions)) | +| **Coda 2** | +| **CodeLite** | +| **CodeRunner** | +| **Comma** (Under: Preferences > Editor > Font) | +| **CotEditor** | +| **Eclipse** | +| **elementary Code** | +| **Geany** (1.37+) | +| **gEdit / Pluma** | +| **GNOME Builder** | +| **Godot** | +| **GoormIDE** ([説明](https://github.com/tonsky/FiraCode/wiki/GoormIDE-Instructions)) | +| **gVim** ([Windows](https://github.com/tonsky/FiraCode/issues/462), [GTK](https://vimhelp.org/options.txt.html#%27guiligatures%27)) | +| **IntelliJ IDEA** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Kate, KWrite** | +| **KDevelop 5+** | +| **Komodo** | +| **Leafpad** | +| **LibreOffice** | +| **LightTable** ([説明](https://github.com/tonsky/FiraCode/wiki/LightTable-instructions)) | +| **LINQPad** | +| **MacVim** 7.4 or newer ([説明](https://github.com/tonsky/FiraCode/wiki/MacVim-instructions)) | +| **Mancy** | +| **MATLAB** ([説明](https://github.com/tonsky/FiraCode/wiki/MATLAB-for-Windows-Instructions)) | +| **Meld** | +| **Mousepad** | +| **NeoVim-gtk** | +| **NetBeans** | +| **Notepad** (Windows) | +| **Notepad++** ([回避方法](https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2287#issuecomment-256638098)) | +| **Notepad3** ([説明](https://github.com/rizonesoft/Notepad3/issues/361#issuecomment-365977420))| +| **Nova** | +| **PhpStorm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **PyCharm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **QOwnNotes** (21.16.6+) | +| **QtCreator** | +| **Rider** | +| **RStudio** ([説明](https://github.com/tonsky/FiraCode/wiki/RStudio-instructions)) | +| **RubyMine** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Scratch** | +| **Scribus** (1.5.3+) | +| **SublimeText** (3146+) | +| **Spyder IDE** (Qt5 のみ) | +| **SuperCollider 3** | +| **TeXShop**| +| **TextAdept** (Linux, macOS) | +| **TextEdit** | +| **TextMate 2** | +| **UltraEdit (UEX)** (Linux) | +| **VimR** ([説明](https://github.com/qvacua/vimr/wiki#ligatures)) | +| **Visual Studio** (2015+, [説明](https://github.com/tonsky/FiraCode/wiki/Visual-Studio-Instructions)) | +| **Visual Studio Code** ([説明](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions)) | +| **WebStorm** (2016.2+, [説明](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions)) | +| **Xamarin Studio/Monodevelop** | +| **Xcode** (8.0+, それ以外は[プラグイン付き](https://github.com/robertvojta/LigatureXcodePlugin)) | +| **Xi** | +| Probably work: **Smultron, Vico** | Under question: **Code::Blocks IDE** | + +### ターミナル互換性リスト + +| サポート | 非サポート | +|-------|--------------| +| crosh ([説明](https://github.com/tonsky/FiraCode/wiki/ChromeOS-Terminal)) | Alacritty | +| Hyper ([#3607](https://github.com/vercel/hyper/issues/3607) を確認) | Asbru Connection Manager | +| iTerm 2 | Cmder | +| Kitty | ConEmu | +| Konsole | GNOME Terminal | +| Mintty | gtkterm ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| QTerminal | guake ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| st ([パッチ](https://st.suckless.org/patches/ligatures/)) | LXTerminal ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Tabby | mate-terminal | +| Terminal.app | PuTTY | +| Termux | rxvt | +| Token2Shell | sakura ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| Wez’s terminal | SecureCRT +| Windows Terminal | Terminator ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| ZOC (macOS) | terminology | +| | Tilix | +| | Windows Console | +| | xfce4-terminal ([チケット](https://gitlab.gnome.org/GNOME/vte/-/issues/1661)) | +| | xterm | +| | ZOC (Windows) | + +### ブラウザサポート + +```html + + +``` + +```css +/* CSS */ +@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css); +``` + +```css +/* Specify in CSS */ +code { font-family: 'Fira Code', monospace; } + +@supports (font-variation-settings: normal) { + code { font-family: 'Fira Code VF', monospace; } +} +``` + +- IE 10+, Edge Legacy: `font-feature-settings: "calt";` で有効にします +- Firefox +- Safari +- Chromium-based browsers (Chrome, Opera) +- ACE +- CodeMirror (`font-variant-ligatures: contextual;` で有効にします) + +### Fira Code を使用したプロジェクト + +- [CodePen](https://codepen.io/) +- [Blink Shell](http://www.blink.sh/) +- [Klipse](http://app.klipse.tech/) +- [IlyaBirman.net](http://ilyabirman.net/) +- [EvilMartians.com](https://evilmartians.com/) +- [FromScratch](https://fromscratch.rocks/) +- [PEP20.org](https://pep20.org/) + +### 代替品 + +合字のある無料等幅フォント: + +- [Hasklig](https://github.com/i-tu/Hasklig) +- [Monoid](http://larsenwork.com/monoid/) +- [Fixedsys Excelsior](https://github.com/kika/fixedsys) +- [Iosevka](https://be5invis.github.io/Iosevka/) +- [DejaVu Sans Code](https://github.com/SSNikolaevich/DejaVuSansCode) +- [Victor Mono](https://rubjo.github.io/victor-mono/) +- [Cascadia Code](https://github.com/microsoft/cascadia-code) +- [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) + +合字のある有償等幅フォント: + +- [PragmataPro](http://www.fsd.it/fonts/pragmatapro.htm) +- [Mono Lisa](https://www.monolisa.dev/) + +### Fira Code をローカルでビルドする + +FiraCode.glyphs を変更し、OTF/TTF/WOFF ファイルを自分でビルドしたい場合、私が macOS で使用している設定は次のとおりです: + +```bash +# 必要なビルドツールをすべてインストール +./script/bootstrap_macos.sh + +# フォントファイルのビルド +./script/build.sh + +# OTF を ~/Library/Fonts にインストール +cp distr/otf/*.otf ~/Library/Fonts +``` + +または、Docker を使用して Fira Code を構築することもできます: + +```bash +# コンテナ内に依存関係をインストールし、フォントファイルをビルド +make + +# dist/ のフォントファイルを zip にまとめる +make package +``` + +特定のスタイルセットやキャラクタバリエーションを *永久的に* 有効にしたい場合、おそらくあなたの選んだエディタではこれらを個別に切り替えることができないため、`-f / --features` フラグでビルドスクリプトにカンマ区切りリストとして希望の機能を提供することができます。
デフォルト: なし。 + +異なるバージョンのフォントを分けるために、`-n / --family-name` フラグで希望のフォントファミリー名を指定することができます。特別な値 'features' を指定すると、有効な機能をソートしてスペースで区切ったリストをデフォルトのファミリー名に追加します。
デフォルト: "Fira Code" + +また、`-w / --weights` オプションで、作成されるフォントのウェイトを制限することができます。
デフォルト: "Light,Regular,Retina,Medium,SemiBold,Bold" + +```bash +# ローカルでシェル内 +./script/build.sh --features "ss02,ss08,ss10,cv03,cv07,cv14" --family-name "Fira Code straight" --weights "Regular,Bold" + +# または Docker コンテナ経由(ファミリー名 'Fira Code cv01 cv02 cv06 cv31 onum ss01 ss03 ss04 zero' を作成) +docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "cv01,cv02,cv06,ss01,zero,onum,ss03,ss04,cv31" -n "features" + +# Git for Windows の Git Bash やその他の MSYS2 ベースのシェルで使用する場合は、パス変換を無効にする必要があるかもしれません +MSYS2_ARG_CONV_EXCL="*" docker run --rm -v "${PWD}":/opt tonsky/firacode:latest ./script/build.sh -f "ss02,ss03,ss04,ss05,ss06,ss07" +``` + +### クレジット + +- 作者: Nikita Prokopov [@nikitonsky](https://twitter.com/nikitonsky) +- 基にした: [Fira Mono](https://github.com/mozilla/Fira) +- インスパイアされた: [Hasklig](https://github.com/i-tu/Hasklig) diff --git a/classes/ClosingBracket.fea b/classes/ClosingBracket.fea new file mode 100644 index 0000000000..d46ab1df07 --- /dev/null +++ b/classes/ClosingBracket.fea @@ -0,0 +1 @@ +bracketright braceright parenright \ No newline at end of file diff --git a/classes/Digit.fea b/classes/Digit.fea new file mode 100644 index 0000000000..c34c1e95d8 --- /dev/null +++ b/classes/Digit.fea @@ -0,0 +1,13 @@ +zero +zero.zero +one +two +twoTurned +threeTurned +three +four +five +six +seven +eight +nine \ No newline at end of file diff --git a/classes/DigitTosf.fea b/classes/DigitTosf.fea new file mode 100644 index 0000000000..78e631ee50 --- /dev/null +++ b/classes/DigitTosf.fea @@ -0,0 +1,12 @@ +zero.tosf +zero.tosf.zero +zero.zero.tosf +one.tosf +two.tosf +three.tosf +four.tosf +five.tosf +six.tosf +seven.tosf +eight.tosf +nine.tosf \ No newline at end of file diff --git a/classes/HexDigit.fea b/classes/HexDigit.fea new file mode 100644 index 0000000000..f2931626b7 --- /dev/null +++ b/classes/HexDigit.fea @@ -0,0 +1 @@ +a b c d e f A B C D E F \ No newline at end of file diff --git a/classes/OpeningBracket.fea b/classes/OpeningBracket.fea new file mode 100644 index 0000000000..255be042e6 --- /dev/null +++ b/classes/OpeningBracket.fea @@ -0,0 +1 @@ +bracketleft braceleft parenleft \ No newline at end of file diff --git a/classes/Tall.fea b/classes/Tall.fea new file mode 100644 index 0000000000..5a50ea2eab --- /dev/null +++ b/classes/Tall.fea @@ -0,0 +1 @@ +@Uppercase zero one two twoTurned threeTurned three four five six seven eight nine @OpeningBracket @ClosingBracket bar \ No newline at end of file diff --git a/clojure/fira_code/calt.clj b/clojure/fira_code/calt.clj new file mode 100755 index 0000000000..a68476a090 --- /dev/null +++ b/clojure/fira_code/calt.clj @@ -0,0 +1,343 @@ +(ns fira-code.calt + (:require + [clojure.string :as str] + [fira-code.coll :as coll] + [fira-code.glyphs :as glyphs] + [fira-code.time :as time] + [flatland.ordered.map :refer [ordered-map]])) + +;; No ligature should follow those sequences +(def ignore-prefixes + [["parenleft" "question" "colon"] + ;; #578 #624 Regexp lookahead/lookbehind + ["parenleft" "question" "equal"] + ["parenleft" "question" "less" "equal"] + ["parenleft" "question" "exclam"] + ["parenleft" "question" "less" "exclam"] + ;; #850 PHP + ["less" "bar" "greater"] 0 + + ;; |||> ||> |> <| <|| <||| + ["bar" "bar" "bar" "greater"] 1 + ["bar" "bar" "greater"] 1 + ["bar" "greater"] 1 + ["less" "bar" "bar" "bar"] 1 + ["less" "bar" "bar"] 1 + ["less" "bar"] 1 + + ;; #346 We need << <<< >> >>> || ||| substituted before -- --- == === + ;; so that `ignore [less greater bar] hyphen hyphen` would not trigger + ["less" "less"] 2 + ["less" "less" "less"] 2 + ["greater" "greater"] 2 + ["greater" "greater" "greater"] 2 + ["bar" "bar"] 2 + ["bar" "bar" "bar"] 2}) + +(def ignores + (coll/multimap-by str + ["slash" "asterisk"] + (str + " ignore sub slash' asterisk slash;\n" + " ignore sub asterisk slash' asterisk;\n") + + ["asterisk" "slash"] + (str + " ignore sub slash asterisk' slash;\n" + " ignore sub asterisk' slash asterisk;\n") + + ["asterisk" "asterisk"] + (str + " ignore sub slash asterisk' asterisk;\n" + " ignore sub asterisk' asterisk slash;\n") + + ["asterisk" "asterisk" "asterisk"] + (str + " ignore sub slash asterisk' asterisk asterisk;\n" + " ignore sub asterisk' asterisk asterisk slash;\n") + + ;; #1061 + ["colon" "colon"] + (str + " ignore sub colon' colon [less greater];\n" + " ignore sub [less greater] colon' colon;\n") + + ["colon" "colon" "colon"] + (str + " ignore sub colon' colon colon [less greater];\n" + " ignore sub [less greater] colon' colon colon;\n") + + ;; #621 <||> + ["less" "bar" "bar"] + " ignore sub less' bar bar greater;\n" + + ["bar" "bar" "greater"] + " ignore sub less bar' bar greater;\n" + + ;; #593 {|} + ["braceleft" "bar"] + " ignore sub braceleft' bar braceright;\n" + + ["bar" "braceright"] + " ignore sub braceleft bar' braceright;\n" + + ;; #593 [|] + ["bracketleft" "bar"] + " ignore sub bracketleft' bar bracketright;\n" + + ["bar" "bracketright"] + " ignore sub bracketleft bar' bracketright;\n" + + ;; #410 <*>> <+>> <$>> + ["greater" "greater"] + " ignore sub [asterisk plus dollar] greater' greater;\n" + + ;; #410 <*>>> <+>>> <$>>> + ["greater" "greater" "greater"] + " ignore sub [asterisk plus dollar] greater' greater greater;\n" + + ;; #410 <<*> <<+> <<$> + ["less" "less"] + " ignore sub less' less [asterisk plus dollar];\n" + + ;; #410 <<<*> <<<+> <<<$> + ["less" "less" "less"] + " ignore sub less' less less [asterisk plus dollar];\n" + + ;; #948 [==[ ]==] + ;; #968 [== ==] + ["equal" "equal"] + (str + " ignore sub bracketleft equal' equal;\n" + " ignore sub equal' equal bracketright;\n") + + ;; #948 [===[ ]===] + ;; #968 [=== ===] + ["equal" "equal" "equal"] + (str + " ignore sub bracketleft equal' equal equal;\n" + " ignore sub equal' equal equal bracketright;\n") + + ;; #346 =:= + ["colon" "equal"] + " ignore sub equal colon' equal;\n" + + ;; #346 =!= + ["exclam" "equal"] + " ignore sub equal exclam' equal;\n" + ;; #346 =!== + ["exclam" "equal" "equal"] + " ignore sub equal exclam' equal equal;\n" + + ;; #346 =<= <=< <=> <=| <=: <=! <=/ + ["less" "equal"] + (str + " ignore sub equal less' equal;\n" + " ignore sub less' equal [less greater bar colon exclam slash];\n") + + ;; #548 >=< + ;; #346 =>= >=> >=< >=| >=: >=! >=/ + ["greater" "equal"] + (str + " ignore sub equal greater' equal;\n" + " ignore sub greater' equal [less greater bar colon exclam slash];\n") + + ;; #346 >>->> >>=>> + ;; #974 keep >>= + ["greater" "greater"] + (str + " ignore sub [hyphen equal] greater' greater;\n" + " ignore sub greater' greater hyphen;\n" + " ignore sub greater' greater equal [equal less greater bar colon exclam slash];\n") + + ;; #346 <<-<< <<=<< + ;; #974 keep <<= + ["less" "less"] + (str + " ignore sub [hyphen equal] less' less;\n" + " ignore sub less' less hyphen;\n" + " ignore sub less' less equal [equal less greater bar colon exclam slash];\n") + + ;; #346 ||-|| ||=|| + ;; #974 keep ||= + ["bar" "bar"] + (str + " ignore sub [hyphen equal] bar' bar;\n" + " ignore sub bar' bar hyphen;\n" + " ignore sub bar' bar equal [equal less greater bar colon exclam slash];\n") + + ;; #816 //= + ["slash" "slash"] + (str + " ignore sub equal slash' slash;\n" + " ignore sub slash' slash equal;\n") + + ;; #346 <--> >--< |--| + ["hyphen" "hyphen"] + (str + " ignore sub [less greater bar] hyphen' hyphen;\n" + " ignore sub hyphen' hyphen [less greater bar];\n") + + ;; #346 <==> >==< |==| /==/ =:== =!== ==:= ==!= + ["equal" "equal"] + (str + " ignore sub equal [colon exclam] equal' equal;\n" + " ignore sub [less greater bar slash] equal' equal;\n" + " ignore sub equal' equal [less greater bar slash] ;\n" + " ignore sub equal' equal [colon exclam] equal;\n") + + ;; #346 <===> >===< |===| /===/ =:=== =!=== ===:= ===!= + ["equal" "equal" "equal"] + (str + " ignore sub equal [colon exclam] equal' equal equal;\n" + " ignore sub [less greater bar slash] equal' equal equal;\n" + " ignore sub equal' equal equal [less greater bar slash];\n" + " ignore sub equal' equal equal [colon exclam] equal;\n") + )) + +;; DO NOT generate ignores at all +(def skip-ignores? #{ + ;; #410 <<*>> <<+>> <<$>> + ["less" "asterisk" "greater"] + ["less" "plus" "greater"] + ["less" "dollar" "greater"] + }) + +;; DO NOT generate ligature +(def manual? #{ + ;; /\ \/ + ["slash" "backslash"] + ["backslash" "slash"] + }) + +(defn liga->rule + "[f f i] => { [LIG LIG i] f_f_i.liga + [LIG f i] LIG + [ f f i] LIG }" + [liga] + (case (count liga) + 2 (let [[a b] liga] + (str/replace + (str + "lookup 1_2 {\n" + (when-not (skip-ignores? liga) + (str + " ignore sub 1 1' 2;\n" + " ignore sub 1' 2 2;\n")) + (gen-ignore-prefixes liga) + (get ignores liga) + " sub 1.spacer 2' by 1_2.liga;\n" + " sub 1' 2 by 1.spacer;\n" + ; "sub 1 2 by 1_2.liga;" + "} 1_2;") + #"\d" {"1" a "2" b})) + 3 (let [[a b c] liga] + (str/replace + (str + "lookup 1_2_3 {\n" + (when-not (skip-ignores? liga) + (str + " ignore sub 1 1' 2 3;\n" + " ignore sub 1' 2 3 3;\n")) + (gen-ignore-prefixes liga) + (get ignores liga) + " sub 1.spacer 2.spacer 3' by 1_2_3.liga;\n" + " sub 1.spacer 2' 3 by 2.spacer;\n" + " sub 1' 2 3 by 1.spacer;\n" + ; "sub 1 2 3 by 1_2_3.liga;" + "} 1_2_3;") + #"\d" {"1" a "2" b "3" c})) + 4 (let [[a b c d] liga] + (str/replace + (str + "lookup 1_2_3_4 {\n" + (when-not (skip-ignores? liga) + (str + " ignore sub 1 1' 2 3 4;\n" + " ignore sub 1' 2 3 4 4;\n")) + (gen-ignore-prefixes liga) + (get ignores liga) + " sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga;\n" + " sub 1.spacer 2.spacer 3' 4 by 3.spacer;\n" + " sub 1.spacer 2' 3 4 by 2.spacer;\n" + " sub 1' 2 3 4 by 1.spacer;\n" + ; "sub 1 2 3 4 by 1_2_3_4.liga;" + "} 1_2_3_4;") + #"\d" {"1" a "2" b "3" c "4" d})) + 5 (let [[a b c d e] liga] + (str/replace + (str + "lookup 1_2_3_4_5 {\n" + (when-not (skip-ignores? liga) + (str + " ignore sub 1 1' 2 3 4 5;\n" + " ignore sub 1' 2 3 4 4 5;\n")) + (gen-ignore-prefixes liga) + (get ignores liga) + " sub 1.spacer 2.spacer 3.spacer 4.spacer 5' by 1_2_3_4_5.liga;\n" + " sub 1.spacer 2.spacer 3.spacer 4' 5 by 4.spacer;\n" + " sub 1.spacer 2.spacer 3' 4 5 by 3.spacer;\n" + " sub 1.spacer 2' 3 4 5 by 2.spacer;\n" + " sub 1' 2 3 4 5 by 1.spacer;\n" + ; "sub 1 2 3 4 5 by 1_2_3_4_5.liga;" + "} 1_2_3_4_5;") + #"\d" {"1" a "2" b "3" c "4" d "5" e})) + )) + +(defn compare-ligas [l1 l2] + (let [p1 (priorities l1 Long/MAX_VALUE) + p2 (priorities l2 Long/MAX_VALUE) + pc (compare p1 p2) + c1 (count l1) + c2 (count l2) + cc (compare c1 c2)] + (cond + (not= 0 pc) pc ;; lower priority first + (not= 0 cc) (- cc) ;; longer first + :else (compare l1 l2)))) ;; alphabetical + +(defn replace-calt [font ligas] + (let [ligas' (->> ligas + (remove manual?) + (sort compare-ligas)) + calt (->> ligas' + (map liga->rule) + (str/join "\n\n")) + glyphs (map #(str (str/join "_" %) ".liga") ligas') + counts (coll/group-by-to count count ligas')] + + (when-some [unused (not-empty (reduce dissoc ignores ligas'))] + (println " WARN Unused ignores" (str/join " " (keys unused)))) + + (when-some [unused (not-empty (reduce disj skip-ignores? ligas'))] + (println " WARN Unused skip-ignores?" (str/join " " unused))) + + (when-some [unused (not-empty (reduce disj manual? ligas))] + (println " WARN Unused manual?" (str/join " " unused))) + + (println " generated calt:" + ; (str/join " " glyphs) + (str + #_"(" (get counts 2) " pairs, " + (get counts 3) " triples, " + (get counts 4) " quadruples, " + (count ligas') " total" #_")")) + + (glyphs/update-code font :features :tag "calt" (constantly calt)))) diff --git a/clojure/fira_code/checks.clj b/clojure/fira_code/checks.clj new file mode 100644 index 0000000000..8bcbaf9f47 --- /dev/null +++ b/clojure/fira_code/checks.clj @@ -0,0 +1,23 @@ +(ns fira-code.checks + (:require + [clojure.string :as str] + [fira-code.coll :as coll] + [fira-code.glyphs :as glyphs])) + +(defn width-ok? [w] + (#{"0" 0 1200} w)) + +(defn widths [font] + (doseq [g (:glyphs font) + :when (not= "0" (:export g)) + :let [[w & _ :as ws] (mapv :width (:layers g))]] + (when-not (apply = ws) + (println (str "WARN glyph '" (:glyphname g) "' has different widths=" (pr-str ws)))) + (when-not (width-ok? w) + (println (str "WARN glyph '" (:glyphname g) "' has unexpected width=" (pr-str w))))) + font) + +(defn -main [& args] + (let [path (or (first args) "FiraCode.glyphs") + font (glyphs/load path)] + (widths font))) diff --git a/clojure/fira_code/classes.clj b/clojure/fira_code/classes.clj new file mode 100644 index 0000000000..96bbb4d8b5 --- /dev/null +++ b/clojure/fira_code/classes.clj @@ -0,0 +1,18 @@ +(ns fira-code.classes + (:require + [clojure.java.io :as io] + [clojure.string :as str] + [fira-code.glyphs :as glyphs] + [fira-code.files :as files]) + (:import + [java.io File])) + +(defn fill-class [font file] + (let [[_ name] (re-matches #"([^.]+)\.fea" (File/.getName file)) + code (slurp file) + class {:code (str/trim code) + :name name}] + (glyphs/set-class font name class))) + +(defn fill-all [font] + (reduce fill-class font (files/find "classes" #"classes/[^/]+\.fea"))) diff --git a/clojure/fira_code/coll.clj b/clojure/fira_code/coll.clj new file mode 100644 index 0000000000..ebd8dc34c3 --- /dev/null +++ b/clojure/fira_code/coll.clj @@ -0,0 +1,22 @@ +(ns fira-code.coll) + +(defn index-of [pred xs] + (let [res (reduce (fn [i x] (if (pred x) (reduced i) (inc i))) 0 xs)] + (if (>= res (count xs)) + -1 + res))) + +(defn group-by-to [key-fn value-fn xs] + (reduce-kv + (fn [m k vs] + (assoc m k (value-fn vs))) + {} + (group-by key-fn xs))) + +(defn multimap-by [f & kvs] + (reduce + (fn [m [k v]] + (if (contains? m k) + (update m k f v) + (assoc m k v))) + {} (partition 2 kvs))) diff --git a/clojure/fira_code/features.clj b/clojure/fira_code/features.clj new file mode 100644 index 0000000000..e7a58aaea9 --- /dev/null +++ b/clojure/fira_code/features.clj @@ -0,0 +1,42 @@ +(ns fira-code.features + (:require + [clojure.java.io :as io] + [clojure.string :as str] + [fira-code.glyphs :as glyphs] + [fira-code.files :as files]) + (:import + [java.io File])) + +(defn trim [s] + (-> s + (str/replace #"(?m) +$" "") + (str/trim))) + +(defn append-calt [font] + (let [features (->> (files/find "features/calt" #"features/calt/[^/]+\.fea") + (map slurp) + (map trim) + (str/join "\n\n"))] + (println " appending to feature calt" (glyphs/lines features) "lines") + (glyphs/update-code font :features :tag "calt" #(str % "\n\n" features)))) + +(defn fill-feature [font file] + (let [[_ tag] (re-matches #"([^.]+)\.fea" (File/.getName file)) + code (slurp file) + [_ name code'] (re-matches #"(?s)###[ ]*([^\n]*[^\n ])[ ]*\n(.*)" code) + code (trim (or code' code)) + feature (cond-> {:code code} + (and (str/starts-with? tag "ss") name) + (assoc :labels + [{:language "dflt" + :value name}]) + true (assoc :tag tag))] + (glyphs/set-feature font tag feature))) + +(defn fill-features [font] + (reduce fill-feature font (files/find "features" #"features/[^/]+\.fea"))) + +(defn fill-all [font] + (-> font + (append-calt) + (fill-features))) diff --git a/clojure/fira_code/files.clj b/clojure/fira_code/files.clj new file mode 100644 index 0000000000..2e7dc4d107 --- /dev/null +++ b/clojure/fira_code/files.clj @@ -0,0 +1,13 @@ +(ns fira-code.files + (:refer-clojure :exclude [find]) + (:require + [clojure.java.io :as io] + [clojure.string :as str]) + (:import + [java.io File])) + +(defn find [path re] + (->> (file-seq (io/file path)) + (next) ;; skip directory itself + (filter #(re-matches re (File/.getPath %))) + (sort-by File/.getPath))) diff --git a/clojure/glyphs.clj b/clojure/fira_code/glyphs.clj similarity index 51% rename from clojure/glyphs.clj rename to clojure/fira_code/glyphs.clj index 4425b02b71..187a08e52e 100755 --- a/clojure/glyphs.clj +++ b/clojure/fira_code/glyphs.clj @@ -1,16 +1,21 @@ -(ns glyphs +(ns fira-code.glyphs + (:refer-clojure :exclude [load]) (:require [clojure.java.io :as io] [clojure.string :as str] [fipp.edn :as fipp] + [fira-code.coll :as coll] [flatland.ordered.map :refer [ordered-map]])) (def ^:dynamic *str) + (def ^:dynamic *pos) -(defn current-char [] (nth @*str @*pos)) +(defn current-char [] + (nth @*str @*pos)) -(defn advance! [] (swap! *pos inc)) +(defn advance! [] + (swap! *pos inc)) (declare parse-anything!) @@ -33,7 +38,6 @@ (= ch \\) (do (.append sb \\) (advance!) (.append sb (current-char)) (recur)) (= ch \") (do (advance!) (str sb)) :else (do (.append sb ch) (recur))))) - (str/replace "\\012" "\n") (str/replace "\\\"" "\"") (str/replace "\\\\" "\\"))))) @@ -53,7 +57,11 @@ :else res)))) (defn expect [c] - (assert (= c (current-char)) (str "Expected '" c "', found " (current-char) " at " @*pos))) + (assert (= c (current-char)) + (str "Expected '" c + "', found " (current-char) + " at " @*pos + " around here:\n" (subs @*str (max 0 (- @*pos 100)) (min (count @*str) (+ @*pos 100)))))) (defn parse-map! [] (skip-ws!) @@ -98,39 +106,114 @@ *pos (atom 0)] (parse-anything!))) -(def escapes {"\n" "\\012" - "\"" "\\\"" - "\\" "\\\\"}) +(defn- serialize-impl [form] + (cond + (string? form) + (if (re-matches #"[a-zA-Z0-9._/]+" form) + form + (str \" (str/replace form #"[\"\\]" {"\"" "\\\"" + "\\" "\\\\"}) \")) + + (keyword? form) + (name form) -(def escape-re #"[\n\"\\]") + (number? form) + (str form) -(defn serialize [form] - (cond - (string? form) (if (re-matches #"[a-zA-Z0-9._/]+" form) - form - (str \" (str/replace form escape-re escapes) \")) - (keyword? form) (name form) - (number? form) (str form) - (sequential? form) (str "(\n" (str/join ",\n" (map serialize form)) "\n)") - (map? form) (str "{\n" (str/join "\n" (for [[k v] form] (str (serialize k) " = " (serialize v) ";"))) "\n}"))) + (instance? clojure.lang.MapEntry form) + (str + (serialize-impl (key form)) + " = " + (case (key form) + ;; https://github.com/googlefonts/glyphsLib/issues/209 + ".appVersion" + (str \" (val form) \") + + ;; ¯\_(ツ)_/¯ + (:stemValues "stemValues") + (str "(\n" (str/join ",\n" (val form)) "\n)") + + ;; else + (serialize-impl (val form))) + ";") + + (and (sequential? form) (empty? form)) + "(\n)" + + (and (sequential? form) (<= 2 (count form) 3) (not (coll? (first form)))) + (str "(" (str/join "," (map serialize-impl form)) ")") + + (sequential? form) + (str "(\n" (str/join ",\n" (map serialize-impl form)) "\n)") + + (and (map? form) (empty? form)) + "{\n}" + + (map? form) + (str "{\n" (str/join "\n" (map serialize-impl form)) "\n}"))) + +(defn serialize [font] + (str (serialize-impl font) "\n")) ; (-> (slurp "FiraCode.glyphs") parse serialize (->> (spit "FiraCode_saved.glyphs"))) +(defn load [path] + (println (str "Parsing '" path "'...")) + (parse (slurp path))) + +(defn save! [path font] + (println (str "Saving '" path "'...")) + (spit path (serialize font))) + (defn -main [& args] (let [font (-> (slurp "FiraCode.glyphs") parse)] (with-open [os (io/writer "clojure/FiraCode.edn")] (binding [*out* os] (fipp/pprint font {:width 200}))))) -(def weights {:Regular "UUID0" - :Bold "BF448B58-7A35-489E-A1C9-12628F60690C"}) +(defn update-code [font key name-attr name f & args] + (let [idx (coll/index-of #(= (get % name-attr) name) (get font key))] + (assert (>= idx 0) (str "Can’t find " key " tag=" name ", got " (str/join ", " (map #(get % name-attr) (get font key))))) + (apply update-in font [key idx :code] f args))) + +(defn lines [s] + (inc (count (re-seq #"\n" s)))) + +(defn words [s] + (count (re-seq #"[^\s]+" s))) + +(defn set-feature [font name feature] + (let [idx (coll/index-of #(= (:tag %) name) (:features font))] + (if (pos? idx) + (do + (println " replacing feature" name "with" (lines (:code feature)) "lines") + (assoc-in font [:features idx] feature)) + (do + (println " appending to feature" name (lines (:code feature)) "lines") + (update font :features conj feature))))) + +(defn set-class [font name class] + (let [idx (coll/index-of #(= (:name %) name) (:classes font))] + (if (pos? idx) + (do + (println " replacing class" name "with" (words (:code class)) "entries") + (assoc-in font [:classes idx] class)) + (do + (println " appending to class" name (words (:code class)) "entries") + (update font :classes conj class))))) + +(def weights + {:Light "B67F0F2D-EC95-4CB8-966E-23AE86958A69" + :Regular "UUID0" + :Bold "4B7A3BAF-EAD8-4024-9BEA-BB1DE86CFCFA"}) (defn layer [l] - { :id (case (:layerId l) - ((:Regular weights)) "Regular" - ((:Bold weights)) "Bold" - (:layerId l)) - :width (:width l) }) + {:id (condp = (:layerId l) + (:Light weights) "Light" + (:Regular weights) "Regular" + (:Bold weights) "Bold" + (:layerId l)) + :width (:width l)}) (defn save-not600 [] (let [font (-> (slurp "FiraCode.glyphs") parse)] diff --git a/clojure/fira_code/main.clj b/clojure/fira_code/main.clj new file mode 100644 index 0000000000..572293a46e --- /dev/null +++ b/clojure/fira_code/main.clj @@ -0,0 +1,32 @@ +(ns fira-code.main + (:require + [clojure.string :as str] + [fira-code.calt :as calt] + [fira-code.coll :as coll] + [fira-code.checks :as checks] + [fira-code.classes :as classes] + [fira-code.features :as features] + [fira-code.glyphs :as glyphs] + [fira-code.not-space :as not-space] + [fira-code.spacers :as spacers] + [fira-code.time :as time] + [flatland.ordered.map :refer [ordered-map]])) + +(defn -main [& args] + (let [path (or (first args) "FiraCode.glyphs") + font (glyphs/load path) + ligas (for [g (:glyphs font) + :let [name (:glyphname g)] + :when (str/ends-with? name ".liga") + :when (not= "0" (:export g)) + :let [[_ liga] (re-matches #"([A-Za-z_]+)\.liga" name)]] + (str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ] + font' (-> font + (calt/replace-calt ligas) + (classes/fill-all) + (features/fill-all) + (spacers/add-spacers ligas) + (not-space/regen-not-space) + (checks/widths))] + (glyphs/save! (or (second args) path) font') + (println))) diff --git a/clojure/fira_code/not_space.clj b/clojure/fira_code/not_space.clj new file mode 100644 index 0000000000..5a5df34547 --- /dev/null +++ b/clojure/fira_code/not_space.clj @@ -0,0 +1,13 @@ +(ns fira-code.not-space + (:require + [clojure.string :as str] + [fira-code.glyphs :as glyphs])) + +(defn regen-not-space [font] + (let [not-spaces (->> (:glyphs font) + (remove #(re-find #"^\.|space$|space\." (:glyphname %))) + (remove #(= "0" (:export %))) + (map :glyphname) + (sort))] + (println " regenerated NotSpace:" (count not-spaces) "glyphs") + (glyphs/update-code font :classes :name "NotSpace" (constantly (str/join " " not-spaces))))) diff --git a/clojure/fira_code/spacers.clj b/clojure/fira_code/spacers.clj new file mode 100644 index 0000000000..2da6bb9851 --- /dev/null +++ b/clojure/fira_code/spacers.clj @@ -0,0 +1,29 @@ +(ns fira-code.spacers + (:require + [clojure.string :as str] + [fira-code.glyphs :as glyphs] + [fira-code.time :as time] + [flatland.ordered.map :refer [ordered-map]])) + +(defn spacer [name] + (ordered-map + :color 3, + :glyphname name, + :lastChange (time/now-str), + :layers + [(ordered-map :layerId (:Light glyphs/weights), :width 1200) + (ordered-map :layerId (:Bold glyphs/weights), :width 1200)])) + +(defn add-spacers [font ligas] + (let [needed (->> (into #{} cat ligas) + (map #(str % ".spacer"))) + existing (->> (:glyphs font) + (map :glyphname) + (filter #(str/ends-with? % ".spacer"))) + new (->> (remove (set existing) needed) + (sort-by str/lower-case))] + (if-not (empty? new) + (do + (println " added glyphs: " (str/join " " new)) + (update font :glyphs #(into % (map spacer new)))) + font))) diff --git a/clojure/fira_code/time.clj b/clojure/fira_code/time.clj new file mode 100644 index 0000000000..797560d4e1 --- /dev/null +++ b/clojure/fira_code/time.clj @@ -0,0 +1,12 @@ +(ns fira-code.time + (:import + [java.time LocalDateTime ZoneId] + [java.time.format DateTimeFormatter])) + +(def ^ZoneId UTC + (ZoneId/of "UTC")) + +(defn now-str [] + (.format + (DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss +0000") + (LocalDateTime/now UTC))) diff --git a/clojure/regen_calt.clj b/clojure/regen_calt.clj deleted file mode 100755 index 7a50037489..0000000000 --- a/clojure/regen_calt.clj +++ /dev/null @@ -1,180 +0,0 @@ -(ns regen-calt - (:require - [clojure.string :as str] - [glyphs :as glyphs])) - -(def ignores - { ["slash" "asterisk"] - (str - " ignore sub slash' asterisk slash;\n" - " ignore sub asterisk slash' asterisk;\n") - - ["asterisk" "slash"] - (str - " ignore sub slash asterisk' slash;\n" - " ignore sub asterisk' slash asterisk;\n") - - ["asterisk" "asterisk"] - (str - " ignore sub slash asterisk' asterisk;\n" - " ignore sub asterisk' asterisk slash;\n") - - ["asterisk" "asterisk" "asterisk"] - (str - " ignore sub slash asterisk' asterisk asterisk;\n" - " ignore sub asterisk' asterisk asterisk slash;\n") - - ;; #624 (?= - ["question" "equal"] - " ignore sub parenleft question' equal;\n" - - ;; #624 (?<= - ["less" "equal"] - (str " ignore sub parenleft question less' equal;\n" - " ignore sub exclam less' equal;\n") - - ;; #624 (?: - ["question" "colon"] - " ignore sub parenleft question' colon;\n" - - ;; #621 <||> - ["less" "bar" "bar"] - " ignore sub less' bar bar greater;\n" - - ["bar" "bar" "greater"] - " ignore sub less bar' bar greater;\n" - - ;; #574 :>= - ["colon" "greater"] - " ignore sub colon' greater equal;\n" - - ;; #548 >=< - ["greater" "equal"] - " ignore sub greater' equal less;\n" - - ["equal" "less"] - " ignore sub greater equal' less;\n" - - ;; #593 {|} - ["braceleft" "bar"] - " ignore sub braceleft' bar braceright;\n" - - ["bar" "braceright"] - " ignore sub braceleft bar' braceright;\n" - - ;; #593 [|] - ["bracketleft" "bar"] - " ignore sub bracketleft' bar bracketright;\n" - - ["bar" "bracketright"] - " ignore sub bracketleft bar' bracketright;\n" - - ;; #410 <*>> <+>> <$>> - ["greater" "greater"] - (str " ignore sub asterisk greater' greater;\n" - " ignore sub plus greater' greater;\n" - " ignore sub dollar greater' greater;\n") - - ;; #410 <*>>> <+>>> <$>>> - ["greater" "greater" "greater"] - (str " ignore sub asterisk greater' greater greater;\n" - " ignore sub plus greater' greater greater;\n" - " ignore sub dollar greater' greater greater;\n") - - ;; #410 <<*> <<+> <<$> - ["less" "less"] - (str " ignore sub less' less asterisk;\n" - " ignore sub less' less plus;\n" - " ignore sub less' less dollar;\n") - - ;; #410 <<<*> <<<+> <<<$> - ["less" "less" "less"] - (str " ignore sub less' less less asterisk;\n" - " ignore sub less' less less plus;\n" - " ignore sub less' less less dollar;\n") -}) - -(def skip-ignores? #{ - ;; #410 <<*>> <<+>> <<$>> - ["less" "asterisk" "greater"] - ["less" "plus" "greater"] - ["less" "dollar" "greater"] -}) - -(defn liga->rule - "[f f i] => { [LIG LIG i] f_f_i.liga - [LIG f i] LIG - [ f f i] LIG }" - [liga] - (case (count liga) - 2 (let [[a b] liga] - (str/replace - (str "lookup 1_2 {\n" - " ignore sub 1 1' 2;\n" - " ignore sub 1' 2 2;\n" - (get ignores liga) - " sub LIG 2' by 1_2.liga;\n" - " sub 1' 2 by LIG;\n" - "} 1_2;") - #"\d" {"1" a "2" b})) - 3 (let [[a b c] liga] - (str/replace - (str "lookup 1_2_3 {\n" - (when-not (skip-ignores? liga) - (str " ignore sub 1 1' 2 3;\n" - " ignore sub 1' 2 3 3;\n")) - (get ignores liga) - " sub LIG LIG 3' by 1_2_3.liga;\n" - " sub LIG 2' 3 by LIG;\n" - " sub 1' 2 3 by LIG;\n" - "} 1_2_3;") - #"\d" {"1" a "2" b "3" c})) - 4 (let [[a b c d] liga] - (str/replace - (str "lookup 1_2_3_4 {\n" - " ignore sub 1 1' 2 3 4;\n" - " ignore sub 1' 2 3 4 4;\n" - (get ignores liga) - " sub LIG LIG LIG 4' by 1_2_3_4.liga;\n" - " sub LIG LIG 3' 4 by LIG;\n" - " sub LIG 2' 3 4 by LIG;\n" - " sub 1' 2 3 4 by LIG;\n" - "} 1_2_3_4;") - #"\d" {"1" a "2" b "3" c "4" d})))) - -(defn index-of [pred xs] - (reduce (fn [i x] (if (pred x) (reduced i) (inc i))) 0 xs)) - -(defn replace-calt [font calt] - (let [features (:features font) - idx (index-of #(= "calt" (:name %)) features) - code (get-in features [idx :code]) - code' (str/replace code - #"### start of generated calt\n[^#]+\n### end of generated calt\n" - (str "### start of generated calt\n" calt "\n### end of generated calt\n"))] - (assoc-in font [:features idx :code] code'))) - -(defn -main [& args] - (let [file (or (first args) "FiraCode.glyphs") - _ (println "Parsing" file "...") - font (glyphs/parse (slurp file)) - ligas (for [g (:glyphs font) - :let [name (:glyphname g)] - :when (str/ends-with? name ".liga") - :let [[_ liga] (re-matches #"([a-z_]+)\.liga" name)]] - (str/split liga #"_")) ;; [ ["dash" "greater" "greater"] ... ] - calt (->> ligas (sort-by count) (reverse) (map liga->rule) (str/join "\n\n")) - font' (replace-calt font calt)] - - (println "Saving" file "...") - (spit file (glyphs/serialize font')) - - (println "Total ligatures count:" (count ligas)) - (println " " (->> ligas - (group-by count) - (sort-by first) - (map (fn [[k v]] (str (count v) (case k 2 " pairs", 3 " triples", 4 " quadruples")))) - (str/join ", "))) - (println))) - -;; (-main) diff --git a/clojure/user.clj b/clojure/user.clj new file mode 100644 index 0000000000..9d53af9749 --- /dev/null +++ b/clojure/user.clj @@ -0,0 +1,17 @@ +(ns user + (:require + [clj-reload.core :as clj-reload] + [clojure+.hashp :as hashp] + [clojure+.print :as print] + [clojure+.error :as error])) + +(hashp/install!) +(print/install!) +(error/install!) + +(clj-reload/init + {:dirs ["clojure"] + :no-reload '#{user}}) + +(def reload + clj-reload/reload) diff --git a/deps.edn b/deps.edn index 5400d830ae..ccc85e5db0 100644 --- a/deps.edn +++ b/deps.edn @@ -1,4 +1,12 @@ {:paths ["clojure"] - :deps {org.clojure/clojure {:mvn/version "1.10.0-alpha8"} - org.flatland/ordered {:mvn/version "1.5.6"} - fipp/fipp {:mvn/version "0.6.12"}}} + :deps {org.clojure/clojure {:mvn/version "1.12.4"} + io.github.tonsky/clojure-plus {:mvn/version "1.7.2"} + io.github.tonsky/clj-reload {:mvn/version "1.0.0"} + org.flatland/ordered {:mvn/version "1.5.7"} + fipp/fipp {:mvn/version "0.6.18"}} + :aliases + {:dev + {:jvm-opts ["-Dclojure.main.report=stderr" + "-Duser.language=en" + "-Duser.country=US" + "-Dfile.encoding=UTF-8"]}}} diff --git a/distr/README.txt b/distr/README.txt new file mode 100644 index 0000000000..ac043089bf --- /dev/null +++ b/distr/README.txt @@ -0,0 +1,559 @@ +Installing +========== + +Windows +------- + +In the ttf folder, double-click each font file, click “Install font”; to install all at once, select all files, right-click, and choose “Install” + +OR + +Use https://chocolatey.org: + + choco install firacode + + +macOS +----- + +In the downloaded TTF folder: + +1. Select all font files +2. Right click and select `Open` (alternatively `Open With Font Book`) +3. Select "Install Font" + +OR + +Use http://brew.sh: + + `brew install --cask font-fira-code` + + +Ubuntu Zesty (17.04), Debian Stretch (9) or newer +------------------------------------------------- + +1. Make sure that the `universe` (for Ubuntu) or `contrib` (for Debian) repository is enabled (see https://askubuntu.com/questions/148638/how-do-i-enable-the-universe-repository or https://wiki.debian.org/SourcesList#Component) +2. Install `fonts-firacode` package either by executing `sudo apt install fonts-firacode` in the terminal or via GUI tool (like “Software Center”) + + +Arch Linux +---------- + +Fira Code package is available in the official repository: https://www.archlinux.org/packages/community/any/ttf-fira-code/. + +Variant of Fira Code package is available in the AUR: https://aur.archlinux.org/packages/otf-fira-code-git/. + + +Gentoo +------ + + emerge -av media-fonts/fira-code + + +Fedora +------ + +To install, perform the following commands: + + dnf install fira-code-fonts + + +Solus +----- + +Fira Code package is available in the official repository: `font-firacode-ttf` and `font-firacode-otf`. +They can be installed by running: + + sudo eopkg install font-firacode-ttf font-firacode-otf + + +Void linux +---------- + + xbps-install font-firacode + + +Linux Manual Installation +------------------------- + +With most desktop-oriented distributions, double-clicking each font file in the ttf folder and selecting “Install font” should be enough. If it isn’t, create and run `download_and_install.sh` script: + + #!/usr/bin/env bash + + fonts_dir="${HOME}/.local/share/fonts" + if [ ! -d "${fonts_dir}" ]; then + echo "mkdir -p $fonts_dir" + mkdir -p "${fonts_dir}" + else + echo "Found fonts dir $fonts_dir" + fi + + for type in Bold Light Medium Regular Retina; do + file_path="${HOME}/.local/share/fonts/FiraCode-${type}.ttf" + file_url="https://github.com/tonsky/FiraCode/blob/master/distr/ttf/FiraCode-${type}.ttf?raw=true" + if [ ! -e "${file_path}" ]; then + echo "wget -O $file_path $file_url" + wget -O "${file_path}" "${file_url}" + else + echo "Found existing file $file_path" + fi; + done + + echo "fc-cache -f" + fc-cache -f + +More details: https://github.com/tonsky/FiraCode/issues/4 + + +FreeBSD +------- + +Using pkg(8): + + pkg install firacode + +OR + +Using ports: + + cd /usr/ports/x11-fonts/firacode && make install clean + + +Enabling ligatures +================== + +Atom +---- + +To change your font to Fira Code, open Atom's preferences (`cmd + ,` on a Mac, `ctrl + ,` on PC), make sure the "Settings" tab is selected, or the "Editor" in Atom 1.10+, and scroll down to "Editor Settings". In the "Font Family" field, enter `Fira Code`. + +If you wish to specify a font weight, for example, Light, use `Fira Code Light` as a font name (Windows) or `FiraCode-Light` (macOS). + +Ligatures are enabled by default in Atom 1.9 and above. + + +VS Code +------- + +To open the settings editor, first from the File menu choose Preferences, Settings or use keyboard shortcut `Ctrl + ,` (Windows) or `Cmd + ,` (macOS). + +To enable FiraCode in the settings editor, under "Commonly Used", expand the "Text Editor" settings and then click on "Font". In the "Font Family" input box type `Fira Code`, replacing any content. Tick the check box "Enables/Disables font ligatures" under "Font Ligatures" to enable the special ligatures. + +If you wish to specify a font weight, for example, Light, use `Fira Code Light` as a font name (Windows) or `FiraCode-Light` (macOS). + + +IntelliJ products +----------------- + +1. Enable in Settings → Editor → Font → Enable Font Ligatures +2. Select `Fira Code` as "Primary font" under Settings → Editor → Font + +Additionally, if a Color Scheme is selected: + +3. Enable in Settings → Editor → Color Scheme → Color Scheme Font → Enable Font Ligatures +4. Select Fira Code as "Primary font" under Settings → Editor → Color Scheme → Color Scheme Font + + +BBEdit +------ + +1. Install FiraCode as per the [macOS installation instructions](https://github.com/tonsky/FiraCode/wiki/Installing#macos) +2. Open BBEdit preferences, Editor Defaults, assign Fira Code as the Default font + + +Brackets +-------- + +1. From the `View` menu choose `Themes....` +2. Paste `'Fira Code'`, at the beginning of `Font Family` + + +Emacs +----- + +There are a few options when it comes down to using ligatures in +Emacs. They are listed in order of preferred to less-preferred. Pick one! + +1. Using composition mode in Emacs Mac port + +If you're using the latest Mac port of Emacs (https://bitbucket.org/mituharu/emacs-mac by Mitsuharu Yamamoto) for macOS, you can use: + + (mac-auto-operator-composition-mode) + +This is generally the easiest solution, but can only be used on macOS. + +2. Using prettify-symbols + +These instructions are pieced together by https://github.com/Triavanicus, taking some pieces from https://github.com/minad/hasklig-mode. + +This method requires you to install the Fira Code Symbol font, made by https://github.com/siegebell: +https://github.com/tonsky/FiraCode/issues/211#issuecomment-239058632 + + (defun fira-code-mode--make-alist (list) + "Generate prettify-symbols alist from LIST." + (let ((idx -1)) + (mapcar + (lambda (s) + (setq idx (1+ idx)) + (let* ((code (+ #Xe100 idx)) + (width (string-width s)) + (prefix ()) + (suffix '(?\s (Br . Br))) + (n 1)) + (while (< n width) + (setq prefix (append prefix '(?\s (Br . Bl)))) + (setq n (1+ n))) + (cons s (append prefix suffix (list (decode-char 'ucs code)))))) + list))) + + (defconst fira-code-mode--ligatures + '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\" + "{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}" + "--" "---" "-->" "->" "->>" "-<" "-<<" "-~" + "#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_(" + ".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*" + "/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||=" + "|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "==" + "===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">=" + ">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>" + "<$" "<$>" "\\)" #Xe113) + ("[^-]\\(->\\)" #Xe114) + ("\\(->>\\)" #Xe115) + ("\\(-<\\)" #Xe116) + ("\\(-<<\\)" #Xe117) + ("\\(-~\\)" #Xe118) + ("\\(#{\\)" #Xe119) + ("\\(#\\[\\)" #Xe11a) + ("\\(##\\)" #Xe11b) + ("\\(###\\)" #Xe11c) + ("\\(####\\)" #Xe11d) + ("\\(#(\\)" #Xe11e) + ("\\(#\\?\\)" #Xe11f) + ("\\(#_\\)" #Xe120) + ("\\(#_(\\)" #Xe121) + ("\\(\\.-\\)" #Xe122) + ("\\(\\.=\\)" #Xe123) + ("\\(\\.\\.\\)" #Xe124) + ("\\(\\.\\.<\\)" #Xe125) + ("\\(\\.\\.\\.\\)" #Xe126) + ("\\(\\?=\\)" #Xe127) + ("\\(\\?\\?\\)" #Xe128) + ("\\(;;\\)" #Xe129) + ("\\(/\\*\\)" #Xe12a) + ("\\(/\\*\\*\\)" #Xe12b) + ("\\(/=\\)" #Xe12c) + ("\\(/==\\)" #Xe12d) + ("\\(/>\\)" #Xe12e) + ("\\(//\\)" #Xe12f) + ("\\(///\\)" #Xe130) + ("\\(&&\\)" #Xe131) + ("\\(||\\)" #Xe132) + ("\\(||=\\)" #Xe133) + ("[^|]\\(|=\\)" #Xe134) + ("\\(|>\\)" #Xe135) + ("\\(\\^=\\)" #Xe136) + ("\\(\\$>\\)" #Xe137) + ("\\(\\+\\+\\)" #Xe138) + ("\\(\\+\\+\\+\\)" #Xe139) + ("\\(\\+>\\)" #Xe13a) + ("\\(=:=\\)" #Xe13b) + ("[^!/]\\(==\\)[^>]" #Xe13c) + ("\\(===\\)" #Xe13d) + ("\\(==>\\)" #Xe13e) + ("[^=]\\(=>\\)" #Xe13f) + ("\\(=>>\\)" #Xe140) + ("\\(<=\\)" #Xe141) + ("\\(=<<\\)" #Xe142) + ("\\(=/=\\)" #Xe143) + ("\\(>-\\)" #Xe144) + ("\\(>=\\)" #Xe145) + ("\\(>=>\\)" #Xe146) + ("[^-=]\\(>>\\)" #Xe147) + ("\\(>>-\\)" #Xe148) + ("\\(>>=\\)" #Xe149) + ("\\(>>>\\)" #Xe14a) + ("\\(<\\*\\)" #Xe14b) + ("\\(<\\*>\\)" #Xe14c) + ("\\(<|\\)" #Xe14d) + ("\\(<|>\\)" #Xe14e) + ("\\(<\\$\\)" #Xe14f) + ("\\(<\\$>\\)" #Xe150) + ("\\( Settings + +Add before "ignored_packages": + + "font_face": "Fira Code", + "font_options": ["subpixel_antialias"], + +If you want enable antialias, add in font_options: "gray_antialias" + + +Visual Studio +------------- + +1. Launch Visual Studio (2015 or later). +2. Launch the Options dialog by opening the "Tools" menu and selecting "Options". +3. In the Options dialog, under the "Environment" category, you'll find "Fonts and Colors". Click on that. You'll see a combo-box on the right hand side of the dialog labelled "Font". Select "Fira Code" from that combo-box. +4. Click "OK" to dismiss. +5. Restart Visual Studio. + +Now, most FiraCode ligatures will work. A notable exception is the hyphen-based ligatures (e.g. the C++ dereference '->'). See https://github.com/tonsky/FiraCode/issues/422 for details. + + +Troubleshooting +=============== + +See https://github.com/tonsky/FiraCode/wiki/Troubleshooting diff --git a/distr/eot/FiraCode-Bold.eot b/distr/eot/FiraCode-Bold.eot deleted file mode 100644 index e661db72c2..0000000000 Binary files a/distr/eot/FiraCode-Bold.eot and /dev/null differ diff --git a/distr/eot/FiraCode-Light.eot b/distr/eot/FiraCode-Light.eot deleted file mode 100644 index 387cb65ac8..0000000000 Binary files a/distr/eot/FiraCode-Light.eot and /dev/null differ diff --git a/distr/eot/FiraCode-Medium.eot b/distr/eot/FiraCode-Medium.eot deleted file mode 100644 index 871397235b..0000000000 Binary files a/distr/eot/FiraCode-Medium.eot and /dev/null differ diff --git a/distr/eot/FiraCode-Regular.eot b/distr/eot/FiraCode-Regular.eot deleted file mode 100644 index cef458e5f1..0000000000 Binary files a/distr/eot/FiraCode-Regular.eot and /dev/null differ diff --git a/distr/fira_code.css b/distr/fira_code.css index f8e4a5b38e..5d3309463e 100644 --- a/distr/fira_code.css +++ b/distr/fira_code.css @@ -1,43 +1,48 @@ -@font-face{ - font-family: 'Fira Code'; - src: url('eot/FiraCode-Light.eot'); - src: url('eot/FiraCode-Light.eot') format('embedded-opentype'), - url('woff2/FiraCode-Light.woff2') format('woff2'), - url('woff/FiraCode-Light.woff') format('woff'), - url('ttf/FiraCode-Light.ttf') format('truetype'); - font-weight: 300; - font-style: normal; +@font-face { + font-family: 'Fira Code'; + src: url('woff2/FiraCode-Light.woff2') format('woff2'), + url('woff/FiraCode-Light.woff') format('woff'); + font-weight: 300; + font-style: normal; } -@font-face{ - font-family: 'Fira Code'; - src: url('eot/FiraCode-Regular.eot'); - src: url('eot/FiraCode-Regular.eot') format('embedded-opentype'), - url('woff2/FiraCode-Regular.woff2') format('woff2'), - url('woff/FiraCode-Regular.woff') format('woff'), - url('ttf/FiraCode-Regular.ttf') format('truetype'); - font-weight: 400; - font-style: normal; +@font-face { + font-family: 'Fira Code'; + src: url('woff2/FiraCode-Regular.woff2') format('woff2'), + url('woff/FiraCode-Regular.woff') format('woff'); + font-weight: 400; + font-style: normal; } -@font-face{ - font-family: 'Fira Code'; - src: url('eot/FiraCode-Medium.eot'); - src: url('eot/FiraCode-Medium.eot') format('embedded-opentype'), - url('woff2/FiraCode-Medium.woff2') format('woff2'), - url('woff/FiraCode-Medium.woff') format('woff'), - url('ttf/FiraCode-Medium.ttf') format('truetype'); - font-weight: 500; - font-style: normal; +@font-face { + font-family: 'Fira Code'; + src: url('woff2/FiraCode-Medium.woff2') format('woff2'), + url('woff/FiraCode-Medium.woff') format('woff'); + font-weight: 500; + font-style: normal; } -@font-face{ - font-family: 'Fira Code'; - src: url('eot/FiraCode-Bold.eot'); - src: url('eot/FiraCode-Bold.eot') format('embedded-opentype'), - url('woff2/FiraCode-Bold.woff2') format('woff2'), - url('woff/FiraCode-Bold.woff') format('woff'), - url('ttf/FiraCode-Bold.ttf') format('truetype'); - font-weight: 700; - font-style: normal; -} \ No newline at end of file +@font-face { + font-family: 'Fira Code'; + src: url('woff2/FiraCode-SemiBold.woff2') format('woff2'), + url('woff/FiraCode-SemiBold.woff') format('woff'); + font-weight: 600; + font-style: normal; +} + +@font-face { + font-family: 'Fira Code'; + src: url('woff2/FiraCode-Bold.woff2') format('woff2'), + url('woff/FiraCode-Bold.woff') format('woff'); + font-weight: 700; + font-style: normal; +} + +@font-face { + font-family: 'Fira Code VF'; + src: url('woff2/FiraCode-VF.woff2') format('woff2-variations'), + url('woff/FiraCode-VF.woff') format('woff-variations'); + /* 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 */ + font-weight: 300 700; + font-style: normal; +} diff --git a/distr/otf/FiraCode-Bold.otf b/distr/otf/FiraCode-Bold.otf deleted file mode 100644 index cea3cbd066..0000000000 Binary files a/distr/otf/FiraCode-Bold.otf and /dev/null differ diff --git a/distr/otf/FiraCode-Light.otf b/distr/otf/FiraCode-Light.otf deleted file mode 100644 index d6bb94b066..0000000000 Binary files a/distr/otf/FiraCode-Light.otf and /dev/null differ diff --git a/distr/otf/FiraCode-Medium.otf b/distr/otf/FiraCode-Medium.otf deleted file mode 100644 index 04bf8193d6..0000000000 Binary files a/distr/otf/FiraCode-Medium.otf and /dev/null differ diff --git a/distr/otf/FiraCode-Regular.otf b/distr/otf/FiraCode-Regular.otf deleted file mode 100644 index 4770d1644c..0000000000 Binary files a/distr/otf/FiraCode-Regular.otf and /dev/null differ diff --git a/distr/otf/FiraCode-Retina.otf b/distr/otf/FiraCode-Retina.otf deleted file mode 100644 index 6316cffeb3..0000000000 Binary files a/distr/otf/FiraCode-Retina.otf and /dev/null differ diff --git a/distr/specimen.html b/distr/specimen.html index 4ee2cf9774..6dce70b9b8 100644 --- a/distr/specimen.html +++ b/distr/specimen.html @@ -1,5 +1,5 @@ - + @@ -19,47 +19,77 @@ .light { font-weight: 300; } .regular { font-weight: 400; } .medium { font-weight: 500; } + .semibold { font-weight: 600; } .bold { font-weight: 700; } + .variable { font-family: 'Fira Code VF'; font-variation-settings: 'wght' 400; } i { font-style: normal; color: #c33; } b { font-weight: inherit; color: #c33; } +
# Fira Code Light -take = (n, [x, ...xs]:list) --> - | n <= 0 => [] - | empty list => [] - | otherwise => [x] ++ take n-1, xs +take = (n, [x, ...xs]:list) --> + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs -last3 = reverse >> take 3 >> reverse
+last3 = reverse >> take 3 >> reverse -
# Fira Code Regular +
# Fira Code Regular take = (n, [x, ...xs]:list) --> - | n <= 0 => [] - | empty list => [] - | otherwise => [x] ++ take n-1, xs + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs -last3 = reverse >> take 3 >> reverse
+last3 = reverse >> take 3 >> reverse
-
# Fira Code Medium +
# Fira Code Medium -take = (n, [x, ...xs]:list) --> - | n <= 0 => [] - | empty list => [] - | otherwise => [x] ++ take n-1, xs +take = (n, [x, ...xs]:list) --> + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs -last3 = reverse >> take 3 >> reverse
+last3 = reverse >> take 3 >> reverse
-
# Fira Code Bold +
# Fira Code SemiBold -take = (n, [x, ...xs]:list) --> - | n <= 0 => [] - | empty list => [] - | otherwise => [x] ++ take n-1, xs +take = (n, [x, ...xs]:list) --> + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs + +last3 = reverse >> take 3 >> reverse
+ + +
# Fira Code Bold + +take = (n, [x, ...xs]:list) --> + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs + +last3 = reverse >> take 3 >> reverse
+ +
# Fira Code Variable + + 400 + +take = (n, [x, ...xs]:list) --> + | n <= 0 => [] + | empty list => [] + | otherwise => [x] ++ take n-1, xs -last3 = reverse >> take 3 >> reverse
+last3 = reverse >> take 3 >> reverse
diff --git a/distr/ttf/FiraCode-Bold.ttf b/distr/ttf/FiraCode-Bold.ttf deleted file mode 100644 index 0d78eef329..0000000000 Binary files a/distr/ttf/FiraCode-Bold.ttf and /dev/null differ diff --git a/distr/ttf/FiraCode-Light.ttf b/distr/ttf/FiraCode-Light.ttf deleted file mode 100644 index 18b9e9a0c2..0000000000 Binary files a/distr/ttf/FiraCode-Light.ttf and /dev/null differ diff --git a/distr/ttf/FiraCode-Medium.ttf b/distr/ttf/FiraCode-Medium.ttf deleted file mode 100644 index d106632096..0000000000 Binary files a/distr/ttf/FiraCode-Medium.ttf and /dev/null differ diff --git a/distr/ttf/FiraCode-Regular.ttf b/distr/ttf/FiraCode-Regular.ttf deleted file mode 100644 index 0fb0817156..0000000000 Binary files a/distr/ttf/FiraCode-Regular.ttf and /dev/null differ diff --git a/distr/ttf/FiraCode-Retina.ttf b/distr/ttf/FiraCode-Retina.ttf deleted file mode 100644 index 5bbb74beda..0000000000 Binary files a/distr/ttf/FiraCode-Retina.ttf and /dev/null differ diff --git a/distr/woff/FiraCode-Bold.woff b/distr/woff/FiraCode-Bold.woff deleted file mode 100644 index dd7abb6f37..0000000000 Binary files a/distr/woff/FiraCode-Bold.woff and /dev/null differ diff --git a/distr/woff/FiraCode-Light.woff b/distr/woff/FiraCode-Light.woff deleted file mode 100644 index 2ecc26d02f..0000000000 Binary files a/distr/woff/FiraCode-Light.woff and /dev/null differ diff --git a/distr/woff/FiraCode-Medium.woff b/distr/woff/FiraCode-Medium.woff deleted file mode 100644 index 06232678f3..0000000000 Binary files a/distr/woff/FiraCode-Medium.woff and /dev/null differ diff --git a/distr/woff/FiraCode-Regular.woff b/distr/woff/FiraCode-Regular.woff deleted file mode 100644 index 5e4106f21b..0000000000 Binary files a/distr/woff/FiraCode-Regular.woff and /dev/null differ diff --git a/distr/woff2/FiraCode-Bold.woff2 b/distr/woff2/FiraCode-Bold.woff2 deleted file mode 100644 index 5151301b22..0000000000 Binary files a/distr/woff2/FiraCode-Bold.woff2 and /dev/null differ diff --git a/distr/woff2/FiraCode-Light.woff2 b/distr/woff2/FiraCode-Light.woff2 deleted file mode 100644 index 82c98507e1..0000000000 Binary files a/distr/woff2/FiraCode-Light.woff2 and /dev/null differ diff --git a/distr/woff2/FiraCode-Medium.woff2 b/distr/woff2/FiraCode-Medium.woff2 deleted file mode 100644 index 8f58744ceb..0000000000 Binary files a/distr/woff2/FiraCode-Medium.woff2 and /dev/null differ diff --git a/distr/woff2/FiraCode-Regular.woff2 b/distr/woff2/FiraCode-Regular.woff2 deleted file mode 100644 index df544dc1f4..0000000000 Binary files a/distr/woff2/FiraCode-Regular.woff2 and /dev/null differ diff --git a/docs/calt_performance.md b/docs/calt_performance.md new file mode 100644 index 0000000000..ac6f3c1cb0 --- /dev/null +++ b/docs/calt_performance.md @@ -0,0 +1,63 @@ +# Time to shape text with different calt code + +Baseline: + +``` +sub 1 2 3 4 by 1_2_3_4.liga; +``` + +Spacers: + +``` +sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; +sub 1.spacer 2.spacer 3' 4 by 3.spacer; +sub 1.spacer 2' 3 4 by 2.spacer; +sub 1' 2 3 4 by 1.spacer; +``` + +Lookups: + +``` +lookup 1_2_3_4 { + sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; + sub 1.spacer 2.spacer 3' 4 by 3.spacer; + sub 1.spacer 2' 3 4 by 2.spacer; + sub 1' 2 3 4 by 1.spacer; +} 1_2_3_4; +``` + +Ignores: + +``` +lookup 1_2_3_4 { + ignore sub 1 1' 2 3 4; + ignore sub 1' 2 3 4 4; + sub 1.spacer 2.spacer 3.spacer 4' by 1_2_3_4.liga; + sub 1.spacer 2.spacer 3' 4 by 3.spacer; + sub 1.spacer 2' 3 4 by 2.spacer; + sub 1' 2 3 4 by 1.spacer; +} 1_2_3_4; +``` + +Benchmark: + +``` +time hb-shape -n 100000 distr/ttf/FiraCode-Regular.ttf "Hello +++ /// !== <-> world" +``` + +Setup: + +``` +HarfBuzz 2.6.4 +3,2 GHz 6-Core Intel Core i7 +MacOS 10.15.3 +``` + +Results: + +``` +Baseline 0.407s +Spacers 1.415s +Lookups 2.080s +Ignores 2.656s +``` \ No newline at end of file diff --git a/extras/arrows.png b/extras/arrows.png new file mode 100644 index 0000000000..f9d0c3256c Binary files /dev/null and b/extras/arrows.png differ diff --git a/extras/arrows_es.png b/extras/arrows_es.png new file mode 100644 index 0000000000..6cda46c128 Binary files /dev/null and b/extras/arrows_es.png differ diff --git a/extras/arrows_pt.png b/extras/arrows_pt.png new file mode 100644 index 0000000000..936b790403 Binary files /dev/null and b/extras/arrows_pt.png differ diff --git a/extras/character_variants.png b/extras/character_variants.png new file mode 100644 index 0000000000..3eebaf9ffb Binary files /dev/null and b/extras/character_variants.png differ diff --git a/extras/character_variants_es.png b/extras/character_variants_es.png new file mode 100644 index 0000000000..1af7d26c2c Binary files /dev/null and b/extras/character_variants_es.png differ diff --git a/extras/character_variants_pt.png b/extras/character_variants_pt.png new file mode 100644 index 0000000000..2810fd8e73 Binary files /dev/null and b/extras/character_variants_pt.png differ diff --git a/extras/console.png b/extras/console.png new file mode 100644 index 0000000000..6de09b4b6a Binary files /dev/null and b/extras/console.png differ diff --git a/extras/console_es.png b/extras/console_es.png new file mode 100644 index 0000000000..9b66c2cee1 Binary files /dev/null and b/extras/console_es.png differ diff --git a/extras/console_pt.png b/extras/console_pt.png new file mode 100644 index 0000000000..2f64469922 Binary files /dev/null and b/extras/console_pt.png differ diff --git a/extras/download.png b/extras/download.png new file mode 100644 index 0000000000..15f56fa5cc Binary files /dev/null and b/extras/download.png differ diff --git a/extras/download_es.png b/extras/download_es.png new file mode 100644 index 0000000000..be0c669546 Binary files /dev/null and b/extras/download_es.png differ diff --git a/extras/download_pt.png b/extras/download_pt.png new file mode 100644 index 0000000000..ed16a166b7 Binary files /dev/null and b/extras/download_pt.png differ diff --git a/extras/ligature_variants.png b/extras/ligature_variants.png new file mode 100644 index 0000000000..c554feb166 Binary files /dev/null and b/extras/ligature_variants.png differ diff --git a/extras/ligature_variants_es.png b/extras/ligature_variants_es.png new file mode 100644 index 0000000000..bf15089c5b Binary files /dev/null and b/extras/ligature_variants_es.png differ diff --git a/extras/ligature_variants_pt.png b/extras/ligature_variants_pt.png new file mode 100644 index 0000000000..af133b9f9c Binary files /dev/null and b/extras/ligature_variants_pt.png differ diff --git a/extras/ligatures.png b/extras/ligatures.png new file mode 100644 index 0000000000..cbd3943789 Binary files /dev/null and b/extras/ligatures.png differ diff --git a/extras/ligatures_es.png b/extras/ligatures_es.png new file mode 100644 index 0000000000..437ae5a48b Binary files /dev/null and b/extras/ligatures_es.png differ diff --git a/extras/ligatures_pt.png b/extras/ligatures_pt.png new file mode 100644 index 0000000000..f05bebb6f5 Binary files /dev/null and b/extras/ligatures_pt.png differ diff --git a/extras/logo.svg b/extras/logo.svg new file mode 100644 index 0000000000..f2883b2f1d --- /dev/null +++ b/extras/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extras/math.png b/extras/math.png new file mode 100644 index 0000000000..77a082684c Binary files /dev/null and b/extras/math.png differ diff --git a/extras/math_es.png b/extras/math_es.png new file mode 100644 index 0000000000..13097e0698 Binary files /dev/null and b/extras/math_es.png differ diff --git a/extras/math_pt.png b/extras/math_pt.png new file mode 100644 index 0000000000..b3b71368f1 Binary files /dev/null and b/extras/math_pt.png differ diff --git a/extras/progress.gif b/extras/progress.gif new file mode 100644 index 0000000000..51af92c6c6 Binary files /dev/null and b/extras/progress.gif differ diff --git a/extras/progress.png b/extras/progress.png new file mode 100644 index 0000000000..545367d88d Binary files /dev/null and b/extras/progress.png differ diff --git a/extras/progress_es.gif b/extras/progress_es.gif new file mode 100644 index 0000000000..e96acd0c7a Binary files /dev/null and b/extras/progress_es.gif differ diff --git a/extras/progress_pt.gif b/extras/progress_pt.gif new file mode 100644 index 0000000000..a5fe188977 Binary files /dev/null and b/extras/progress_pt.gif differ diff --git a/extras/samples.png b/extras/samples.png new file mode 100644 index 0000000000..f7e7ec2255 Binary files /dev/null and b/extras/samples.png differ diff --git a/extras/samples2.png b/extras/samples2.png new file mode 100644 index 0000000000..40a70e282c Binary files /dev/null and b/extras/samples2.png differ diff --git a/extras/showcases.txt b/extras/showcases.txt new file mode 100644 index 0000000000..2dda141aa7 --- /dev/null +++ b/extras/showcases.txt @@ -0,0 +1,376 @@ + .= ..= := ::= =:= __ + == != === !== =/= =!= + +<-< <<- <-- <- <-> -> --> ->> >-> +<=< <== <<->> <=> => ==> =>> >=> + >>- >- <~> -< -<< =<< + <-| <=| /\ \/ |-> |=> + <~~ <~ ~~ ~> ~~> + + <<< << <= <> >= >> >>> + {. {| [| |] |} .} +<:> >:< >:> <:< :>: :<: :> :< >: <: + <||| <|| <| <|> |> ||> |||> + + <$ <$> $> + <+ <+> +> + <* <*> *> + + \n \\ /* */ /// // + --> /> + 0xF www Fl Tl Il fi fj + + ;; :: ::: !! ?? %% && + || .. ... ..< .? ?. + -- --- ++ +++ ** *** + + =~ !~ ~- -~ ~@ + ^= ?= /= /== + -| _|_ |- ||- + #! #= ## ### #### + #{ #[ ]# #( #? #_ #_( + +# Context-aware alignment + +fii fjj +a*b a*A B*b A*B *a *A a* A* +a-b a-A B-b A-B -a -A a- A- +a+b a+A B+b A+B +a +A a+ A+ +a:b a:A B:b A:B :a :A a: A: + +# Powerline + +       + +# Stylistic sets + +r 0 123456789 & && $ <$ <$> $> @ <= >= + +# Unicode + +       +⌀ ⌃ ⌄ ⌅ ⌆ ⌘ ⌤ ⌥ ⎇ ⎋ ⏏ ⎈ ✓ ⌂ ⇪ ⌧ ⌫ ⌦ ⌨ ⏎ � +☐ ☑ ☒ ■ □ ▢ ▣ ▤ ▦ ▧ ▨ ▩ ◧ ◨ ◩ ◪ ◫ ◰ ◱ ◲ ◳ +⊜ 🄍 🄎 🄏 🅭 🅮 🅯 🆭 +⟲ ⟳ ⟰ ⟱ ⟴ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ↩ ↪ ⇞ ⇟ ⇤ ⇥ ↰ ↱ ↲ ↳ ❰ ❱ +            + +≢ ẞ ᐅ ᐊ ∴ ∵ ⎈ ‖ ∧ ∨ ⊢ ⊣ ⊤ ⊥ ⊦ ⊧ ⊨ ⊩ ⊪ ⊫ ⊬ ⊭ ⊮ ⊯ +⟲ ⟳ ⟰ ⟱ ⟴ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ +↩ ⇞ ⇟ ⇤ ⇥ ⌀ ⌃ ⌄ ⌅ ⌆ ⌘ ⌤ ⌥ ⎇ ⎋ ⏏ ✓ ☐ ☑ ☒ ▤ ▦ ▧ ▨ ▩ +␆ ␈ ␇ ␣ ␢ ␘ ␍ ␐ ␡ ␥ ␔ ␑ ␓ ␒ ␙ ␃ ␄ ␗ ␅ ␛ ␜ ␌ ␝ ␉ ␊ ␕ ␤ ␀ ␞ ␏ ␎ ␠ ␁ ␂ ␚ ␦ ␖ ␟ ␋ +ℂ ℍ ℕ ℙ ℚ ℝ ℤ 𝔹 ∀ ∃ ∄ ∅ ⊂ ⊃ ⊄ ⊅ ⊆ ⊇ ⊈ ⊉ ⊊ ⊋ ∈ ∉ ∊ ∋ ∌ ∍ ∪ ∩ +☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ 「a」 「a」 + +# Box drawing + +╭╌╌╌╌╮ ╭┄┄┄┄╮ ╭┈┈┈┈╮ +╎ ╏ ┆ ┇ ┊ ┋ +╎ ╏ ┆ ┇ ┊ ┋ +╰╍╍╍╍╯ ╰┅┅┅┅╯ ╰┉┉┉┉╯ + +┌─┬─┐ ╔╦═╗ ┏━┳┓ ╒═╤═╗ ╭─┰─╮ ○ ○ ◆ ◆ +├─┼─┤ ╠╬═╣ ┣━╋┫ ├─┼─╢ ┝━╋━┥ ╲ ╱ ╳ +└─┴─┘ ╚╩═╝ ┗━┻┛ ╘═╧═╝ ╰─┸─╯ ■ ◆ ◆ + +# Blocks + +|███ | 50% + +▖ ▗ ▙ ▚ ▛ ▜ ▞ ▟ + +▁▂▃▄▅▆▇█▀▔ +▏ +▎ +▍ +▌ +▋ +▊ +▉ +▐ +▕ + +# Multi-line brackets + +⎛ 1 ⎞ ⎡ a ⎤ ⎧ x ⎫ +⎜ 2 ⎟ ⎢ b ⎥ ⎪ y ⎪ +⎜ 3 ⎟ ⎢ c ⎥ ⎨ z ⎬ +⎜ 4 ⎟ ⎢ d ⎥ ⎪ y ⎪ +⎝ 5 ⎠ ⎣ e ⎦ ⎩ x ⎭ + +# Stylistic sets + +cv01 a +cv02 g +cv03..06 i +cv07..10 l +ss01 r +zero, cv11..13 0 +cv14 3 +onum 0123456789 +cv17 ~ +ss05 @ +ss04 $ +cv18 % +ss03 & +cv15..16 * +cv31 () +cv29 {} +cv30 | + +ss02 <= >= +cv19..20 <= +cv23 >= +cv21..22 =< +ss08 == === != !== +cv24 /= +ss09 >>= <<= ||= |= +cv25 .- +cv26 :- +cv32 .= +cv27 [] +cv28 {. .} +ss06 \\ +ss07 =~ !~ +ss10 Fl Tl fi fj fl ft + +# Arbitrary-length arrows #346 + +<---------------------------------------------<< +<- <-- <--- <---- ----> ---> --> -> +>- >-- >--- >---- ----< ---< --< -< +|- |-- |--- |---- ----| ---| --| -| +<<- <<-- <<--- <<---- ---->> --->> -->> ->> +>>- >>-- >>--- >>---- ----<< ---<< --<< -<< +||- ||-- ||--- ||---- ----|| ---|| --|| -|| +----- ----< ---<< ----> --->> ----| ---|| +<---- <---< <--<< <---> <-->> <---| <--|| --<-- +<<--- <<--< <<-<< <<--> <<->> <<--| <<-|| -<<- +>---- >---< >--<< >---> >-->> >---| >--|| -->-- +>>--- >>--< >>-<< >>--> >>->> >>--| >>-|| ->>- +|---- |---< |--<< |---> |-->> |---| |--|| --|-- +||--- ||--< ||-<< ||--> ||->> ||--| ||-|| -||- +|-<-<<->>->-|-||-| +|--<--<<-->>-->--|--||--| +|---<---<<--->>--->---|---||---| + +< -< --< ---< ----< +<- -<- --<- ---<- ----<- +<-- -<-- --<-- ---<-- ----<-- +<--- -<--- --<--- ---<--- ----<--- +<---- -<---- --<---- ---<---- ----<---- + +> -> --> ---> ----> +>- ->- -->- --->- ---->- +>-- ->-- -->-- --->-- ---->-- +>--- ->--- -->--- --->--- ---->--- +>---- ->---- -->---- --->---- ---->---- + +| -| --| ---| ----| +|- -|- --|- ---|- ----|- +|-- -|-- --|-- ---|-- ----|-- +|--- -|--- --|--- ---|--- ----|--- +|---- -|---- --|---- ---|---- ----|---- + +<< -<< --<< ---<< ----<< +<<- -<<- --<<- ---<<- ----<<- +<<-- -<<-- --<<-- ---<<-- ----<<-- +<<--- -<<--- --<<--- ---<<--- ----<<--- +<<---- -<<---- --<<---- ---<<---- ----<<---- + +>> ->> -->> --->> ---->> +>>- ->>- -->>- --->>- ---->>- +>>-- ->>-- -->>-- --->>-- ---->>-- +>>--- ->>--- -->>--- --->>--- ---->>--- +>>---- ->>---- -->>---- --->>---- ---->>---- + +|| -|| --|| ---|| ----|| +||- -||- --||- ---||- ----||- +||-- -||-- --||-- ---||-- ----||-- +||--- -||--- --||--- ---||--- ----||--- +||---- -||---- --||---- ---||---- ----||---- + +<<< -<<< --<<< ---<<< ----<<< +<<<- -<<<- --<<<- ---<<<- ----<<<- +<<<-- -<<<-- --<<<-- ---<<<-- ----<<<-- +<<<--- -<<<--- --<<<--- ---<<<--- ----<<<--- +<<<---- -<<<---- --<<<---- ---<<<---- ----<<<---- + +>>> ->>> -->>> --->>> ---->>> +>>>- ->>>- -->>>- --->>>- ---->>>- +>>>-- ->>>-- -->>>-- --->>>-- ---->>>-- +>>>--- ->>>--- -->>>--- --->>>--- ---->>>--- +>>>---- ->>>---- -->>>---- --->>>---- ---->>>---- + +||| -||| --||| ---||| ----||| +|||- -|||- --|||- ---|||- ----|||- +|||-- -|||-- --|||-- ---|||-- ----|||-- +|||--- -|||--- --|||--- ---|||--- ----|||--- +|||---- -|||---- --|||---- ---|||---- ----|||---- + +# Equal-based arrows + +<====================================================<< +<= <== <=== <==== ====> ===> ==> => +>= >== >=== >==== ====< ===< ==< =< +|= |== |=== |==== ====| ===| ==| =| +<<= <<== <<=== <<==== ====>> ===>> ==>> =>> +>>= >>== >>=== >>==== ====<< ===<< ==<< =<< +||= ||== ||=== ||==== ====|| ===|| ==|| =|| +===== ====< ===<< ====> ===>> ====| ===|| ====/ +<==== <===< <==<< <===> <==>> <===| <==|| <===/ ==<== +<<=== <<==< <<=<< <<==> <<=>> <<==| <<=|| <<==/ =<<= +>==== >===< >==<< >===> >==>> >===| >==|| >===/ ==>== +>>=== >>==< >>=<< >>==> >>=>> >>==| >>=|| >>==/ =>>= +|==== |===< |==<< |===> |==>> |===| |==|| |===/ ==|== +||=== ||==< ||=<< ||==> ||=>> ||==| ||=|| ||==/ =||= +/==== /===< /==<< /===> /==>> /===| /==|| /===/ ==/== +|=<=<<=>>=>=|=||=/=:=!=| +|==<==<<==>>==>==|==||==/==:==!==| +|===<===<<===>>===>===|===||===/===:===!===| + +< =< ==< ===< ====< +<= =<= ==<= ===<= ====<= +<== =<== ==<== ===<== ====<== +<=== =<=== ==<=== ===<=== ====<=== +<==== =<==== ==<==== ===<==== ====<==== + +> => ==> ===> ====> +>= =>= ==>= ===>= ====>= +>== =>== ==>== ===>== ====>== +>=== =>=== ==>=== ===>=== ====>=== +>==== =>==== ==>==== ===>==== ====>==== + +| =| ==| ===| ====| +|= =|= ==|= ===|= ====|= +|== =|== ==|== ===|== ====|== +|=== =|=== ==|=== ===|=== ====|=== +|==== =|==== ==|==== ===|==== ====|==== + +/ =/ ==/ ===/ ====/ +/= =/= ==/= ===/= ====/= +/== =/== ==/== ===/== ====/== +/=== =/=== ==/=== ===/=== ====/=== +/==== =/==== ==/==== ===/==== ====/==== + +: =: ==: ===: ====: +:= =:= ==:= ===:= ====:= +:== =:== ==:== ===:== ====:== +:=== =:=== ==:=== ===:=== ====:=== +:==== =:==== ==:==== ===:==== ====:==== + +! =! ==! ===! ====! +!= =!= ==!= ===!= ====!= +!== =!== ==!== ===!== ====!== +!=== =!=== ==!=== ===!=== ====!=== +!==== =!==== ==!==== ===!==== ====!==== + +<< =<< ==<< ===<< ====<< +<<= =<<= ==<<= ===<<= ====<<= +<<== =<<== ==<<== ===<<== ====<<== +<<=== =<<=== ==<<=== ===<<=== ====<<=== +<<==== =<<==== ==<<==== ===<<==== ====<<==== + +>> =>> ==>> ===>> ====>> +>>= =>>= ==>>= ===>>= ====>>= +>>== =>>== ==>>== ===>>== ====>>== +>>=== =>>=== ==>>=== ===>>=== ====>>=== +>>==== =>>==== ==>>==== ===>>==== ====>>==== + +|| =|| ==|| ===|| ====|| +||= =||= ==||= ===||= ====||= +||== =||== ==||== ===||== ====||== +||=== =||=== ==||=== ===||=== ====||=== +||==== =||==== ==||==== ===||==== ====||==== + +// =// ==// ===// ====// +//= =//= ==//= ===//= ====//= +//== =//== ==//== ===//== ====//== +//=== =//=== ==//=== ===//=== ====//=== +//==== =//==== ==//==== ===//==== ====//==== + +:: =:: ==:: ===:: ====:: +::= =::= ==::= ===::= ====::= +::== =::== ==::== ===::== ====::== +::=== =::=== ==::=== ===::=== ====::=== +::==== =::==== ==::==== ===::==== ====::==== + +!! =!! ==!! ===!! ====!! +!!= =!!= ==!!= ===!!= ====!!= +!!== =!!== ==!!== ===!!== ====!!== +!!=== =!!=== ==!!=== ===!!=== ====!!=== +!!==== =!!==== ==!!==== ===!!==== ====!!==== + +<<< =<<< ==<<< ===<<< ====<<< +<<<= =<<<= ==<<<= ===<<<= ====<<<= +<<<== =<<<== ==<<<== ===<<<== ====<<<== +<<<=== =<<<=== ==<<<=== ===<<<=== ====<<<=== +<<<==== =<<<==== ==<<<==== ===<<<==== ====<<<==== + +>>> =>>> ==>>> ===>>> ====>>> +>>>= =>>>= ==>>>= ===>>>= ====>>>= +>>>== =>>>== ==>>>== ===>>>== ====>>>== +>>>=== =>>>=== ==>>>=== ===>>>=== ====>>>=== +>>>==== =>>>==== ==>>>==== ===>>>==== ====>>>==== + +||| =||| ==||| ===||| ====||| +|||= =|||= ==|||= ===|||= ====|||= +|||== =|||== ==|||== ===|||== ====|||== +|||=== =|||=== ==|||=== ===|||=== ====|||=== +|||==== =|||==== ==|||==== ===|||==== ====|||==== + +/// =/// ==/// ===/// ====/// +///= =///= ==///= ===///= ====///= +///== =///== ==///== ===///== ====///== +///=== =///=== ==///=== ===///=== ====///=== +///==== =///==== ==///==== ===///==== ====///==== + +::: =::: ==::: ===::: ====::: +:::= =:::= ==:::= ===:::= ====:::= +:::== =:::== ==:::== ===:::== ====:::== +:::=== =:::=== ==:::=== ===:::=== ====:::=== +:::==== =:::==== ==:::==== ===:::==== ====:::==== + +!!! =!!! ==!!! ===!!! ====!!! +!!!= =!!!= ==!!!= ===!!!= ====!!!= +!!!== =!!!== ==!!!== ===!!!== ====!!!== +!!!=== =!!!=== ==!!!=== ===!!!=== ====!!!=== +!!!==== =!!!==== ==!!!==== ===!!!==== ====!!!==== + +# Underscore lines + +_ __ ___ ____ +_|_ __|_ _|__ __|__ +_| |_ _||_ __| ___| |__ |___ + +# Numbersign lines + +# ## ### #### ##### ###### + +# Progress bars + +[...........] [-----------]  +[#..........] [>----------]  +[##.........] [=>---------]  +[###........] [==>--------]  +[####.......] [===>-------]  +[#####......] [====>------]  +[######.....] [=====>-----]  +[#######....] [======>----]  +[########...] [=======>---]  +[#########..] [========>--]  +[##########.] [=========>-]  +[###########] [==========>]  + +# Sanity check + +- -- --- |> <| ||> <|| |||> <||| ->> >-> -<=< <<= <== <=> => ==> =>> >=> - >>= >>- >- <~> -< -<< =<< - <~~ <~ ~~ ~> ~~> - - <<< << <= <> >= >> >>> - {. {| [| <: ✓ :> |] |} .} - <||| <|| <| <|> |> ||> |||> - - <$ <$> $> - <+ <+> +> - <* <*> *> - - \ \\ /* */ /// // - --> /> - 0xF 9:45 m-x *ptr www - - ;; :: ::: !! ?? %% && - || .. ... ..< .? ?. ?: - -- --- ++ +++ ** *** - - ~= ~- -~ ~@ - ^= ?= /= /== - -| _|_ |- |= ||= - #! #= ## ### #### - #{ #[ ]# #( #? #_ #_( - - -a*b a*A B*b A*B *a *A a* A* -a-b a-A B-b A-B -a -A a- A- -a+b a+A B+b A+B +a +A a+ A+ -a:b a:A B:b A:B :a :A a: A: \ No newline at end of file diff --git a/showcases/swift.png b/showcases/swift.png deleted file mode 100644 index f099242a05..0000000000 Binary files a/showcases/swift.png and /dev/null differ