Когда евро — не евро

Начинаем новую рубрику «пятиминутка ликбеза с сайтом Таблица символов Юникода»

Сегодня посмотрим на раздел «Управляющие символы С1», к которому относятся символы с кодами от 0080 до 009F. То есть блок, идущий сразу после ASCII (первые 128 символов).

Этот раздел был унаследован Юникодом от кодовой страницы ISO 8859-1. Сама же ISO 8859-1 (также известная, как Latin-1), основана на символьном наборе для терминалов. В следствии чего, первые 32 символа были выделены для различных терминальных команд. То есть, «разрешение разрыва строки», «запрещение разрыва строки», «обратный перевод строки», «символ-заполнитель» и остальной допотопный треш.

На Latin-1 также раньше строились и другие 8-битные кодировки, в частности Windows-1252, использовавшаяся в Windows для западноевропейских алфавитов.

Однако, Microsoft, как всегда, сторонние стандарты использует, но только так, как хочет. Там решили, что в Latin-1 не попали многие нужные и ненужные, но забавные, символы. Например, не попал знак евро (€), что всех очень напрягало, так как цены на сайтах писать не удобно. Зато целых тридцать две позиции занимают какие-то символы для терминалов. Кому они нужны? На терминалах-то и Windows нету.


То есть, взяли и понапихали в этот раздел своих символов. Был символ 0080 «символом-заполнителем», а стал знаком евро. Ещё различных крестиков, процентиков, знаков функций и ещё чего-то совершенно непонятного напридумывали. Ну, и шрифты, соответственно, перерисовали, чтобы на 128-м месте шло евро. А если какой терминал подавится подобным текстом, то никому уже никакого дела не было.

ƒ Œ

И потом пришёл Юникод, а у него в стандарте 0080 никакой не евро. Евро у него — 20AC. А 0080—009F, по-прежнему, терминальные символы.

То есть, все тексты, которые раньше использовали эти символы из win-1252, они как-бы неправильные. И советы по всей сети, вроде «для ввода евро нажмите ALT+128» тоже неправильные.

Но это какая-то нехорошая ситуация, поэтому её решили, как всегда костылём. Например, в стандарте HTML5 сказано, символы из ISO-8859-1 нужно заменять на windows-1252. И все браузеры этому следует.

Что это значит, рассмотрим на примере:

<div id="div">&#128;</div>
 
<script>
var div = document.getElementById("div"),    
    char = div.firstChild.nodeValue,
    code = char.charCodeAt(0);
 
console.log(code); // 8364
</script>

Получается, что мы вывели символ с кодом 128, а он заменился на 8364. То есть, «терминальный символ, который использовался вместо евро», заменился на «настоящий Unicode-евро». Также &#131; меняется на 402-й символ (знак функции).

То есть, даже если взять нормальный шрифт, поддерживающий Unicode (Universalia, например), в котором по 128-му коду нет никакого евро, всё равно вместо &#128; будет красоваться евро (но html-валидатор всё-таки выругается).

Тоже самое, если вставлять в DOM через JavaScript:

var div = document.createElement("div");
div.innerHTML = "&#128;";
console.log(div.firstChild.nodeValue.charCodeAt(0)); // 8364

Но можно вставить непосредственно символ. Тогда всё нормально:

var div = document.createElement("div"),
    char = String.fromCharCode(128),
    text = document.createTextNode(char);
div.appendChild(text);
console.log(div.firstChild.nodeValue.charCodeAt(0)); // 128

Выводы и вопросы

1. Верстальщикам: евро, это не &#128;, а &#8364;. А ещё лучше: &euro;.

2. Программистам: когда вам кажется, что из DOM должен прийти точно определённый символ — креститься надо.

3. Разработчикам Юникода: нахрена вам терминальные символы и почему столько мусора, а знака рубля нет?

Список заменяемых символов из 0080—009F

0080 20AC Euro sign
0082 201A Single low-9 quotation mark
ƒ 0083 0192 Latin small letter f with hook
0084 201E Double low-9 quotation mark
0085 2026 Horizontal ellipsis
0086 2020 Dagger
0087 2021 Double dagger
ˆ 0088 02C6 Modifier letter circumflex accent
0089 2030 Per mille sign
Š 008A 0160 Latin capital letter s with caron
008B 2039 Single left-pointing angle quotation mark
Π008C 0152 Latin capital ligature oe
Ž 008E 017D Latin capital letter z with caron
0091 2018 Left single quotation mark
0092 2019 Right single quotation mark
0093 201C Left double quotation mark
0094 201D Right double quotation mark
0095 2022 Bullet
0096 2013 En dash
0097 2014 Em dash
˜ 0098 02DC Small tilde
0099 2122 Trade mark sign
š 009A 0161 Latin small letter s with caron
009B 203A Single right-pointing angle quotation mark
œ 009C 0153 Latin small ligature oe
ž 009E 017E Latin small letter z with caron
Ÿ 009F 0178 Latin capital letter y with diaeresis

Комментариев нет »

Комментариев ещё нет

Leave a comment