Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Автоформат, нужна помощь. (https://javascript.ru/forum/misc/40649-avtoformat-nuzhna-pomoshh.html)

feniks7 14.08.2013 11:56

Автоформат, нужна помощь.
 
Появилась такая идея/надобность - автоформатирование поступающего текста. Тоесть текст изначально идет сплошным потоком, типа:

"Это пробный текст.Переносов по строкам нету.Выделений по шрифтам нету. Списков нету:хотя это был бы 1; Это 2;Этопоследний;."

Так вот собственно мысль сделать так чтобы скрипт переформировал этот текст в:

"Это пробный текст.
Переносов по строкам нету.
Выделений по шрифтам нету.
Списков нету:
  • хотя это был бы 1;
  • Это 2;
  • Это последний;
"

Знаки:

"." - перенос строки
":" - начало списка
";" - элемент списка
";." - конец списка

Хотя бы так пока что.
Вот что у меня есть. (с последних изменений работать перестало)


<div id="to"><span id="tospan">!!!!!!</span></div>
	<input type="submit" value="CHECK" id="check">


<script language="JavaScript" type="text/javascript"> 
	$( "#check" ).click(function(){
			var i = 0;
			var current_txt='';
			var txt = 'ЭТО ПЕРВАЯ СТРОКА. ЭТО ВТОРАЯ СТРОКА.Это голова списка:Список1;Список2;Список3;.Надеюсь это соседним блоком пойдет уже.';
			alert(txt);
			var N = txt.replace(/[^.]/g,"").length;
			alert(N);
			for (var i = 0; i < N; i++) {
				var txt_i=txt.split('.')[i];
				var N_listheader = txt_i.replace(/[^:]/g,"").length;
				alert(N_listheader);
				alert("Text:"+ current_txt);
				for (var k = 0; k <= N_listheader; k++) {
					var txt_list_head=txt_i.split(':')[0];
					var txt_list_content=txt_i.split(':')[1];
					N_listcontent = txt_list_content.replace(/[^;]/g,"").length;
					for (var s = 0; s<=N_listcontent; s++)
					{
						var txt_list_contentlocal=txt_list_content.split(':')[s];
						txt_list_content = "<li>"+txt_list_contentlocal"</li>";
					}
					if(k>0)
					{
						current_txt = current_txt+txt_list_head+":<ul>"+txt_list_content;
						alert("Adding Listhead:");
						alert("Text:"+ current_txt);
					}
					else
					{
						current_txt= current_txt+txt_i+"<br>";
						alert("Adding normal text");
						alert("Text:"+ current_txt);
					}
					}
				
			}
			$( '#tospan' ).html(current_txt);
			return false;
		});
</script>


Было бы еще хорошо например если более Х точек, делать двухколоночный. То есть заносить в другой блок, или ячейку таблицы.

danik.js 14.08.2013 13:18

Пример парсера. По идее можно сколь угодно усложнять и развивать форматирование, в отличие от твоего метода. Я тут сразу строю DOM, но можно просто формировать HTML, а дальше скормить браузеру через innerHTML.

Недостатки: громоздко (но вроде вполне все ясно), не быстро (посимвольный просмотр).

<body>
<script>
function Parser() {
    this.fragment = document.createDocumentFragment();
    this.buffer = '';
}

Parser.prototype.State = {
    IN_TEXT: 0,
    IN_LIST: 1
};

Parser.prototype.parse = function(text) {
    var state = this.State.IN_TEXT;
    for (var i = 0; i < text.length; i++) {
        var c = text.charAt(i);
        switch (state) {
            case this.State.IN_TEXT:
                if (c == '.') {
                    this.fragment.appendChild(this.createNodeFromBuffer('text'));
                    this.fragment.appendChild(this.createNode('break'));
                } else if (c == ':') {
                    this.fragment.appendChild(this.createNodeFromBuffer('list-header'));
                    this.fragment.appendChild(this.createNode('list'));
                    state = this.State.IN_LIST;
                } else {
                    this.buffer += c;
                }
                break;
            case this.State.IN_LIST:
                if (c == '.') {
                    state = this.State.IN_TEXT;
                } else if (c == ';') {
                    var list = this.fragment.childNodes[this.fragment.childNodes.length -1];
                    list.appendChild(this.createNodeFromBuffer('list-item'));
                } else {
                    this.buffer += c;
                }
                break;
        }
    }
    return this.fragment;
};

Parser.prototype.createNodeFromBuffer = function(type) {
    var content = this.buffer;
    this.buffer = '';
    return this.createNode(type, content);
};

Parser.prototype.createNode = function(type, content) {
    switch (type) {
        case 'text':
            return document.createTextNode(content);
        case 'break':
            return document.createElement('br');
        case 'list-header':
            var element = document.createElement('strong');
            element.appendChild(document.createTextNode(content));
            return element;
        case 'list':
            return document.createElement('ul');
        case 'list-item':
            var element = document.createElement('li');
            element.appendChild(document.createTextNode(content));
            return element;
    }
};

// юзание:

var string = "Это пробный текст.Переносов по строкам нету.Выделений по шрифтам нету. Списков нету:хотя это был бы 1; Это 2;Этопоследний;.";
document.body.appendChild(new Parser().parse(string));
</script>
</body>

feniks7 14.08.2013 16:08

Спасибо, вполне подходит и этот вариант.
Только никак что-то не получается сделать привязку к кнопке и конкретному элементу. Ну как было в моем коде - нажимаешь кнопку, текст вставляется отформатированный в окно блока.

feniks7 14.08.2013 16:21

А, все, тупил, не тот файл открыт был)

вот так сделал:
$( "#check" ).click(function(){
$('#tospan').html(new Parser().parse(string));
});

danik.js 14.08.2013 16:23

А разве $(el).append(fragment) не работает?


Часовой пояс GMT +3, время: 06:31.