Динамическая загрузка подсветки синтаксиса.

Опубликовано в рубрике "Всячина", 17 сентября, 2011.
Тэги: , , автор:

Долгое время я использовал свой подсветчик синтаксиса, выполненный в виде плагина для
windows live writer’а. Это оказалось неудобно по нескольким причинам:

  • синтаксис не подсвечивается в комментариях
  • для добавления нового языка приходилось вспоминать regexpr’ы (а это – геморрой еще тот)
bool IsBsviSiteUsingSyntasHighlighter()
{
    // HttpRequest *request = new HttpGetRequest("http://bsvi.ru", ...);
    // bool using_syntax_highlighter = IsTrueResponse(request.GetResponse());
    // delete request;
    // return using_syntax_highlighter;

    return true;
}

Поэтому, я решил пойти простым путем и прицепить к сайту подсветку синтаксиса на javascript от Alex Gorbatchev.

Начал прикручивать и обнаружил, что для каждого языка придется подключить по js файлу. Вот пример из кода ziblog‘а:

‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shCore.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushAS3.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushBash.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushColdFusion.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushClojure.js?ver=20090602'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushCpp.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushCSharp.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushCss.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushDelphi.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushDiff.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushErlang.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushFSharp.js?ver=20091003'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushGroovy.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushJava.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushJavaFX.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushJScript.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushLatex.js?ver=20090613'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushMatlabKey.js?ver=20091209'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushObjC.js?ver=20091207'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPerl.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPhp.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPlain.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPowerShell.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPython.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/third-party-brushes/shBrushR.js?ver=20100919'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushRuby.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushScala.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushSql.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushVb.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript' src='http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushXml.js?ver=3.0.83b'›‹/script›
‹script type='text/javascript'›
	(function(){
		var corecss = document.createElement('link');
		var themecss = document.createElement('link');
		var corecssurl = "http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shCore.css?ver=3.0.83b";
		if ( corecss.setAttribute ) {
				corecss.setAttribute( "rel", "stylesheet" );
				corecss.setAttribute( "type", "text/css" );
				corecss.setAttribute( "href", corecssurl );
		} else {
				corecss.rel = "stylesheet";
				corecss.href = corecssurl;
		}
		document.getElementsByTagName("head")[0].insertBefore( corecss, document.getElementById("syntaxhighlighteranchor") );
		var themecssurl = "http://ziblog.ru/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shThemeDefault.css?ver=3.0.83b";
		if ( themecss.setAttribute ) {
				themecss.setAttribute( "rel", "stylesheet" );
				themecss.setAttribute( "type", "text/css" );
				themecss.setAttribute( "href", themecssurl );
		} else {
				themecss.rel = "stylesheet";
				themecss.href = themecssurl;
		}
		//document.getElementById("syntaxhighlighteranchor").appendChild(themecss);
		document.getElementsByTagName("head")[0].insertBefore( themecss, document.getElementById("syntaxhighlighteranchor") );
	})();
	SyntaxHighlighter.config.strings.expandSource = '+ expand source';
	SyntaxHighlighter.config.strings.help = '?';
	SyntaxHighlighter.config.strings.alert = 'SyntaxHighlighter\n\n';
	SyntaxHighlighter.config.strings.noBrush = 'Can\'t find brush for: ';
	SyntaxHighlighter.config.strings.brushNotHtmlScript = 'Brush wasn\'t configured for html-script option: ';
	SyntaxHighlighter.defaults['pad-line-numbers'] = false;
	SyntaxHighlighter.defaults['toolbar'] = false;
	SyntaxHighlighter.all();
‹/script›

Впечатляет, правда? Почему-бы не подгружать только то, что нужно в данный момент?
Для этого я написал вот такой скриптец:

$(document).ready(function() {

	var base = "http://alexgorbatchev.com/pub/sh/current/";
	var brushes = [];


	$('pre[class^="brush"]').each(function() {
		var brush= this.className.substring(6, this.className.indexOf(';', 6));
		if (this.className.indexOf("html-script") › 0) brushes.push("Xml");
		brushes.push(jQuery.trim(brush));
		this.className = this.className.toLowerCase();
	});

	Array.prototype.unique = function() {
	    var o = {}, i, l = this.length, r = [];
	    for(i=0; i‹l;i+=1) o[this[i]] = this[i];
	    for(i in o) r.push(o[i]);
	    return r;
	};
	
	if (brushes.length › 0)
	{
		$.getScript(base + "scripts/shCore.js", function(a,b) {

			$("head").append("‹link›");
			$("head").children(":last").attr({rel:  "stylesheet", type: "text/css", href: base + "styles/shCoreDefault.css"});

			brushes = brushes.unique();
			var files_loaded = 0;

			for (var index=0; index‹brushes.length; index++)
			{
				$.getScript(base + "scripts/shBrush" + brushes[index] + ".js", function(a, b)
				{
					files_loaded++;
					if (files_loaded == brushes.length) SyntaxHighlighter.highlight();
				});
			}
		});
	}
});

 

До этого у меня на сайтике небыло jquery. Похоже пора добавить и попробовать поработать с этой "легендарной" библиотекой. Тем более, у меня есть идеи как ее использовать в эмбеддерских целях.

Сам jquery подтягивается с гугловского CDNа, а значит, с большой вероятностью, он уже есть в кэше вашего браузера.

Для моего домашнего ПК, гугловский CDN на 2мс медленнее, чем мой хостинг. Но так как хостинг будет занят обработкой других запросов, думаю, что эти 2мс окупятся.

Все статические скрипты я предпочтиаю вынести в отдельный js файл, он закешируется и не будет передаваться каждый раз.

Кроме этого, пришлось написать еще один плагин к windows live writer. Его я выкладывать пока не буду – он сыроват. Выложу, когда хорошо обкатаю.




Комментарии
  1. ZiB написал(а) 18 сентября, 2011 в 4:14

    Привет, ёлки-палки и это у меня на каждой странице, нужно избавляться :)
    Что за плагин к WLW?

    BSVi Reply:

    Собственно, который вставляет код в статью. Я не пользуюсь редактором вордпресса, исключительно WLW. Плагин очень сырой, только вчера написал и периодически вылазят баги и недочеты, так что он не готов к прайм-тайму :)

    ZiB Reply:

    Есть же готовый с одноименным названием, я сам только через WLW пишу.

    BSVi Reply:

    Их даже несколько, но они не подходят. Для подгрузки, название кисти только писаться так-же, как и название фала. К примеру, готовый плагин для яваскрипта пишет js, а должен JScript. Можно, конечно переименовать файлы, но это — не по джедайски.

    У меня есть автоформатирвоание кода, удаление лишних отступов.
    Есть мелкие ньюансы — типа того, что для html нужно подгружать подсветку xml +javascript, а если код будет свернут, то нужно чтобы параметр toolbar syntaxhighlighter’а был true.

    ZiB Reply:

    Понятненько

Создать новую ветку комментариев


Вы должны войти или зарегистрироваться чтобы оставить комментарий.