БетаЛаборатория - внеочередной IT-блог

Записки обычного программиста

 

Записи с тэгом Подсветка синтаксиса

Подсветка синтаксиса, часть четветрая, заключительная

Ну вот , кажется, и походит к концу моя эпопея с подсветкой синтаксиса. В процессе беседы, несколько для меня неожиданной, с Иваном Салагаевым, получил от него несколько разъяснений по его библиотеке и сам покопался в ней поглубже. В итоге, убрал из функции инициализации автоматический поиск блоков для подсветки и открыл функцию highlight для внешнего доступа. Кое-какие недочеты конечно остались, но я думаю разберусь со временем. Ивану огромное спасибо за библиотеку и за помощь.
 
Еще добавил вывод номеров строк, но он работает независимо от основной библиотеки.
Подстветка синтаксиса, часть третья

Задумался о том, что в текущей реализации подсветки кода я могу столкнуться с чрезмерным увеличением количества AJAX-запросов. Учитывая что на одной странице выводится до 20 записей, в каждой из которой может оказаться по несколько блоков кода, это чревато десятками запросов.
 
В сети я нашел несколько скриптов для подсветки синтаксиса на JavaScript, однако, после нескольких экспериментов, я убедился что они не дают никаких реальных преимуществ. Самым качественным решением, из тех которые я нашел, является библиотека Ивана Салагаева (http://softwaremaniacs.org/soft/highlight/). Но, во-первых, упакованная библиотека со всеми языками весит 78 Килобайт, а во-вторых, имеет несколько странную реализацию - подсветка осуществляется ТОЛЬКО автоматически, основываясь на анализе кода, то есть нельзя вручную указать какой блок подсвечивать. Скорость его работы я не анализировал, поскольку для меня достаточным для отказа фактором стал именно вес библиотеки.
 
Поэтому я несколько оптимизировал свою систему. В новой версии все блоки на странице обрабатываются одним AJAX запросом. Для этого сначала генерируется форма, в которую агрегируются все блоки с кодом. Форма создается по правилам Django Formset, для удобства ее обработки на сервере.
Полученный от сервера ответ разбит на блоки, которые очень легко разбираются и размещаются где положено.
 
$(document).ready(function() {
	var form = $("<form>"); // Создаем форму.
	var i = 0;
	$(".highlight").each(function() { //Перебираем все блоки требующие подсветки
		var hObject = $(this);
		hObject.attr("id", "highlight-"+i); // Присваиваем блоку уникальный id, чтобы потом найти его.
		// Создаем поле language для формы. Содержит название языка.
		language = $("<input>").attr({
			"name" : "form-"+i+"-language",
			"value" :  hObject.attr("lang")? hObject.attr("lang") : "text", // Если аттрибудет lang не задан, код будет возвращен без подсветки.
			"type" : "text"
		});
		// Создаем поле id для формы. Используется для идентификации блока с результатом.
		id = $("<input>").attr({
			"name" : "form-"+i+"-id",
			"value" :  i,
			"type" : "text"
		});
		// Создаем поле code для формы. Содержит код для подсветки.
		code = $("<textarea>").attr({
			"name" : "form-"+i+"-code",
		}).text(hObject.html());
		// Добавляем поля к форме.
		form.append(language);
		form.append(code);
		form.append(id);
		i++;
	});
	// Если есть хотя бы один блок
	if (i) {
		// Создаем поле form-TOTAL_FORMS. Нужен для Django Formset для обработки формы. 
		total = $("<input>").attr({
			"name" : "form-TOTAL_FORMS",
			"type" : "text",
			"value" : i
		});
		// Создаем поле form-INITIAL_FORMS. Нужен для Django Formset для обработки формы. В нашем случае всегда 0.
		initial  = $("<input>").attr({
			"name" : "form-INITIAL_FORMS",
			"type" : "text",
			"value" : "0"
		});
		// Добавляем поля к форме.
		form.append(total); 
		form.append(initial);
		// Отправляем запрос 
		$.post("/tools/highlight/", form.serialize(), function(response_data) {
			// Перебираем блоки ответа.
			$(response_data).find(".highlighted").each(function(){
				// Заменяем исходный блок, на подсвеченный, ореинтируясь на id.
				$("#highlight-"+$(this).attr("id")).replaceWith($(this).html());
			});
		});
	}
});
Подсветка синтаксиса, часть вторая

Мои эксперименты так важны, так прекрасны, так удивительны, что я с трудом могу оторваться от них, чтобы поесть.
(с) Н. Тесла

Как я и думал, встраивание подсвеченного кода в пост в чистом виде оказалось решением скверным. Причем, помимо неудобств при редактиваронии, такой подход вызывает дополнительные проблесмы при экспотре RSS - лишние теги + лишние стили... ничего хорогошего вобщем. =)
 
В итоге я заменил способ подстветки - теперь это работает так:
 
В WYSIWYG вставляется контейнер с небработанным кодом, которому присваивается класс highlight и в аттрибуте lang указывается язык для подсветки. По окончании загрузаки страницы, из всех контейнеров класса highlight извлекается их содержимое и AJAX-запросом отправляется на сервер, а полученный результат замещает собой первоначальный контейнер.
 
Выполнено это пока не очень изящно, однако работает.
 
$(document).ready(function() {
	$(".highlight").each(function() {
		var hObject = $(this);
		$.post("/tools/highlight/", {
			"language" : hObject.attr("lang")? hObject.attr("lang") : "text",
			"code" : hObject.html()
		},
		function(response_data) {
			hObject.replaceWith($("<div>").append(response_data));
		});
	})
});

Авторизация

Логин:

Пароль:


Регистрация | Забыли пароль?


Последние записи


Promo

Follow pyhoster on Twitter Subscribe

Реклама

A Django project.