пятница, 18 января 2008 г.

Как лучше постить код в Bloggere

Пока нашел только такое решение - заключать код в эти теги:

<code>
.....
.Код.
.....
</code>


Попробовал заключать еще и в <pre>, но при копировании кода через clipboard, теряются символы переноса и весь код выстраивается в одну строку.

* * *

Попробовал вставить скрипт. Пока получилось вот что:

package {
import flash.display.Sprite;
import flash.display.Bitmap;

[Frame(factoryClass="MyFactory")]
public class FrameTest extends Sprite
{
[Embed(source="big_asset.jpg")]
private var Asset:Class;

public function FrameTest()
{
init();
}

public function init():void
{
var asset:Bitmap = new Asset();
addChild(asset);
}
}
}


* * *

Вот код преобразовывающего скрипта:

<script type="text/javascript">
// CodeBlocksSubstitutor
var i=0;
var j=0;
while(_DIV = document.getElementById("code"))
{ _DIV.id="processed";
if ((_DIV.innerText==null)(_DIV.innerText=="")) continue;
AREA = document.createElement("TEXTAREA");
AREA.id = "codeArea"+i;
if (_DIV.rows==null) AREA.rows = 10; else AREA.rows = _DIV.rows;
AREA.cols = 53;
AREA.readOnly = true;
AREA.wrap = "off";
i++;
// *** Удалено *** if (_DIV.markup!=null) AREA.appendChild(_DIV.cloneNode(true)); else
AREA.innerText=_DIV.innerText;
newdiv=document.createElement("DIV");
newdiv.appendChild(AREA);
div_parent=_DIV.parentNode;
div_parent.replaceChild(newdiv,_DIV);
}
</script>


В тексте, код необходимо поместить в контейнер:

<div id="code" rows="20">
</div>


Параметр id="code" указывает на то, что текст необходимо обработать.
Параметр rows задает количество строк поля TextArea.
*** УДАЛЕНО *** Параметр markup="on" включает разметку кода. Но при этом, код будет неверно копироваться в клипбоард.
Тег div можно заменить на любой другой, например, code. Это повлияет на внешний вид контейнера.

* * *

Итак, выдрав код замены DIV на TEXTAREA отсюда, выявил несколько неудобств (копируемый в клипбоард код теряет переносы, необходимо заключать в дополнительный контейнер содержимое) и внес коррекции. Однако, остался один недостаток - теряются пробельные символы в начале строк. Кроме того, теряется форматирование, но, на мой взгляд, это не является большим минусом при выкладывании кода.

Итак, решение позволяет сделать так, чтобы код помещался в контейнере TextArea. Не более того.

* * *

После непродолжительного использования скрипта, выявился важный недостаток. IE 6.0 сваливается по критической ошибке, если уйти со страницы и опять на нее вернуться.
Виновником оказался код AREA.appendChild(_DIV.cloneNode(true));.
Код AREA.appendChild(_DIV.firstChild); тоже валит IE.

Пришлось отказаться от форматированного варианта с markup="on". Да и фиг с ним.

* * *

Обновил код: для пользователей альтернативных браузеров и Mac, текст в полях ввода не виден, всё из-за того, что на свойство innerText им совсем наплевать - оно не поддерживается DOM. Посему, не вдаваясь в подробности, я просто отключаю помещение кода в TextArea для всех браузеров, которые не IE. Возможно, позже найдется лучшее решение.
Да, знаю - камень в огород бесплатного блогирования.

7 комментариев:

* Ёж * комментирует...

задался какое-то время назад тем же вопросом ... Если Вам интересно - готов поделиться:

в результате остановился на 2 вариантах .. простом но не слишком удовлетворительном и извращенном, но более функционально широким ...
1) Ваше же предложение по поводу code тэгов и дополнительное описание небольшого css класса к нему. Не слишком здорово честно говоря, поскольку фактически обеспечивает только акцент внимания на коде, но не более ..
2) С использованием DOM. Весь код при редактировании поста я заключаю в div'ы с одним и тем же id='code'. Далее, на основную страницу добавляю небольшой js, который циклично while'ом подменяет эти блоки textarea, предварительно вынув из них innerHtml. С точки зрения общей архитектуры страницы конечно не слишком элегантное решение ... но на время загрузки существенного влияния не оказывает ... (для теста проверял на 20 блоках кода на странице) ... особенно сильно видимого для глаза эффекта так и не достиг ...
Вот так выглядит конечный результат, что правда - без особенных трудов над внешним видом ...
Существенный на мой взгляд + - возможность добавить на эти блоки любую функциональность вроде скажем копирования в буфер при клике и прочая ...

Unknown комментирует...

Спасибо! Принял к сведению, совет очень помог. :)

* Ёж * комментирует...

Рад помочь, тем более что сам уже воспользовался несколькими удачными своетами с Ваших страниц, за что отдельное спасибо .. )

PS. C разрешения, подредактирую свой код на основе Ваших изменений ...

Unknown комментирует...

Да не вопрос.
Вот только что-то нехорошее стал иногда IE 6.0 творить - если со страницы, на которой этот скрипт, есть перейти на другую ссылку, а потом быстро нажать Back, IE выдает ошибку и валится. Гад такой.

* Ёж * комментирует...

хм странно ... надо потестить ... хотя у него (IE) вообще довольно своеобразный взгляд на мир .. ))
как впрочем и у остальных ... в общем один большой сюрприз .. )

Unknown комментирует...

Да, у меня стабильно вылетает, причем. Даже немодифицированный.
Только один момент - чтобы скрипт съедал весь текст (т.к. в коде firstChild), я заключаю его в тег div. Если так не сделать, текст оборвется на первом же теге. А перебрать и зааппендить остальные у меня не получилось :(. Всё равно перебор останавливался только на первом элементе.

Unknown комментирует...

Причем, если в тег не заключать содержимое контейнера - ошибка не вылетает, иначе - грохается.
А мой первый вариант - там где я аппендю в TextArrea дупликат divа с тектсом - рушит 100%...