-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2847 from LabhanshAgrawal/ligatures-addon
Merge ligatures addon into core repo
- Loading branch information
Showing
19 changed files
with
1,184 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
node_modules/ | ||
.nyc_output/ | ||
coverage/ | ||
|
||
lib/ | ||
fonts/ | ||
|
||
.env | ||
.vscode/ | ||
*.swp | ||
*.tgz | ||
npm-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Blacklist - exclude everything except npm defaults such as LICENSE, etc | ||
* | ||
!*/ | ||
|
||
# Whitelist - entries to be included must be negated with "!" | ||
!*.js | ||
!*.json | ||
|
||
# Whitelist - lib/ | ||
!lib/**/*.d.ts | ||
|
||
!lib/**/*.js | ||
!lib/**/*.js.map | ||
|
||
# Whitelist - out/ | ||
!out/**/*.d.ts | ||
|
||
!out/**/*.js | ||
!out/**/*.js.map | ||
|
||
# Whitelist - src/ | ||
!src/**/*.ts | ||
!src/**/*.d.ts | ||
|
||
!src/**/*.js | ||
!src/**/*.js.map | ||
|
||
# Whitelist - typings/ | ||
!typings/**/*.d.ts | ||
|
||
# Blacklist - (normal behavior) these will override any whitelist | ||
*.test.ts | ||
*.test.d.ts | ||
*.test.js | ||
*.test.js.map | ||
|
||
docs/ | ||
/.idea/ | ||
.vscode/ | ||
coverage/ | ||
.nyc_output/ | ||
fonts/ | ||
|
||
**/*.api.js | ||
**/*.api.ts | ||
tsconfig.json | ||
.yarnrc | ||
webpack.config.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
## xterm-addon-ligatures | ||
|
||
Add support for programming ligatures to [xterm.js] when running in environments with access to [Node.js] APIs (such as [Electron]). | ||
|
||
### Requirements | ||
|
||
* [Node.js] 8.x or higher (present in [Electron] 1.8.3 or higher) | ||
* [xterm.js] 4.0.0 or higher using the default canvas renderer | ||
|
||
### Install | ||
|
||
```bash | ||
npm install --save xterm-addon-ligatures | ||
``` | ||
|
||
### Usage | ||
|
||
```ts | ||
import { Terminal } from 'xterm'; | ||
import { LigaturesAddon } from 'xterm-addon-ligatures'; | ||
|
||
const terminal = new Terminal(); | ||
const ligaturesAddon = new LigaturesAddon(); | ||
terminal.open(containerElement); | ||
terminal.loadAddon(ligaturesAddon); | ||
``` | ||
|
||
### How It Works | ||
|
||
In a browser environment, font ligature information is read directly by the web browser and used to render text correctly without any intervention from the developer. As of version 3, xterm.js uses the canvas to render characters individually, resulting in a significant performance boost. However, this means that it can no longer lean on the browser to determine when to draw font ligatures. | ||
|
||
This package locates the font file on disk for the font currently in use by the terminal and parses the ligature information out of it (via the [font-ligatures] package). As text is rendered in xterm.js, this package annotates it with the locations of ligatures, allowing xterm.js to render it correctly. | ||
|
||
Since this package depends on being able to find and resolve a system font from disk, it has to have system access that isn't available in the web browser. As a result, this package is mainly useful in environments that combine browser and Node.js runtimes (such as [Electron]). | ||
|
||
### Fonts | ||
|
||
This package makes use of the following fonts for testing: | ||
|
||
* [Fira Code][Fira Code] - [Licensed under the OFL][Fira Code License] by Nikita | ||
Prokopov, Mozilla Foundation with reserved names Fira Code, Fira Mono, and | ||
Fira Sans | ||
* [Iosevka] - [Licensed under the OFL][Iosevka License] by Belleve Invis with | ||
reserved name Iosevka | ||
|
||
[xterm.js]: https://github.com/xtermjs/xterm.js | ||
[Electron]: https://electronjs.org/ | ||
[Node.js]: https://nodejs.org/ | ||
[font-ligatures]: https://github.com/princjef/font-ligatures | ||
[Fira Code]: https://github.com/tonsky/FiraCode | ||
[Fira Code License]: https://github.com/tonsky/FiraCode/blob/master/LICENSE | ||
[Iosevka]: https://github.com/be5invis/Iosevka | ||
[Iosevka License]: https://github.com/be5invis/Iosevka/blob/master/LICENSE.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Copyright (c) 2018 The xterm.js authors. All rights reserved. | ||
* @license MIT | ||
*/ | ||
|
||
const fs = require('fs'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
|
||
const axios = require('axios').default; | ||
const mkdirp = require('mkdirp'); | ||
const yauzl = require('yauzl'); | ||
|
||
const urls = { | ||
fira: 'https://github.com/tonsky/FiraCode/raw/master/distr/otf/FiraCode-Regular.otf', | ||
iosevka: 'https://github.com/be5invis/Iosevka/releases/download/v1.14.3/01-iosevka-1.14.3.zip' | ||
}; | ||
|
||
const writeFile = util.promisify(fs.writeFile); | ||
const fontsFolder = path.join(__dirname, '../fonts'); | ||
|
||
async function download() { | ||
await mkdirp(fontsFolder); | ||
|
||
await downloadFiraCode(); | ||
await downloadIosevka(); | ||
|
||
console.log('Loaded all fonts for testing') | ||
} | ||
|
||
async function downloadFiraCode() { | ||
const file = path.join(fontsFolder, 'firaCode.otf'); | ||
if (await util.promisify(fs.exists)(file)) { | ||
console.log('Fira Code already loaded'); | ||
} else { | ||
console.log('Downloading Fira Code...'); | ||
await writeFile( | ||
file, | ||
(await axios.get(urls.fira, { responseType: 'arraybuffer' })).data | ||
); | ||
} | ||
} | ||
|
||
async function downloadIosevka() { | ||
const file = path.join(fontsFolder, 'iosevka.ttf'); | ||
if (await util.promisify(fs.exists)(file)) { | ||
console.log('Iosevka already loaded'); | ||
} else { | ||
console.log('Downloading Iosevka...'); | ||
const iosevkaContents = (await axios.get(urls.iosevka, { responseType: 'arraybuffer' })).data; | ||
const iosevkaZipfile = await util.promisify(yauzl.fromBuffer)(iosevkaContents); | ||
await new Promise((resolve, reject) => { | ||
iosevkaZipfile.on('entry', entry => { | ||
if (entry.fileName === 'ttf/iosevka-regular.ttf') { | ||
iosevkaZipfile.openReadStream(entry, (err, stream) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
|
||
const writeStream = fs.createWriteStream(file); | ||
stream.pipe(writeStream); | ||
writeStream.on('close', () => resolve()); | ||
}); | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
download(); | ||
|
||
process.on('unhandledRejection', e => { | ||
console.error(e); | ||
process.exit(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "xterm-addon-ligatures", | ||
"version": "0.2.1", | ||
"description": "Add support for programming ligatures to xterm.js", | ||
"author": { | ||
"name": "The xterm.js authors", | ||
"url": "https://xtermjs.org/" | ||
}, | ||
"main": "lib/xterm-addon-ligatures.js", | ||
"types": "typings/xterm-addon-ligatures.d.ts", | ||
"repository": "https://github.com/xtermjs/xterm.js", | ||
"engines": { | ||
"node": ">8.0.0" | ||
}, | ||
"scripts": { | ||
"prepare": "node bin/download-fonts.js", | ||
"build": "tsc -p src", | ||
"watch": "tsc -w -p src", | ||
"prepackage": "npm run build", | ||
"package": "webpack", | ||
"pretest": "npm run build", | ||
"test": "nyc mocha out/**/*.test.js", | ||
"prepublish": "npm run package" | ||
}, | ||
"keywords": [ | ||
"font", | ||
"ligature", | ||
"xterm", | ||
"xterm.js", | ||
"terminal" | ||
], | ||
"license": "MIT", | ||
"dependencies": { | ||
"font-finder": "^1.0.4", | ||
"font-ligatures": "^1.3.2" | ||
}, | ||
"devDependencies": { | ||
"@types/sinon": "^5.0.1", | ||
"axios": "^0.18.0", | ||
"mkdirp": "^0.5.1", | ||
"sinon": "^6.1.3", | ||
"yauzl": "^2.10.0" | ||
}, | ||
"peerDependencies": { | ||
"xterm": "^4.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* Copyright (c) 2018 The xterm.js authors. All rights reserved. | ||
* @license MIT | ||
*/ | ||
|
||
import { Terminal } from 'xterm'; | ||
import { enableLigatures } from '.'; | ||
|
||
export interface ITerminalAddon { | ||
activate(terminal: Terminal): void; | ||
dispose(): void; | ||
} | ||
|
||
export class LigaturesAddon implements ITerminalAddon { | ||
constructor() {} | ||
|
||
public activate(terminal: Terminal): void { | ||
enableLigatures(terminal); | ||
} | ||
|
||
public dispose(): void {} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Copyright (c) 2018 The xterm.js authors. All rights reserved. | ||
* @license MIT | ||
*/ | ||
|
||
import * as fontFinder from 'font-finder'; | ||
import * as fontLigatures from 'font-ligatures'; | ||
|
||
import parse from './parse'; | ||
|
||
let fontsPromise: Promise<fontFinder.FontList> | undefined = undefined; | ||
|
||
/** | ||
* Loads the font ligature wrapper for the specified font family if it could be | ||
* resolved, throwing if it is unable to find a suitable match. | ||
* @param fontFamily The CSS font family definition to resolve | ||
* @param cacheSize The size of the ligature cache to maintain if the font is resolved | ||
*/ | ||
export default async function load(fontFamily: string, cacheSize: number): Promise<fontLigatures.Font | undefined> { | ||
if (!fontsPromise) { | ||
fontsPromise = fontFinder.list(); | ||
} | ||
|
||
const fonts = await fontsPromise; | ||
for (const family of parse(fontFamily)) { | ||
// If we reach one of the generic font families, the font resolution | ||
// will end for the browser and we can't determine the specific font | ||
// used. Throw. | ||
if (genericFontFamilies.includes(family)) { | ||
return undefined; | ||
} | ||
|
||
if (fonts.hasOwnProperty(family) && fonts[family].length > 0) { | ||
return await fontLigatures.loadFile(fonts[family][0].path, { cacheSize }); | ||
} | ||
} | ||
|
||
// If none of the fonts could resolve, throw an error | ||
return undefined; | ||
} | ||
|
||
// https://drafts.csswg.org/css-fonts-4/#generic-font-families | ||
const genericFontFamilies = [ | ||
'serif', | ||
'sans-serif', | ||
'cursive', | ||
'fantasy', | ||
'monospace', | ||
'system-ui', | ||
'emoji', | ||
'math', | ||
'fangsong' | ||
]; |
Oops, something went wrong.