├── .gitignore ├── .travis.yml ├── Makefile ├── Readme.md ├── lib └── index.js ├── package.json └── test ├── fixtures ├── basic │ ├── expected │ │ └── index.html │ └── src │ │ └── index.html ├── custom │ ├── expected │ │ └── index.html │ └── src │ │ └── index.html └── untouched │ ├── expected │ └── index.html │ └── src │ └── index.html └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test/**/build -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | node_modules: package.json 3 | @npm install 4 | 5 | test: node_modules 6 | @./node_modules/.bin/mocha --reporter spec 7 | 8 | .PHONY: test -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # metalsmith-typography [](https://travis-ci.org/algenon/metalsmith-typography) 3 | 4 | A Metalsmith plugin to enhance typography in HTML — abbreviations, quotes and dashes, non-breaking spaces after prepositions. Based on [Richtypo.js](https://github.com/sapegin/richtypo.js). 5 | 6 | ## Installation 7 | 8 | $ npm install metalsmith-typography 9 | 10 | ## CLI Usage 11 | 12 | Install via npm and then add the `metalsmith-typography` key to your `metalsmith.json` plugins: 13 | 14 | ```json 15 | { 16 | "plugins": { 17 | "metalsmith-typography": { 18 | "lang": "en" 19 | } 20 | } 21 | } 22 | ``` 23 | 24 | ## Javascript Usage 25 | 26 | Pass `options` to the typography plugin and pass it to Metalsmith with the `use` method: 27 | 28 | ```js 29 | var typography = require('metalsmith-typography'); 30 | 31 | metalsmith.use(typography({ 32 | lang: "en" 33 | })); 34 | ``` 35 | 36 | Call it after the `metalsmith-markdown` plugin, so that HTML files are available. 37 | 38 | ## Options 39 | 40 | `lang` determines which language to use. `en` and `ru` supported, `en` is the default. 41 | 42 | `rules` is an array of typographic rules to apply. Default is 43 | ```javascript 44 | ['save_tags', 'cleanup_before', 'lite', 'spaces_lite', 'spaces', 'quotes', 'abbrs', 'cleanup_after', 'restore_tags'] 45 | ``` 46 | See [Richtypo.js documentation](https://github.com/sapegin/richtypo.js) for the list of available rules. 47 | 48 | ## License 49 | 50 | MIT 51 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var debug = require('debug')('metalsmith-typography'); 4 | var extname = require('path').extname; 5 | var richtypo = require('richtypo'); 6 | 7 | /** 8 | * Expose `plugin`. 9 | */ 10 | 11 | module.exports = plugin; 12 | 13 | /** 14 | * Typography rules 15 | */ 16 | var DEFAULT_RULES = ['save_tags', 'cleanup_before', 'lite', 'spaces_lite', 'spaces', 'quotes', 'abbrs', 'cleanup_after', 'restore_tags']; 17 | 18 | /** 19 | * Metalsmith plugin to enhance typography in HTML. 20 | * 21 | * @param {Object} options (optional) 22 | * @property {String} lang 23 | * @property {Array} rules 24 | * @return {Function} 25 | */ 26 | 27 | function plugin(options){ 28 | options = options || {}; 29 | if (options.lang) richtypo.lang(options.lang); 30 | var rules = options.rules || DEFAULT_RULES; 31 | 32 | return function(files, metalsmith, done){ 33 | setImmediate(done); 34 | Object.keys(files).forEach(function(file){ 35 | debug('checking file: %s', file); 36 | if (!isHtml(file)) return; 37 | var data = files[file]; 38 | debug('applying typography rules to file: %s', file); 39 | var str = richtypo.richtypo(data.contents.toString(), rules); 40 | data.contents = new Buffer(str); 41 | files[file] = data; 42 | }); 43 | }; 44 | } 45 | 46 | /** 47 | * Check if a `file` is HTML. 48 | * 49 | * @param {String} file 50 | * @return {Boolean} 51 | */ 52 | 53 | function isHtml(file){ 54 | return /\.html?/.test(extname(file)); 55 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metalsmith-typography", 3 | "version": "0.1.1", 4 | "description": "A Metalsmith plugin to enhance typography — hanging punctuation, abbreviations, quotes and dashes", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "make test" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/algenon/metalsmith-typography.git" 12 | }, 13 | "keywords": [ 14 | "metalsmith", 15 | "typography", 16 | "punctuation" 17 | ], 18 | "author": { 19 | "name": "Anton Zhiyanov", 20 | "email": "m@antonz.ru", 21 | "url": "http://antonz.ru" 22 | }, 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/algenon/metalsmith-typography/issues" 26 | }, 27 | "homepage": "https://github.com/algenon/metalsmith-typography", 28 | "dependencies": { 29 | "debug": "~0.7.4", 30 | "richtypo": "~0.1.8" 31 | }, 32 | "devDependencies": { 33 | "assert-dir-equal": "0.x", 34 | "metalsmith": "0.x", 35 | "mocha": "1.x" 36 | } 37 | } -------------------------------------------------------------------------------- /test/fixtures/basic/expected/index.html: -------------------------------------------------------------------------------- 1 |
Welcome to the world of beautiful web typography — only with Richtypo. OMG, it's truly awesome, I take it
4 | # Here is my precious code, which should be left untouched 5 | var text = "Awesome Web Typography with 'Richtypo'"; 6 |-------------------------------------------------------------------------------- /test/fixtures/basic/src/index.html: -------------------------------------------------------------------------------- 1 |
Welcome to the world of beautiful web typography - only with Richtypo. OMG, it's truly awesome, I take it 3-5 times a day.
3 |4 | # Here is my precious code, which should be left untouched 5 | var text = "Awesome Web Typography with 'Richtypo'"; 6 |-------------------------------------------------------------------------------- /test/fixtures/custom/expected/index.html: -------------------------------------------------------------------------------- 1 |
Welcome to the world of beautiful web typography — only with Richtypo. OMG, it's truly awesome, I take it 3-5 times a day.
-------------------------------------------------------------------------------- /test/fixtures/custom/src/index.html: -------------------------------------------------------------------------------- 1 |Welcome to the world of beautiful web typography - only with Richtypo. OMG, it's truly awesome, I take it 3-5 times a day.
-------------------------------------------------------------------------------- /test/fixtures/untouched/expected/index.html: -------------------------------------------------------------------------------- 1 |Welcome to the world of beautiful web typography — only with Richtypo. OMG, it's truly awesome, I take it
Welcome to the world of beautiful web typography — only with Richtypo. OMG, it's truly awesome, I take it 3-5 times a day.
-------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var equal = require('assert-dir-equal'); 5 | var Metalsmith = require('metalsmith'); 6 | var typography = require('..'); 7 | 8 | function check(name, settings, done) { 9 | var path = 'test/fixtures/' + name; 10 | Metalsmith(path) 11 | .use(settings) 12 | .build(function(err){ 13 | if (err) return done(err); 14 | equal(path + '/expected', path + '/build'); 15 | done(); 16 | }); 17 | } 18 | 19 | describe('metalsmith-typography', function(){ 20 | it('should enhance typography', function(done){ 21 | check('basic', typography({ 22 | lang: "en" 23 | }), done); 24 | }); 25 | 26 | it('should leave already typographed text untouched', function(done){ 27 | check('untouched', typography({ 28 | lang: "en" 29 | }), done); 30 | }); 31 | 32 | it('should work with custom typography rules', function(done){ 33 | check('custom', typography({ 34 | lang: "en", 35 | rules: ['save_tags', 'cleanup_before', 'lite', 'quotes', 'cleanup_after', 'restore_tags'] 36 | }), done); 37 | }); 38 | }); --------------------------------------------------------------------------------