parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Класс "Типограф"

Spearance 21.05.2004 13:11 / 21.05.2004 13:45

Пршло время выложить свой вариант класса для общей обкатки и теста.

Сам класс:
# $Id: typograf.p,v 1.4.5.0 2004/05/21 Eugene Spearance Exp $

@CLASS
typograf

########################################
# Определение пути к классу
#####
@auto[filespec][full_path]
$full_path[^file:dirname[$filespec]]
$c_dir[/^full_path.trim[start;$request:document-root]]
$hash[^hash::create[]]
### End @auto


########################################
# Обработка текста
# 
# $.dirty_text[текст] - который нужно типографировать
# $.regex_path[путь_к_файлу] - с альтернативной таблицей правил (включая имя файла)
# $.symbols_path[путь_к_файлу] - с альтернативной таблицей замен символов (включая имя файла)
#
#####
@text_process[params][regex_path]
^if(def $params.dirty_text){
	^memory:compact[]
	^if(def $params.regex_path){$regex_path[$params.regex_path]}{$regex_path[$c_dir/regex.cfg]}

	^rem{ *** Заменяю символы UTF-8 и символы мнемоники на печатные *** }
	$result[^prepare_text[$params.dirty_text;$params.symbols_path]]

	^rem{ *** Удаляю таблицы стилей, скрипты, пре-формаченый текст и теги. ПОРЯДОК УДАЛЕНИЯ НЕ МЕНЯТЬ!!! *** }
	$result[^remove[$result;css]]
	$result[^remove[$result;js]]
	$result[^remove[$result;pre]]
	$result[^remove[$result;tag]]

	^rem{ *** Обрабатываю текст правилами *** }
	^if(!$regex){
		$regex[^table::load[$regex_path]]
	}
	^regex.menu{
		^if(def $regex.reg1){
			$result[^result.match[$regex.reg1][$regex.reg2]{^process{^taint[as-is][$regex.reg3]}}]
		}
	}

	^rem{ *** Возвращаю таблицы стилей, скрипты, пре-формаченый текст и теги ПОРЯДОК ВОЗВРАТА НЕ МЕНЯТЬ!!! *** }
	$result[^return[$result;tag]]
	$result[^return[$result;pre]]
	$result[^return[$result;js]]
	$result[^return[$result;css]]
	^memory:compact[]
}
### End @text_process


########################################
# Замена символов в UTF кодировке и символов "мнемоников" на печатные символы
#####
@prepare_text[dirty_text;symbols_path]
^if(!$table_symbols){
	$table_symbols[^table::load[nameless;^if(def $symbol_path){$symbol_path}{$c_dir/replace.cfg}]]
}
$result[^dirty_text.replace[$table_symbols]]
### End @prepare_text


########################################
# Замена тегов, скриптов и внутренних CSS на <*>, <js>, <css>
#
# tag - заменяю теги на <*>
# css - заменяю встроенные таблицы стилей на <css>
# js, javascript - заменяю скрипты на <js>
# pre - заменяю предварительно форматированный текст на <pre>
#
#####
@remove[prepared_text;text_type][counter]
$counter(0)
^hash.add[$.[$text_type][^hash::create[]]]
^switch[$text_type]{
	^case[css]{
		$result[^prepared_text.match[(<style[^^>]*>.*?</style>)][gi]{<css>^hash.[$text_type].add[$.[$counter][$match.1]]^counter.inc[]}]
	}
	^case[js;javascript]{
		$result[^prepared_text.match[(<script[^^>]*>.*?</script>)][gi]{<js>^hash.[$text_type].add[$.[$counter][$match.1]]^counter.inc[]}]
	}
	^case[pre]{
		$result[^prepared_text.match[(<pre[^^>]*>.*?</pre>)][gi]{<pre>^hash.[$text_type].add[$.[$counter][$match.1]]^counter.inc[]}]
	}
	^case[DEFAULT]{
		$result[^prepared_text.match[(<[^^>]+>)][g]{<*>^hash.[$text_type].add[$.[$counter][$match.1]]^counter.inc[]}]
	}
}
### End @remove


########################################
# Возврат тегов, скриптов и внутренних CSS
#####
@return[matched_text;text_type][counter]
$counter(0)
$result[$matched_text]
^if(def $hash.[$text_type]){
	^switch[$text_type]{
		^case[css]{
			$result[^result.match[(<css>)][g]{$hash.[$text_type].[$counter]^counter.inc[]}]
		}
		^case[js;javascript]{
			$result[^result.match[(<js>)][g]{$hash.[$text_type].[$counter]^counter.inc[]}]
		}
		^case[pre]{
			$result[^result.match[(<pre>)][g]{$hash.[$text_type].[$counter]^counter.inc[]}]
		}
		^case[DEFAULT]{
			$result[^result.match[(<\*>)][g]{$hash.[$text_type].[$counter]^counter.inc[]}]
		}
	}
}
### End @return
Это облегченный по функциональности вариант класса, относительно того что используется на моем сайте.

Для правил использую обычную таблицу с 3 полями reg1, re2, reg3. В которых описано что ищем, метод поиска и чем заменяем.
Такой подход упрощает работу с правилами т.к. можно забыть про парные ^^ и заескепливание специальных парсеровских символов. При желании можно сделать свою собственную таблицу с правилами хоть для каждой страницы сайта, что весьма удобно.

Вызов метода:
@USE
typograf.p
...
^typograf:text_process[
	$.dirty_text[текст] - который нужно типографировать
	$.regex_path[путь_к_файлу] - с альтернативной таблицей правил (включая имя файла)
	$.symbols_path[путь_к_файлу] - с альтернативной таблицей замен символов (включая имя файла)
...
]
Все это богатство вместе с таблицей правил и таблицей замен можно скачать здесь.
Рабочий пример можно посмотреть здесь.

Спасибо Misha v.3 за помощь в разработке.

P.S. чуть не забыл, класс работает с версией 3.1.2, для младших версий нужно заменить trim на схожий метод и Мишиного класса lib.p (он есть в примерах).