diff --git a/bred.js b/bred.js new file mode 100644 index 0000000..e69d430 --- /dev/null +++ b/bred.js @@ -0,0 +1,88 @@ +/** + * Бредогенератор + * + * @version 1.0 + * @date 10.10.2013 + * @author Vladimir Shestakov + * @uss JQuery, chain.js + * @constructor + */ +var Bred = (function($, Chain){ + /** + * Генератор бреда + * @param src Источник бреда - текс или html + * @param config Конфигурация бреда - размеры предложений, абзацев, комментов, качества бреда + * @constructor + */ + var Bred = function(src, config){ + this.config = config; + this.articles = new Chain(); + this.comments = new Chain(); + this.users = []; + this.articles.pfx_length = config.quality; + this.comments.pfx_length = config.quality; + // Создание цепочек из src + var self = this; + if (/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/.test(src)){ + var $articles = $('
').append(src).find('article'); + // HTML исходник + $articles.each(function(article_i, article){ + // Вырезаем и обрабатываем комментарии + var $com = $(article).find('.comments').remove(); + $com.find('.username').each(function(user_i, user){ + self.users.push($(user).text()); + }); + $com.find('.message').each(function(message_i, message){ + self.comments = self.comments.addElement(message); + }); + // Обработка текста статьи + self.articles = self.articles.addElement(article); + }); + }else{ + // Обработка как текста + var lines = src.split("\n"); + var cnt = lines.length; + for (var i=0; i 0)? this.users[Math.round(Math.random() * (this.users.length-1))] : 'Гость'); + $comment.find(tpl.places.comment_places.date).text('сегодня'); + $comment.find(tpl.places.comment_places.text).html(com.getText(comment_cfg)); + comment_list[Math.round(Math.random() * (comment_list.length-1))].append($comment); + comment_list.push($comment.find(tpl.places.comment_places.sub)); + } + return $article; + }; + + return Bred; + +})(jQuery, Chain); \ No newline at end of file diff --git a/chain.js b/chain.js new file mode 100644 index 0000000..96f4907 --- /dev/null +++ b/chain.js @@ -0,0 +1,214 @@ +/** + * Цепочка слов для генерации бреда + * (Цепь маркова) + * @version 1.0 + * @date 10.10.2013 + * @author Vladimir Shestakov + * @use jquery + * @constructor + */ +var Chain = (function($, undefined){ + /** + * Узел цепочки слов. + * Имеет связанные узлы, в итоге образует цепочку + * @param {string|undefined} word Слово из текста + * @param {string|undefined} type Тип текста (тег) + * @param {Chain|undefined} root Корневой узел цепочки + * @param {Array|undefined} pfx Префикс + * @constructor + */ + var Chain = function(word, type, root, pfx){ + this.word = word || ''; + this.type = type? type : ''; + this.root = root || this; + this.pfx = pfx || [this.word]; + this.pfx_length = this.root.pfx_length || 1; + this.index = (this.root !== this)? this.root.index : {}; + this.children = []; + }; + + /** + * Следующий узел цепочки, выбираемый случайно + * @returns {Chain|null} Узел или null, если нет связанных узлов + */ + Chain.prototype.next = function(){ + if (this.children.length > 0){ + return this.children[Math.round(Math.random() * (this.children.length-1))]; + } + return null; + }; + + /** + * Итератор по цепочке + * @param min Минимальное количество итераций + * @param max Максимальное количество итераций + * @returns {{next: Function, current: Function, completed: Function}} + */ + Chain.prototype.iterator = function(min, max){ + var curr = this.root; + var cnt = Math.round(Math.random()*(max-min))+min; + return { + next: function(){ + if (curr && (max === 0 && !this.completed() || cnt-->0 || curr.isBadEnd())){ + curr = curr.next(); + // Если задано минимальное кол-во слов и текущий узел - точка + if (min!==0 && cnt < min && this.completed()) return this.next(); + return curr; + } + return undefined; + }, + current: function(){ + return curr; + }, + completed: function(){ + return curr && /^[.?!]+$/.test(curr.word); + } + }; + }; + + /** + * Добавление в цепочку нового текста. + * Текст разбивается на узлы + * @param {string} text Текст для парсинга на цепочки + * @param {string|undefined} type Тип текста (название html тега) + * @returns {Chain} Новый узел или текущий, если не создан + */ + Chain.prototype.addText = function(text, type){ + var self = this; + var key, keys = self.pfx; + if (!type || type == 'p') type = ''; + switch (type){ + case '': + case 'b': + case 'i': + case 'u': +// case 'li': +// case 'blockquote': + var words = text.match(/([a-zа-яА-ЯёЁ*'-]+|[.,:!?]+)/ig); + if (words){ + var i, cnt = words.length; + for (i=0; i this.pfx_length) keys = keys.slice(keys.length - this.pfx_length); + keys.push(words[i]+'#'+type); + key = keys.join(' ')/*.toLowerCase()*/; + // Создание/получение узла и добавление в родительский + if (typeof this.index[key] === 'undefined') this.index[key] = new Chain(words[i], type, this.root, keys); + if (!i && !this.index[key].isPunctuation() && type!=='li') self.root.children.push(this.index[key]); + self.children.push(this.index[key]); + self = this.index[key]; + } + } + break; + //case 'a': + case 'pre': +// case 'ul': +// case 'ol': + if (keys.length > this.pfx_length) keys = keys.slice(keys.length - this.pfx_length); + keys.push(text+'#'+type); + key = keys.join(' ')/*.toLowerCase()*/; + if (typeof this.index[key] === 'undefined') this.index[key] = new Chain(text, type, this.root, keys); + self.root.children.push(this.index[key]); + self.children.push(this.index[key]); + self = this.index[key]; + break; + } + return self; + }; + /** + * Добавление в цепочку нового DOM элемента. + * Элемент парсится на текст, потом на узлы цепочки + * @param {Node} element DOM элемент, например с текстом статьи + * @returns {Chain} Новый узел или текущий, если не создан + */ + Chain.prototype.addElement = function(element){ + var self = this; + $(element).contents().each(function(node_i, node){ +// if (Node.ELEMENT_NODE === node.nodeType && (node.localName == 'ul' || node.localName == 'ol')){ +// self = self.addText('', node.localName); +// self.addElement(node); +// } + if (node.textContent){ + self = self.addText(node.textContent, Node.ELEMENT_NODE === node.nodeType ? node.localName : ''); + } + }); + return self; + }; + /** + * Является ли узел символом пунктуации? + * @returns {boolean} + */ + Chain.prototype.isPunctuation = function(){ + return /^[.,:!?]+$/.test(this.word); + }; + + Chain.prototype.isBadEnd = function(){ + return /^(вот|так|как|же|что|чем|и|или|а|то|ли|бы|в|с|к|за|на|о|об|обо|у|но|по|не|уж|из|под|при|,)$/i.test(this.word); + }; + + /** + * Создание предложения из цепочки + * @param words_min Минимальное кол-во слов + * @param words_max Максимальное кол-во слов + * @returns {string} + */ + Chain.prototype.getSentence = function(words_min, words_max){ + var words, text = '', tag; + words = this.iterator(words_min, words_max); + tag = ''; + var cnt = 0, w; + while (words.next()){ + if (words.current().type !== tag){ + if (tag) text += ''; + if (tag = words.current().type) text += '<'+words.current().type+'>'; + tag = words.current().type; + } + w = words.current().word; + if (!cnt){ + if (words.current().isPunctuation()){ + w = ''; + }else{ + w = w[0].toLocaleUpperCase() + w.slice(1); + } + } + if (!words.current().isPunctuation()){ + text += ' '; + } + text += w; + cnt++; + } + if (!/[.,!?:]$/.test(text)) text += "."; + if (tag) text += ''; + return text; + }; + + /** + * Создание текста с абзацами + * @param config Конфигурация текста (кол-во абзацев, предложений, слов) + * @returns {string} + */ + Chain.prototype.getText = function(config){ + var pcnt, scnt, text = ''; + pcnt = Math.round(Math.random()*(config.paragraphs.max-config.paragraphs.min))+config.paragraphs.min; + while (pcnt-->0){ + scnt = Math.round(Math.random()*(config.sentences.max-config.sentences.min))+config.sentences.min; + text += '

'; + while (scnt-->0){ + text += this.getSentence(config.words.min, config.words.max); + } + text += '

'; + } + return text; + }; + + /** + * Пустая ли цепочка? + * @returns {boolean} + */ + Chain.prototype.isEmpty = function(){ + return this.root.children.length === 0; + }; + + return Chain; + +})(jQuery); \ No newline at end of file diff --git a/habr.html b/habr.html index 4b8af99..2736152 100644 --- a/habr.html +++ b/habr.html @@ -44679,7 +44679,6 @@

Дисклеймер

-
Скрытый текст
@@ -44702,7 +44701,6 @@

Дисклеймер
Этот?
-
Картинка

@@ -45895,7 +45893,7 @@

Дисклеймер

-
Подсказка
Это — два пистолета одной и той же модели. «Liberator» — это и есть «Освободитель». +ПодсказкаЭто — два пистолета одной и той же модели. «Liberator» — это и есть «Освободитель».
@@ -46430,7 +46428,7 @@

Коммьюнити


Вот не знаю выжимает максимум или нет из железа, но мне заполнилась графика из FinalFantasy 9.
-
Да и в википедии всякое пишут
Final Fantasy IX создавалась в поздний период эпохи 32/64-разрядных игровых систем, и компания Square к этому времени на PlayStation выпустила более двух десятков игр, поэтому разработчики, отвечавшие за производительность и быстродействие, отлично понимали технические возможности консоли и в отношении визуализации смогли добиться поистине высоких результатов +Да и в википедии всякое пишутFinal Fantasy IX создавалась в поздний период эпохи 32/64-разрядных игровых систем, и компания Square к этому времени на PlayStation выпустила более двух десятков игр, поэтому разработчики, отвечавшие за производительность и быстродействие, отлично понимали технические возможности консоли и в отношении визуализации смогли добиться поистине высоких результатов
@@ -47902,7 +47900,6 @@

Коммьюнити


Весь из себя курортный остров Mallorca, где-то в курортном же городке Illetas:
-
Скрытый текст

@@ -48677,7 +48674,7 @@

Коммьюнити


на баше прочитал про коммент, вспомнил документальное тому подтверждение ( если кто не читал Стивена Леви), пара цитат из его книги
-
Хакеры: Герои компьютерной революции
У SAIL хакеров не заняло много времени, чтобы выяснить, что промежуток между подвесным потолком и собственно крышей может быть вполне комфортабельным местом для сна, и некоторые из них так и жили там, в течение многих лет. В начале 70 х годов один системный хакер вообще жил в неисправном автомобиле, припаркованном невдалеке от здания. Он раз в неделю спускался на велосипеде в Пало Альто за едой.
+Хакеры: Герои компьютерной революции
У SAIL хакеров не заняло много времени, чтобы выяснить, что промежуток между подвесным потолком и собственно крышей может быть вполне комфортабельным местом для сна, и некоторые из них так и жили там, в течение многих лет. В начале 70 х годов один системный хакер вообще жил в неисправном автомобиле, припаркованном невдалеке от здания. Он раз в неделю спускался на велосипеде в Пало Альто за едой.

@@ -63125,7 +63122,6 @@

Вывод.



-
скан
@@ -70298,7 +70294,7 @@

Итог


Не могу даже представить, чем она может быть похожа. У меня точно такая же лежит дома — полная противоположность ThinkPad'овским. Клавиши, по-моему, даже без пантографов — при нажатии на край клавиша перекашивается и с трудом пропихивается вниз, распиханные по краю Home/End/PgUp/PgDown, Insert слева от стрелок, F-клавиши без разделения на группы и т.д.
-Для сравнения:
ThinkPad keyboard
+Для сравнения:ThinkPad keyboard
@@ -70633,7 +70629,7 @@

Итог


Хм, а какой смысл покупать процы сделанные для разгона, и не разгонять их? :) Что касается мак мини, то cpubenchmark не совсем адекватный. Вот к примеру тест в реальном приложении, Photoshop — i7-3720QM выполняет тест за 30,1 секунду, а i7-2600K (даже без разгона) тот же тест выполняет за 19,7 секунд. Т.е. уже в 1,5 раза медленнее
-
i7-3720QM против i7-2600K
+i7-3720QM против i7-2600K
@@ -70806,7 +70802,6 @@

