Обработчик типографских символов в HTML согласно общепринятым правилам. Посвящается П.Г.Гиленсону[www.rudtp.ru/lib.php?book=172], благодаря которому русские правила тех. редактуры еще как минимум 20 лет таки останутся бессмысленно старомодными.
Gilenson расставит в тексте "умные" правильные кавычки (русские - для кириллицы, английские - для латиницы), заменит "хитрые" пунктуационные символы на entities и отформатирует знаки типа (c), (tm), телефоны и адреса.
Gilenson базируется на коде Typografica от PixelApes, который был приведен к положенному в Ruby стандарту. Основные отличия Gilenson от Typografica на PHP:
* работа только и полностью в UTF-8 (включая entities, применимые в XML) * поддержка "raw"-вывода (символов вместо entities) - текст выводимый Gilenson можно верстать на бумаге
Быстрее всего - через метод +gilensize+ для любой строковой переменной
%{ И вот они таки "приехали"}.gilensize => 'И вот они таки «приехали»'
Все дополнительные настройки в таком случае передаются форматтеру
%{ И вот они таки "приехали"}.gilensize(:laquo=>false) => 'И вот они таки "приехали"'
Если форматтер надо настроить более тонко, можно использовать его и так:
typ = RuTils::Gilenson.new('Эти "так называемые" великие деятели') typ.to_html => 'Эти «так называемые» великие деятели'
или как фильтр
formatter = RuTils::Gilenson.new formatter.configure(:dash=>true) for string in strings puts formatter.process(string) end
Настройки регулируются через методы
formatter.dashglue = true
или ассоциированным хешем
formatter.configure!(:dash=>true, :quotes=>false)
Хеш также можно передавать как последний аргумент методам process и to_html, в таком случае настройки будут применены только при этом вызове
beautified = formatter.process(my_text, :dash=>true)
В параметры можно подставить также ключ :all чтобы временно включить или выключить все фильтры
beautified = formatter.process(my_text, :all=>true)
Помимо этого можно пользоваться каждым фильтром по отдельности используя метод apply
Можно менять глифы, которые форматтер использует для подстановок. К примеру,
formatter.glyph[:nbsp] = ' '
заставит форматтер расставлять "традиционные" неразрывные пробелы. Именно это - большая глупость, но другие глифы заменить может быть нужно.
"inches" - преобразовывать дюймы в знак дюйма; "laquo" - кавычки-ёлочки "quotes" - кавычки-английские лапки "dash" - проставлять короткое тире (150) "emdash" - длинное тире двумя минусами (151) "initials" - проставлять тонкие шпации в инициалах "copypaste" - замена непечатных и "специальных" юникодных символов на entities "(c)" - обрабатывать знак копирайта "(r)", "(tm)", "(p)", "+-" - спецсимволы, какие - понятно "acronyms" - сворачивание пояснений к аббревиатурам (пояснение - в скобках после аббревиатуры без пробела). В текстовой версии пояснение будет "приклеено" к аббревиатуре полукруглой шпацией "degrees" - знак градуса "dashglue", "wordglue" - приклеивание предлогов и дефисов "spacing" - запятые и пробелы, перестановка "phones" - обработка телефонов "html" - при false - запрет использования тагов html "de_nobr" - при true все <nobr/> заменяются на <span class="nobr"/> "raw_output" - (по умолчанию false) - при true вместо entities выводятся UTF-символы "skip_attr" - (по умолчанию false) - при true не отрабатывать типографику в атрибутах тегов (title, alt) "skip_code" - (по умолчанию true) - при true не отрабатывать типографику внутри <code/>, <tt/>, CDATA
Кто придумал “? Не учите людей плохому... Привет А.Лебедеву www.artlebedev.ru/kovodstvo/62/ Используем символы, потом берем по символам из glyphs форматтера. Молодец mash!
Глифы, использующиеся в подстановках по-умолчанию
Метка на которую подменяются вынутые теги
All the unicode whitespace
Нормальные "типографские" символы в UTF-виде. Браузерами обрабатываются плохонько, поэтому лучше заменять их на entities.
Применяет отдельный фильтр к text и возвращает результат. Например:
formatter.apply(:wordglue, "Вот так") => "Вот так"
Удобно применять когда вам нужно задействовать отдельный фильтр Гиленсона, но не нужна остальная механика Последний аргумент определяет, нужно ли при применении фильтра сохранить в неприкосновенности таги и другие игнорируемые фрагменты текста (по умолчанию они сохраняются).
# File lib/gilenson/gilenson.rb, line 357 def apply(filter, text, lift_ignored_elements = true) copy = text.dup unless lift_ignored_elements self.send("process_#{filter}".to_sym, copy) else lifting_fragments(copy) { self.send("process_#{filter}".to_sym, copy) } end copy end
Настраивает форматтер ассоциированным хешем
formatter.configure!(:dash=>true, :wordglue=>false)
# File lib/gilenson/gilenson.rb, line 234 def configure!(*config) accept_configuration_arguments!(config.last) if config.last.is_a?(Hash) end
Обрабатывает text_to_process с сохранением настроек, присвоенных обьекту-форматтеру Дополнительные аргументы передаются как параметры форматтера и не сохраняются после прогона.
# File lib/gilenson/gilenson.rb, line 250 def process(text_to_process, *args) @_text = text_to_process args.last.is_a?(Hash) ? with_configuration(args.last) { to_html } : to_html end
Обрабатывает текст, присвоенный форматтеру при создании и возвращает результат обработки
# File lib/gilenson/gilenson.rb, line 257 def to_html return '' unless @_text # NOTE: strip is Unicode-space aware on 1.9.1, so here we simulate that text = @_text.gsub(/[#{UNICODE_WHITESPACE}]\z/, '').gsub(/\A[#{UNICODE_WHITESPACE}]/, '') # -6. Подмухляем таблицу глифов, если нам ее передали glyph_table = glyph.dup if @settings["enforce_ru_quotes"] glyph_table[:ldquo], glyph_table[:rdquo] = glyph_table[:laquo], glyph_table[:raquo] elsif @settings["enforce_en_quotes"] glyph_table[:laquo], glyph_table[:raquo] = glyph_table[:ldquo], glyph_table[:rdquo] end # -5. Копируем глифы в ивары, к ним доступ быстр и в коде они глаза тоже не мозолят glyph_table.each_pair do | ki, wi | instance_variable_set("@#{ki}", wi) end # -4. запрет тагов html process_escape_html(text) unless @settings["html"] # -3. Никогда (вы слышите?!) не пущать лабуду &#not_correct_number; FORBIDDEN_NUMERIC_ENTITIES.dup.each_pair do | key, rep | text.gsub!(/&##{key};/, self.glyph[rep]) end # -2. Чистим copy&paste process_copy_paste_clearing(text) if @settings['copypaste'] # -1. Замена &entity_name; на входе (' ' => ' ' и т.д.) process_html_entities(text) # 0. Вырезаем таги tags = lift_ignored_elements(text) if @skip_tags # 1. Запятые и пробелы process_spacing(text) if @settings["spacing"] # 1. лапки process_quotes(text) if @settings["quotes"] # 2. ёлочки process_laquo(text) if @settings["laquo"] # 3. Инчи process_inches(text) if @settings["inches"] # 2b. одновременно ёлочки и лапки process_compound_quotes(text) if (@settings["quotes"] && @settings["laquo"]) # 3. тире process_dash(text) if @settings["dash"] # 3a. тире длинное process_emdash(text) if @settings["emdash"] # 5. +/- process_plusmin(text) if @settings["+-"] # 5a. 12^C process_degrees(text) if @settings["degrees"] # 6. телефоны process_phones(text) if @settings["phones"] # 7. Короткие слова и process_wordglue(text) if @settings["wordglue"] # 8. Склейка ласт. Тьфу! дефисов. process_dashglue(text) if @settings["dashglue"] # 8a. Инициалы process_initials(text) if @settings['initials'] # 8b. Троеточия process_ellipsises(text) if @settings["wordglue"] # 9. Акронимы от Текстиля process_acronyms(text) if @settings["acronyms"] # БЕСКОНЕЧНОСТЬ. Вставляем таги обратно. reinsert_fragments(text, tags) if @skip_tags # фуф, закончили. process_span_instead_of_nobr(text) if @settings["de_nobr"] # заменяем entities на истинные символы process_raw_output(text) if @settings["raw_output"] text.strip end
Generated with the Darkfish Rdoc Generator 2.