Ответ 1
Нужно решить, является ли это вопросом внешнего вида или трансформации. Нужно также решить, является ли это вопросом, включающим семантику символьного уровня или числовые представления. Вот мои мысли:
Вопрос имел бы совершенно другую семантику, если бы у нас была ситуация, когда Unicode не разгласил коды для числовых символов. Затем отображение различных глифов, если это было необходимо, просто связано с использованием соответствующего шрифта. С другой стороны, было бы невозможно просто написать разные символы, как я сделал ниже, не меняя шрифтов. (Ситуация не совсем идеальна, поскольку шрифты не обязательно охватывают весь диапазон 16-разрядного Unicode-набора, не говоря уже о 32-разрядном Unicode-наборе.)
9, ٩ (Arabic), ۹ (Urdu), 玖 (Chinese, complex), ๙ (Thai), ௯ (Tamil) etc.
Теперь, предполагая, что мы принимаем семантику Unicode, т.е. 9 ', 9 и 9 являются отдельными символами, мы можем заключить, что речь идет не о внешности (что-то, что было бы в поле зрения CSS), а трансформации - несколько соображений об этом позже, а теперь предположим, что это так. Если сосредоточиться на символьной семантике, ситуация не слишком отличается от того, что происходит с алфавитами и буквами. Например, греческий "α" и латинский "a" считаются отличными, хотя латинский алфавит почти идентичен греческому алфавиту, используемому в Эвбее. Возможно, даже более драматично соответствующие варианты капитала "А" (греч.) И "А" (латынь) визуально идентичны практически во всех шрифтах, поддерживающих оба сценария, но различающихся по отношению к Юникоду.
Изложив основные правила, давайте посмотрим, как можно ответить на вопрос, игнорируя их и, в частности, игнорируя семантику Unicode на уровне символов.
(Ужасно, противно и без обратной совместимости) Решение: Используйте шрифты, которые сопоставляют "0" и "9" с желаемыми глифами. Я не знаю таких шрифтов. Вам нужно будет использовать шрифт @font-face и некоторый шрифт, который был надлежащим образом взломан, чтобы делать то, что вы хотите.
Излишне говорить, что я не очень люблю это решение. Тем не менее, это единственное простое решение, которое я знаю о том, что делает то, что задает вопрос "без изменения кодов символов" на сервере или на стороне клиента. (Технически говоря, решение Cufon, предлагаемое ниже, также не изменяет коды символов, но то, что он делает, рисование текста в холсты значительно сложнее, а также требует настройки кода с открытым исходным кодом).
Примечание. Любое трансформационное решение, то есть любое решение, которое изменяет DOM и заменяет символы в диапазоне от 0 до 9, скажем, их арабскими эквивалентами, приведет к слому кода, который ожидает появления цифр в их первоначальном виде в DOM. Эта проблема, конечно, хуже всего при обсуждении форм и исходных данных.
Примером ответа, принимающего трансформационный подход, будет:
$("[lang='fa']").find("*").andSelf().contents().each(function() {
if (this.nodeType === 3)
{
this.nodeValue = this.nodeValue.replace(/\d/g, function(v) {
return String.fromCharCode(v.charCodeAt(0) + 0x0630);
});
}
});
Примечание. Код, взятый из второй сессии VisioN jsFiddle. Если это единственная часть этого ответа, который вам нравится, убедитесь, что вы перенесите ответ VisioN, а не мой!!!: -)
У этого есть две проблемы:
- Это беспорядок с DOM и в результате может сломать код, который использовался для работы, предполагая, что он найдет цифры в "стандартной" форме (используя цифры от 0 до 9). См. Здесь проблему: http://jsfiddle.net/bKEbR/10/ Например, если у вас есть поле, содержащее сумму некоторых целых чисел, пользовательские входы, вы можете быть в удивление, когда вы пытаетесь получить его ценность...
- Он не затрагивает вопрос о том, что происходит внутри элементов
input
(иtextarea
). Если поле ввода инициализировано, скажем, "42", оно будет продавать это значение. Это можно легко исправить, но тогда возникает вопрос о фактическом вводе... Можно принять решение об изменении символов по мере их поступления, преобразовать значения при их изменении и т.д. И т.д. Если такое преобразование сделано, то и клиентская сторона, и сторона сервера должны быть готовы иметь дело с разными типами цифр. Что происходит из коробки в Javascript, jQuery и даже с глобализацией (на стороне клиента) и ASP.NET, PHP и т.д. (На стороне сервера), будут разбиты, если их кормить цифрами в нестандартных форматах...
Несколько более комплексное решение (заботясь также об элементах ввода /textarea, как их начальных значениях, так и пользовательских вводах):
//before the DOM change, test1 holds a numeral parseInt can understand
alert("Before: test holds the value:" +parseInt($("#test1").text()));
function convertNumChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 0x0630);
}
function convertNumStr(s) {
return s.replace(/\d/g, convertNumChar);
}
//the change in the DOM
$("[lang='fa']").find("*").andSelf().contents()
.each(function() {
if (this.nodeType === 3)
this.nodeValue = convertNumStr(this.nodeValue);
})
.filter("input:text,textarea")
.each(function() {
this.value = convertNumStr(this.value)
})
.change(function () {this.value = convertNumStr(this.value)});
//test1 now holds a numeral parseInt cannot understand
alert("After: test holds the value:" +parseInt($("#test1").text()))
Весь jsFiddle можно найти здесь: http://jsfiddle.net/bKEbR/13/
Излишне говорить, что это только частично решает вышеупомянутые проблемы. Клиентский и/или серверный код должны распознавать нестандартные цифры и соответствующим образом конвертировать их в стандартный формат или в их фактические значения.
Это не просто то, что несколько строк javascript будут решаться. И это всего лишь самый простой случай такого возможного преобразования, поскольку существует простое сопоставление символов с символами, которое необходимо применять для перехода от одной формы числа к другой.
Другой подход основан на внешнем виде:
Решение на основе Cufon (Overkill, Non-Backward Compatible (требует холста) и т.д.):. Можно было бы относительно легко настроить библиотеку, такую как Cufon, чтобы сделать то, что предусмотрено. Cufon может выполнить свою задачу и нарисовать глифы на объекте canvas, за исключением того, что настройка будет гарантировать, что когда элементы имеют определенное свойство, вместо обычных выбираются нужные глифы. Cufon и другие библиотеки такого типа, как правило, добавляют элементы в DOM и изменяют внешний вид существующих элементов, но не затрагивают их текст, поэтому проблемы с трансформационными подходами не должны применяться. На самом деле интересно отметить, что в то время как (улучшенный) Cufon обеспечивает явно трансформационный подход в отношении общей DOM, это решение на основе внешнего вида, насколько это касается его менталитета; Я бы назвал это гибридным решением.
Альтернативное гибридное решение: Создайте новые элементы DOM с арабским контентом, скройте старые элементы, но оставите их идентификаторы и содержимое неповрежденными. Синхронизируйте арабские элементы контента со своими соответствующими, скрытыми элементами.
Попробуйте подумать вне коробки (поле является текущими веб-стандартами).
Тот факт, что определенные символы уникальны, не означает, что они не связаны друг с другом. Более того, это не обязательно означает, что их различие является одним из видов. Например, "a" и "A" - это одна и та же буква; в некоторых контекстах они считаются одинаковыми, а в других - разными. Имея, различие в Unicode (и ASCII и ISO-Latin-1 и т.д. Перед ним) означает, что для его преодоления требуются некоторые усилия.
CSS позволяет быстро и легко изменить регистр букв. Например, body {text-transform:uppercase}
превратит все буквы в тексте в теле страницы в верхний регистр. Обратите внимание, что это также случай изменения вида, а не преобразования: DOM элемента body не изменяется, так же, как он отображается.
Примечание.. Если CSS поддерживает что-то вроде numerals-transform: 'ar'
, это, вероятно, было бы идеальным ответом на вопрос, поскольку он был сформулирован.
Однако, прежде чем мы спешим сообщить комитету CSS о добавлении этой функции, мы можем подумать, что это будет означать. Здесь мы решаем небольшую проблему, но им приходится иметь дело с большой картиной.
Вывод: Будет ли это работать с цифрами-преобразованиями, чтобы "10" (2-символьные) отображались как 十 (китайский, простой), 拾 (китайский, сложный), X (латинский) (все 1-символьный) и т.д., Если вместо ' ar ', были приведены соответствующие аргументы?
Input: Будет ли эта функция преобразования цифр "十" (китайская, простая) в ее арабский эквивалент или просто нацелена на "10"? Будет ли это каким-то умным образом обнаруживать, что "MMXI" (латинская цифра на 2012 год) является числом, а не словом и соответствующим образом конвертирует его?
Вопрос о представлении чисел не так прост, как можно было подумать, просто глядя на этот вопрос.
Итак, где все это оставляет нас:
- Нет простого решения на основе презентации. Если он появится в будущем, он не будет обратно совместим.
- Здесь и сейчас может быть трансформационное "решение", но даже если это сделано для работы с элементами формы, как я это делал (http://jsfiddle.net/bKEbR/13/), должен быть сервер -сторонняя и клиентская осведомленность о нестандартном формате.
- Могут быть сложные гибридные решения. В некоторых случаях они сложны, но в некоторых случаях предлагают некоторые преимущества подходов, основанных на презентации.
Решение с CSS было бы неплохо, но на самом деле проблема большая и сложная, когда вы смотрите на общую картину, которая включает в себя другие числовые системы (с менее тривиальными преобразованиями и от стандартной системы), десятичные точки, знаки и т.д.
В конце концов, решение, которое я вижу как реалистичное и обратное совместимое, было бы продолжением Globalize (и эквивалентов на стороне сервера), возможно, с некоторым дополнительным кодом, чтобы заботиться о вводе пользователя. Идея заключается в том, что это не проблема на уровне персонажа (потому что, как только вы считаете, что это большая картина), и что ее нужно будет обрабатывать так же, как были рассмотрены различия с тысячами и десятичными разделителями: как проблемы форматирования/разбора.