Итог


В тему о компактных корпусах — могу посоветовать Cooler Master Elite 120. Немножко погабаритнее, чем Sugo SG07, но зато в несколько раз дешевле, даже с учетом покупки БП. Собрал в данном корпусе домашний NAS, качеством и комплектацией доволен на все 100%. Даже стильные черные стяжечки для кабель-менеджмента в комплекте есть :)
-
Скрытый текст
@@ -93468,7 +93463,7 @@
Ссылки и контакты

shara
-
Ответ айтишников мира не заставит себя ждать
+ Ответ айтишников мира не заставит себя ждать
@@ -95337,7 +95332,7 @@
Ссылки и контакты

Может, пригодится кому – слепил для себя, ибо смотрю базу вручную. :)
-
Конвертер из base32 в обычный hex формат.
Скопировать в файл (.xxe), декодировать в .rar Total Commander'ом или чем-нибудь наподобие http://www.webutils.pl/XXencode.
+Конвертер из base32 в обычный hex формат.Скопировать в файл (.xxe), декодировать в .rar Total Commander'ом или чем-нибудь наподобие http://www.webutils.pl/XXencode.

@@ -102161,13 +102156,9 @@

С Новым Годом!

Скрины 'as is':
-
- -

- -

- -
+
+
+
@@ -104748,7 +104739,6 @@

