• Stars
    star
    318
  • Rank 131,872 (Top 3 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 12 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🔤 Microtypography fixer for the web

JoliTypo – Web Microtypography fixer

Finally a tool for typography nerds.

JoliTypo is a tool fixing Microtypography glitches inside your HTML content.

use JoliTypo\Fixer;

$fixer = new Fixer(array('Ellipsis', 'Dash', 'SmartQuotes', 'CurlyQuote', 'Hyphen'));
$fixedContent = $fixer->fix('<p>"Tell me Mr. Anderson... what good is a phone call... if you\'re unable to speak?" -- Agent Smith, <em>Matrix</em>.</p>');
<p>&ldquo;Tell me Mr. Ander&shy;son&hellip; what good is a phone call&hellip; if you&rsquo;re unable to speak?&rdquo;&mdash;Agent Smith, <em>Matrix</em>.</p>

“Tell me Mr. Anderson… what good is a phone call… if you’re unable to speak?”—Agent Smith, Matrix.

It's designed to be:

  • language agnostic (you can fix fr_FR, fr_CA, en_US... You tell JoliTypo what to fix);
  • easy to integrate into modern PHP projects (composer and autoload);
  • robust (make use of \DOMDocument instead of parsing HTML with dummy regexp);
  • smart enough to avoid Javascript, Code, CSS processing... (configurable protected tags list);
  • fully tested;
  • fully open and usable in any project (MIT License).

You can try it with the online demo!

Latest Stable Version

Quick usage

Just tell the Fixer class which Fixer you want to run on your content and then, call fix():

use JoliTypo\Fixer;

$fixer = new Fixer(array("SmartQuotes", "FrenchNoBreakSpace"));
$fixer->setLocale('fr_FR');
$fixedContent = $fixer->fix('<p>Je suis "très content" de t\'avoir invité sur <a href="http://jolicode.com/">Jolicode.com</a> !</p>');

For your ease of use, you can find ready to use list of Fixer for your language here. Micro-typography is nothing like a standard or a law, what really matters is consistency, so feel free to use your own lists.

Please be advised that JoliTypo works best on HTML content; it will also work on plain text, but will be less smart about smart quotes. When fixing a complete HTML document, potential <head>, <html> and <body> tags may be removed.

To fix non HTML content, use the fixString() method:

use JoliTypo\Fixer;

$fixer = new Fixer(array("Trademark", "SmartQuotes"));
$fixedContent = $fixer->fixString('Here is a "protip(c)"!'); // Here is a “protip©”!

CLI usage

You can run a standalone version of JoliTypo by downloading the PHAR version

Run jolitypo --help to know how to configure the Fixer.

Installation

Requirements are handled by Composer (libxml and mbstring are required).

composer require jolicode/jolitypo

Usage outside composer is also possible, just add the src/ directory to any PSR-0 compatible autoloader.

Integrations

Available Fixers

Dash

Replaces the simple dash - by a ndash between numbers (dates ranges...) and the double -- by a mdash .

Dimension

Replaces the letter x between numbers (12 x 123) by a times entity (×, the real mathematical symbol).

Ellipsis

Replaces the three dots ... by an ellipsis .

SmartQuotes

Converts dumb quotes " " to all kinds of smart style quotation marks (“ ”, « », „ “...). Handles a good variety of locales, like English, Arabic, French, Italian, Spanish, Irish, German...

See the code for more details, and do not forget to specify a locale on the Fixer instance.

This Fixer replaces legacy EnglishQuotes, FrenchQuotes and GermanQuotes.

FrenchNoBreakSpace

Replaces some classic spaces by non-breaking spaces following the French typographic code. No break space are placed before :, thin no break space before ;, ! and ?.

NoSpaceBeforeComma

Removes space before , and makes sure there is only one space after.

Hyphen (automatic hyphenation)

Makes use of org_heigl/hyphenator, a tool enabling word-hyphenation in PHP. This Hyphenator uses the pattern-files from OpenOffice which are based on the pattern-files created for TeX.

There are only some locales available for this fixer: af_ZA, ca, da_DK, de_AT, de_CH, de_DE, en_GB, en_UK, et_EE, fr, hr_HR, hu_HU, it_IT, lt_LT, nb_NO, nn_NO, nl_NL, pl_PL, pt_BR, ro_RO, ru_RU, sk_SK, sl_SI, sr, zu_ZA.

You can read more about this fixer on the official github repository.

This Fixer requires a Locale to be set on the Fixer with $fixer->setLocale('fr_FR');. Default to en_GB.

Proper hyphenation is mandatory in justified text and you should avoid word breaking in titles with this line of CSS: hyphens:none;.

Be aware that the current screen readers are unable to spell correctly the words containing &shy; tags. The Hyphen filter should therefore be used with caution or you might reduce your website's accessibility.

CurlyQuote (Smart Quote)

Replaces straight quotes ' with curly ones . There is one exception to consider: foot and inch marks (minutes and second marks). Purists use prime , this fixer uses straight quotes for compatibility. Read more about Curly quotes.

Trademark

Handles trade­mark symbol , a registered trade­mark symbol ®, and a copy­right symbol ©. This fixer replaces commonly used approximations: (r), (c) and (TM). A non-breaking space is put between numbers and copyright symbols too.

Unit (formerly Numeric)

Adds a non-breaking space between a numeral and its unit. Like this: 12_h, 42_฿ or 88_%. It was named Numeric before release 1.0.2, but BC is kept for now.

It is really easy to make your own Fixers, feel free to extend the provided ones if they do not fit your typographic rules.

Fixer recommendations by locale

en_GB

$fixer = new Fixer(array('Ellipsis', 'Dimension', 'Unit', 'Dash', 'SmartQuotes', 'NoSpaceBeforeComma', 'CurlyQuote', 'Hyphen', 'Trademark'));
$fixer->setLocale('en_GB');

fr_FR

Those rules apply for most of the recommendations of "Abrégé du code typographique à l'usage de la presse", ISBN: 9782351130667.

$fixer = new Fixer(array('Ellipsis', 'Dimension', 'Unit', 'Dash', 'SmartQuotes', 'FrenchNoBreakSpace', 'NoSpaceBeforeComma', 'CurlyQuote', 'Hyphen', 'Trademark'));
$fixer->setLocale('fr_FR');

fr_CA

Mostly the same as fr_FR, but the space before punctuation points is not mandatory.

$fixer = new Fixer(array('Ellipsis', 'Dimension', 'Unit', 'Dash', 'SmartQuotes', 'NoSpaceBeforeComma', 'CurlyQuote', 'Hyphen', 'Trademark'));
$fixer->setLocale('fr_CA');

de_DE

Mostly the same as en_GB, according to Typefacts and Wikipedia.

$fixer = new Fixer(array('Ellipsis', 'Dimension', 'Unit', 'Dash', 'SmartQuotes', 'NoSpaceBeforeComma', 'CurlyQuote', 'Hyphen', 'Trademark'));
$fixer->setLocale('de_DE');

More to come (contributions welcome!).

Documentation

Default usage

$fixer        = new Fixer(array('Ellipsis', 'Dimension', 'Dash', 'SmartQuotes', 'CurlyQuote', 'Hyphen'));
$fixedContent = $fixer->fix("<p>Some user contributed HTML which does not use proper glyphs.</p>");

$fixer->setRules(array('CurlyQuote'));
$fixedContent = $fixer->fix("<p>I'm only replacing single quotes.</p>");

$fixer->setRules(array('Hyphen'));
$fixer->setLocale('en_GB'); // I tell which locale to use for Hyphenation and SmartQuotes
$fixedContent = $fixer->fix("<p>Very long words like Antidisestablishmentarianism.</p>");

Define your own Fixer

If you want to add your own Fixer to the list, you have to implement JoliTypo\FixerInterface. Then just give JoliTypo their fully qualified name, or even instance:

// by FQN
$fixer        = new Fixer(array('Ellipsis', 'Acme\\YourOwn\\TypoFixer'));
$fixedContent = $fixer->fix("<p>Content fixed by the 2 fixers.</p>");

// or instances, or both
$fixer        = new Fixer(array('Ellipsis', 'Acme\\YourOwn\\TypoFixer', new Acme\\YourOwn\\PonyFixer("Some parameter")));
$fixedContent = $fixer->fix("<p>Content fixed by the 3 fixers.</p>");

Configure the protected tags

Protected tags is a list of HTML tag names that the DOM parser must avoid. Nothing in those tags will be fixed.

$fixer        = new Fixer(array('Ellipsis'));
$fixer->setProtectedTags(array('pre', 'a'));
$fixedContent = $fixer->fix("<p>Fixed...</p> <pre>Not fixed...</pre> <p>Fixed... <a>Not Fixed...</a>.</p>");

Add your own Fixer / Contribute a Fixer

  • Write tests;
  • A Fixer is run on a piece of text, no HTML to deal with;
  • Implement JoliTypo\FixerInterface;
  • Send your Pull request.

Contribution guidelines

  • You MUST write code in english;
  • you MUST follow PSR2 and Symfony coding standard (run composer cs on your branch);
  • you MUST run the tests (run composer test);
  • you MUST comply to the MIT license;
  • you SHOULD write documentation.

If you add a new Fixer, please provide sources and references about the typographic rule you want to fix.

Compatibility & OS support restrictions

  • Windows XP : Thin No-Break Space can't be used, all other spaces are ignored, but they do not look bad (normal space).
  • Mac OS Snow Leopard : no no-break space, half no-break space, ems and en-dash but doesn't look bad (normal space).

BUT if you use a font (@font-face maybe) that contains all those glyphs, there will be no issues.

There is a known issue preventing JoliTypo to work correctly with APC versions older than 3.1.11.

What can you do to help?

We need to be able to use this tool everywhere, you can help by providing:

  • Wordpress plugin (to replace or complete wptexturize)
  • Dotclear plugin ...

Also, there is a Todo list 😙

License

This piece of code is under MIT License. See the LICENSE file.

Alternatives and other implementations

There is already quite a bunch of tools like this one (including good ones). Sadly, some are only for one language, some are running regexp on the whole HTML code (which is bad), some are not tested, some are bundled inside a CMS or a Library, some are not using proper auto-loading, some do not have an open bug tracker... Have a look by yourself:

Glossary & References

Thanks to theses online resources for helping a developer understand typography:

More Repositories

1

JoliNotif

💻 Send notifications to your desktop directly from your PHP script
PHP
1,324
star
2

JoliCi

✅ JoliCi - Run your TravisCi builds locally
PHP
657
star
3

castor

🦫 DX oriented task runner and command launcher built with PHP.
PHP
406
star
4

elasticsearch-cheatsheet

🔎 Elasticsearch is awesome, here is a cheatsheet for it.
HTML
339
star
5

docker-starter

🏗️ A skeleton to start a new web project with PHP, Docker and Castor
PHP
335
star
6

elastically

🔍 JoliCode's Elastica wrapper to bootstrap Elasticsearch PHP integrations
PHP
241
star
7

slack-php-api

#️⃣ PHP Slack Client based on the official OpenAPI specification
PHP
219
star
8

emoji-search

😄 Emoji synonyms to build your own emoji-capable search engine (elasticsearch, solr, OpenSearch)
PHP
215
star
9

secret-santa

🎅 The code behind Secret Santa, the holiday bot for Slack / Discord / Webex
PHP
213
star
10

GifExceptionBundle

😛 The GhostBuster of your exception page!
PHP
205
star
11

php-ar-drone

🚁 Port of node-ar-drone which allows user to control a Parrot AR Drone over PHP
PHP
204
star
12

composer-cheatsheet

📋 Everything you have to know about composer.json in one page.
HTML
146
star
13

automapper

🚀 Very FAST 🚀 PHP AutoMapper with on the fly code generation
PHP
130
star
14

generator-joli-symfony

👨 Yeoman Generator for Symfony2 projects with sensible defaults and frontend tools.
JavaScript
100
star
15

asynit

🌠 Asynchronous HTTP Request Testing Library for API or more...
PHP
77
star
16

Alloy-PullToRefresh

Pull to refresh widget for Titanium Alloy applications.
JavaScript
55
star
17

Badass-Pageflow

📲 A simple Alloy "pageflow" widget, which allows to open windows w/ styles back buttons. Features a complete a simple API.
JavaScript
44
star
18

ffi-uuid

Binding of the libuuid library with PHP thanks to PHP/FFI.
PHP
39
star
19

docker-images

🚢 Basic images for different usages
Makefile
33
star
20

pomdok

🍏 Simple wrapper to Symfony Go Binary for multi-app
Go
27
star
21

qotd

PHP
25
star
22

codingstyle

💅 JoliCode's base dotfile for PHP / JS projects
PHP
24
star
23

chef-cookbook-php

A Chef Cookbook for PHP, does not depend on apache and will not use or install pear like the official one.
Ruby
23
star
24

harvest-php-api

🌾 A Harvest API PHP Client
PHP
22
star
25

starfleet

🚀 Share your conferences activity to your buddies
PHP
20
star
26

php7-checker

☑️ PHP7 checker
PHP
18
star
27

Harvest-Forecast-tools

📅 Some useful additions to https://www.getharvest.com/ and https://www.getharvest.com/forecast
JavaScript
16
star
28

symfony-jwt-article

PHP
16
star
29

seo-override

🏁 Override your SEO related markup on the fly
PHP
14
star
30

harvest-openapi-generator

🔮 Transforms Harvest API HTML documentation pages into a valid Swagger / OpenAPI 3.0 specification
PHP
13
star
31

JoliTypoBundle

🔤 Integration of JoliTypo for Symfony2 (deprecated, use the provided bridge instead)
PHP
13
star
32

forecast-tools

⛅ Tools to get the most out of Harvest Forecast. Get Slack notifications, schedule Slack stand-up meetings, share public Forecasts, and more
PHP
13
star
33

JoliMarkdown

✍ A syntax fixer for markdown content
PHP
12
star
34

Symfony2BackboneDemo

JavaScript
12
star
35

symfony-security-article

PHP
12
star
36

php-os-helper

Provides helpers to detect OS of the machine where PHP is running.
PHP
12
star
37

monologue

A bot to manage "monologue" rule in a Slack Channel
PHP
10
star
38

ApacheTikaBundle

📁 Symfony Bundle for https://github.com/vaites/php-apache-tika
PHP
10
star
39

elasticsearch-php-benchmark

Benchmark of some PHP Clients for Elasticsearch
PHP
10
star
40

Reepo

Abstraction of repository providers (github, gitlab, redmine, ...)
PHP
9
star
41

symfony2-eventdispatcher-extension

Symfony2 Event Dispatcher as PHP extension written with Zephir
C
9
star
42

JoliToken

🔍 Elasticsearch plugin to visualize field tokens as analyzed by Lucene
JavaScript
9
star
43

isready-symfony2

Symfony2 production checklist for http://isready.org
7
star
44

best-bundle-conf

Symfony Live Paris 2013 talk about the best and unknown Symfony2 Bundles (in French)
JavaScript
7
star
45

JoliSnap

JavaScript
6
star
46

100-async-0-callback-conf

✨ https://jolicode.github.io/100-async-0-callback-conf/#/0
JavaScript
6
star
47

webhook-demo

PHP
6
star
48

unicode-conf

😋 Unicode, PHP et la sécurité
JavaScript
5
star
49

forecast-php-api

⛅ A Forecastapp API PHP Client
PHP
5
star
50

GouvCamp-mobile

Mobile app for the GouvCamp 2012
JavaScript
5
star
51

SecurityBundle-avec-de-l-aspirine

JavaScript
4
star
52

react-et-symfony-conf

💍 Marier React et Symfony
HTML
4
star
53

value-object-conf

💻 Slides from Forum PHP 2015 talk about Value Object
HTML
4
star
54

everything-titanium-using-the-cli-talk

Slides of the TiConf Amsterdam 2014 about using CLI tools in the Titanium world.
JavaScript
4
star
55

symfony-htmx-demo

Small Symfony project with HTMX and AssetMapper
PHP
3
star
56

lab-webgl-home

Jolicode website homepage in 3D
JavaScript
3
star
57

jolitypo-website

✍️ Sample app to testdrive JoliTypo
Twig
3
star
58

tabto

➡️ Auto-tabulation for your inputs. Tiny helper that focus user on the next field when a field reach maxLength.
JavaScript
3
star
59

php-the-wrong-way-conf

⛔ PHP The Wrong Way
PHP
3
star
60

docker-drupal-meetup-conf

CSS
2
star
61

php7cc-conf

💻 A la recherche d'incompatibilités avec PHP 7, Apéro PHP conf by @pyrech
JavaScript
2
star
62

http-cache-conf

JavaScript
2
star
63

smile-php

🙂
PHP
2
star
64

fosuserbundle-conf

💻 Do Not Use FOSUserBundle conference
JavaScript
2
star
65

zephir-conf

Introduction about Zephir in french
JavaScript
2
star
66

typography-conf

Sud Web 2013 - Damien ALEXANDRE slides about space and french typography
JavaScript
1
star
67

drupal-rache-conf

Drupal Meetup Paris mai 2013 – Bastien Jaillot slides "Drupal au secours de la méthode R.A.C.H.E"
JavaScript
1
star
68

Badass-Pageflow-Demo

Demo App for the Badass-Pageflow alloy widget
JavaScript
1
star
69

phptour-2014--dette-technique--conf

Conférence "Prévenez la dette technique de vos projets" au PHP Tour Lyon 2014
CSS
1
star
70

phptour2014-drink

1
star
71

phptour2014-burger

PHP
1
star
72

ca-marche-chez-moi

Sources des slides de la conférence "Chez moi ça marche" - PHP Tour 2012
CSS
1
star
73

sud-web--2014--dette-technique

Conférence sur la dette technique à SudWeb 2014
CSS
1
star