UPD: Видео


UPD: Переместил в учебный процесс. Спасибо.
-
diff --git a/index.html b/index.html new file mode 100644 index 0000000..a4b4814 --- /dev/null +++ b/index.html @@ -0,0 +1,908 @@ + + + + + 3-oop-js-dom + + + + + + + + + + + + + +
+
+ +
  + +
+
+ + + +
+
+

Бредописатель

+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + — + +
+
+
+ +
+ + — + +
+
+
+ +
+ + — + +
+
+
+ +
+ + — + +
+
+ +
+ +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+ + + + \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..b75f284 --- /dev/null +++ b/main.js @@ -0,0 +1,66 @@ +/** + * Создание среднестатической хабра-статьи с комментариями + * @version 1.0 + * @date 08.10.2013 + * @author Vladimir Shestakov + */ +(function($, Bred){ + + $(document).ready(function(){ + var $content = $('#content'), + $wait = $('#bred_wait'), + $form = $('#bred_form'); + + // Генерируем и показываем бред + $form.on('submit', function(e){ + + // Шаблон статьи и комментария + var tpl = { + comment: $('#bred_comment').remove(), + article: $('#bred_article').remove(), + places:{ + title: '.post_title', + date: '.post_date', + text: '.post_text', + comments: '.post_comments', + comments_cnt: '.post_comments_count', + comment_places: { + username: '.username', + date: '.date', + text: '.message', + sub: '.reply_comments' + } + } + }; + var config = { + quality: parseInt($form.find('[name="quality"]').val()), + words:{ + max: parseInt($form.find('[name="words[min]"]').val()), + min: parseInt($form.find('[name="words[max]"]').val()) + }, + paragraphs:{ + max: parseInt($form.find('[name="paragraphs[min]"]').val()), + min: parseInt($form.find('[name="paragraphs[max]"]').val()) + }, + sentences:{ + max: parseInt($form.find('[name="sentences[min]"]').val()), + min: parseInt($form.find('[name="sentences[max]"]').val()) + }, + comments:{ + max: parseInt($form.find('[name="comments[min]"]').val()), + min: parseInt($form.find('[name="comments[max]"]').val()) + } + }; + + $form.addClass('hide'); + $wait.show(); + + $.get($form.find('[name="src"]').val(), function(src){ + $content.append((new Bred(src, config)).render(tpl)); + $wait.hide(); + }); + + return false; + }) + }); +})(jQuery, Bred); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..c9c8dba --- /dev/null +++ b/style.css @@ -0,0 +1,73 @@ +/* Форма настроек бреда */ +#bred_form +{ + margin-top: -14px; +} + +#bred_form .block +{ + background: #F0F0E7; + border-radius: 5px; + padding: 15px 20px; +} + +#bred_form.hide +{ + position: fixed; + left: 30px; +} + +#bred_form.hide .block +{ + display: none; +} + +#bred_form h1 +{ + margin: 0 0 20px; +} + +#bred_form .item +{ + clear: both; + margin: 10px 0; + height: 16px; +} + +#bred_form .item > label +{ + float: left; + width: 180px; +} + +#bred_form .item > div +{ + float: left; +} + +#bred_form .item select +{ + width: 50px; +} + +#bred_form .item select[name="src"]{ + width: 200px; +} + +#bred_form .buttons +{ + margin-top: 20px; +} + +/* Коррекция хабра стилей */ +#bred_article .post_text p, +#bred_article .post_text pre +{ + margin: 15px 0; +} + +#bred_article .post_text pre{ + background: #eee; + border: 1px solid #ddd; + padding: 5px; +} \ No newline at end of file