diff --git a/README.md b/README.md index 9185db0..90682a7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 3-oop-js-dom +[https://rawgithub.com/ArtKuz/3-oop-js-dom/master/index.html](https://rawgithub.com/ArtKuz/3-oop-js-dom/master/index.html) + ## Алгоритм, ООП, DOM, JQuery и Хабрахабр Третье домашнее задание по курсу ШРИ: ООП, Javascript, DOM и JQuery. diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..57e22b3 --- /dev/null +++ b/css/style.css @@ -0,0 +1,699 @@ +html, +body, +h1, +h2, +p +{ + margin: 0; +} + +ol, ul +{ + list-style: none outside none; +} + +a +{ + color: #6DA3BD; +} + +a:hover +{ + color: #4D7285; +} + +body +{ + padding: 10px; + min-width: 600px; + background: #fff; + color: #000; + text-align: left; + font: 400 14px Arial, Helvetica, sans-serif; +} + +header +{ + height: 195px; + border-bottom: 4px solid #fc3; +} + +h1 +{ + padding: 0 0 10px; + text-align: center; + font: 400 36px Verdana, Helvetica, sans-serif; +} + +h1 span +{ + color: #f00; +} + +button +{ + position: relative; + display: inline-block; + margin: 0.5em; + padding: 0.5em 0.6em 0.4em; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + background-color: #bfbfbf; + box-shadow: 0 0.3em 0.3em rgba(255, 254, 255, 0.6) inset, 0 -0.1em 0.3em rgba(0, 0, 0, 0.15) inset, 0 0.1em 3px #999, 0 0.3em 1px #727272, 0 0.5em 5px rgba(0, 0, 0, 0.2); + color: #333; + text-decoration: none; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + font: bold 14px/1em Arial, Helvetica, sans-serif; + transition: background 0.2s ease-in-out 0s; +} + +button:hover +{ + background: #D3D3D3; + cursor: pointer; +} + +button:active +{ + box-shadow: 0 0.3em 0.3em rgba(255, 255, 255, 0.6) inset, 0 -0.1em 0.3em rgba(0, 0, 0, 0.2) inset, 0 0.1em 1px rgba(0, 0, 0, 0.4), 0 0.2em 6px rgba(0, 0, 0, 0.2); + transform: translateY(0.2em); +} + +button:focus +{ + outline: medium none; + color: rgba(254, 255, 255, 0.898); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); +} + +button[disabled], .button[disabled]:hover, .button.disabled, .button.disabled:hover +{ + border-top: medium none; + background-color: rgba(0, 0, 0, 0.05); + background-image: none; + box-shadow: 0 0.3em 0.3em rgba(255, 254, 255, 0.4) inset, 0 -0.1em 0.3em rgba(0, 0, 0, 0.1) inset, 0 0.1em 1px rgba(0, 0, 0, 0.3), 0 0.2em 6px rgba(0, 0, 0, 0.2); + color: rgba(0, 0, 0, 0.2); + text-shadow: none; + opacity: 0.5; + cursor: default; + transform: translateY(5px); +} + +input +{ + width: 33px; +} + +.settings +{ + float: left; +} + +.settings span +{ + font-weight: 700; +} + +.settings .setting +{ + padding: 3px 0; +} + +.settings .setting .words +{ + float: left; + padding: 5px 46px 0 0; +} + +.settings .setting .proffer +{ + float: left; + padding: 5px 32px 0 0; +} + +.settings .setting .paragraph +{ + float: left; + padding: 5px 49px 0 0; +} + +.buttons +{ + float: right; + margin: 77px 0 0; + width: 250px; + text-align: center; +} + +.buttons .control +{ + padding: 3px 0; + text-align: center; +} + +.buttons .control label +{ + padding: 5px 0 0; +} + +#loading +{ + position: absolute; + z-index: 1; + display: none; + width: 100%; + height: 100%; + background: #fff; + opacity: 0.8; +} + +#loading img +{ + margin: 70px 50%; +} + +#loading .textload +{ + left: 30px; + position: relative; + text-align: center; + top: -60px; +} + +section +{ + margin: 30px auto; + width: 880px; +} + +header section +{ + margin: 0 auto; +} + +article +{ + display: none; +} + +article .published +{ + margin: 0 0 2px; + color: #7E7E7E; + font-size: 11px; +} + + +article h1.title +{ + margin: 0 0 8px; + padding: 0; + color: #333333; + text-align: left; + letter-spacing: -1px; + font: normal 30px/118% sVerdana,Tahoma,sans-serif; +} + +article .hubs { + margin: 0 0 15px; + padding: 2px 25px; + background: url("../images/hub.icon.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0); + color: #999; + font-size: 11px; +} + +article .hubs a +{ + color: #999; +} + +article .content +{ + overflow: hidden; + margin: 0 0 15px; + font: 13px/160% Verdana,sans-serif; +} + +article .content p +{ + padding: 10px 0; +} + +article .content code +{ + display: block; + margin: 15px 0; + padding: 0 4px; + border: 1px solid #E1E1E8; + border-radius: 3px; + background-color: #F7F7F9; + color: #222; + white-space: pre-wrap; + font-family: 12px Menlo,Monaco,"Courier New",monospace; +} + +article ul.tags +{ + margin: 0 0 15px; + padding: 2px 0 2px 20px; + background: url("../images/bg-tags2.gif") no-repeat scroll 0 50% rgba(0, 0, 0, 0); + font: 10px Verdana,sans-serif; +} + +article ul.tags li +{ + display: inline; + color: #999; +} + +article ul.tags li a +{ + color: #666; +} + +article .infopanel +{ + display: inline-block; + padding: 0 10px; + border: 1px solid #E5E5E5; + border-radius: 5px; + vertical-align: middle; + font-family: 11px Arial,sans-serif; +} + +article .infopanel .voting +{ + position: relative; + float: left; + margin: 6px 26px 6px 0; + padding: 0 20px; +} + +article .infopanel .voting span.plus +{ + background: url("../images/icons_vote_posts.gif") no-repeat scroll right top rgba(0, 0, 0, 0); +} + +article .infopanel .voting .plus +{ + position: absolute; + top: 0; + left: 0; + display: block; + width: 11px; + height: 15px; +} + +article .infopanel .voting .mark +{ + float: left; + margin-top: 1px; + color: #A9A9A9; + font-weight: 700; + font-size: 12px; +} + +article .infopanel .voting .mark.positive span +{ + color: #390; +} + +article .infopanel .voting span.minus +{ + background: url("../images/icons_vote_posts.gif") no-repeat scroll right bottom rgba(0, 0, 0, 0); +} + +article .infopanel .voting .minus +{ + position: absolute; + top: 0; + right: 0; + display: block; + width: 11px; + height: 15px; +} + +article .infopanel .pageviews +{ + float: left; + margin: 0 20px 0 0; + padding: 0 0 0 20px; + background: url("../images/pageviews.png") no-repeat scroll 0 6px rgba(0, 0, 0, 0); + font-size: 9px; + line-height: 28px; +} + +article .infopanel .favorite +{ + float: left; + margin: 0 5px 0 0; + padding: 6px 0 5px; +} + +article .infopanel .favorite a.guest +{ + background: url("../images/favorite.gif") no-repeat scroll left top rgba(0, 0, 0, 0); + cursor: help; +} + +article .infopanel .favorite a +{ + display: block; + margin: 1px 0 0 0; + width: 15px; + height: 13px; +} + +article .infopanel .favs_count +{ + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 9px; + line-height: 28px; + cursor: help; +} + +article .infopanel .author +{ + position: relative; + float: left; + margin: 0 0 0 19px; + padding: 0 0 0 17px; + background: url("../images/bg-user2.gif") no-repeat scroll 0 7px rgba(0, 0, 0, 0); + font-weight: 700; + line-height: 27px; +} + +article .infopanel .author a +{ + color: #CF0000; + text-decoration: none; + font-size: 9px; +} + +article .infopanel .author a:hover +{ + color: #F17D7D; +} + +article .infopanel .author .rating +{ + position: relative; + top: -5px; + left: 0; + color: #C6C; + white-space: nowrap; + font-weight: 700; + font-size: 9px; + cursor: help; +} + +article .infopanel .share +{ + float: left; + overflow: hidden; + margin-left: 19px; +} + +article .infopanel .twitter, +article .infopanel .vkontakte, +article .infopanel .facebook, +article .infopanel .googleplus +{ + float: left; + margin: 0 5px 0 0; + padding: 5px 0; +} + +article .infopanel .twitter a +{ + display: block; + width: 19px; + height: 19px; + background: url("../images/share.icons.png") no-repeat scroll -42px 0 rgba(0, 0, 0, 0); + opacity: 0.5; +} + +article .infopanel .vkontakte a +{ + display: block; + width: 19px; + height: 19px; + background: url("../images/share.icons.png") no-repeat scroll -21px 0 rgba(0, 0, 0, 0); + opacity: 0.5; +} + +article .infopanel .facebook a +{ + display: block; + width: 19px; + height: 19px; + background: url("../images/share.icons.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0); + opacity: 0.5; +} + +article .infopanel .googleplus a +{ + display: block; + width: 19px; + height: 19px; + background: url("../images/share.icons.png") no-repeat scroll -63px 0 rgba(0, 0, 0, 0); + opacity: 0.5; +} + +article .infopanel .twitter a:hover +{ + background: url("../images/share.icons.png") no-repeat scroll -42px -21px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .vkontakte a:hover +{ + background: url("../images/share.icons.png") no-repeat scroll -21px -21px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .facebook a:hover +{ + background: url("../images/share.icons.png") no-repeat scroll 0 -21px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .googleplus a:hover +{ + background: url("../images/share.icons.png") no-repeat scroll -63px -21px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .twitter a:active +{ + background: url("../images/share.icons.png") no-repeat scroll -42px -42px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .vkontakte a:active +{ + background: url("../images/share.icons.png") no-repeat scroll -21px -42px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .facebook a:active +{ + background: url("../images/share.icons.png") no-repeat scroll 0 -42px rgba(0, 0, 0, 0); + opacity: 1; +} + +article .infopanel .googleplus a:active +{ + background: url("../images/share.icons.png?r=1") no-repeat scroll -63px -42px rgba(0, 0, 0, 0); + opacity: 1; +} + +.comments_list +{ + position: relative; + overflow: hidden; + margin: 20px 0 10px; + padding: 20px; +} + +.comments_list h2.title +{ + margin: 0 0 20px; + padding: 0 0 0 23px; + background: url("../images/comments.gif") no-repeat scroll left 65% rgba(0, 0, 0, 0); + color: #AFA56A; + letter-spacing: -1px; + font-family: 400 20px Verdana,sans-serif; +} + +.comments_list .comment_item .info +{ + position: relative; + font: 11px/18px tahoma,sans-serif; +} + +.comments_list .comment_item .info .folding-dot-holder +{ + position: absolute; + top: 0; + left: 0; + display: none; + width: 1px; + height: 1px; +} + +.comments_list .comment_item .info .folding-dot +{ + position: absolute; + top: 9px; + right: 1px; + width: 500px; + height: 5px; + background: url("../images/bg-folding-dot-light.png") repeat-x scroll 100% 0 rgba(0, 0, 0, 0); +} + +.comments_list .comment_item:hover > .comment_body .info > .folding-dot-holder { + display: block; +} + +.comments_list .comment_item .info .voting +{ + float: right; + margin-top: 2px; + margin-right: 2px; +} + +.comments_list .comment_item .info .voting span.minus +{ + background: url("../images/icons_vote_posts.gif") no-repeat scroll -24px -16px rgba(0, 0, 0, 0); +} + +.comments_list .comment_item .info .voting .minus +{ + display: block; + float: right; + margin: 2px 0 0 5px; + width: 11px; + height: 15px; +} + +.comments_list .comment_item .info .voting span.plus +{ + background: url("../images/icons_vote_posts.gif") no-repeat scroll -24px 0 rgba(0, 0, 0, 0); +} + +.comments_list .comment_item .info .voting .plus +{ + display: block; + float: right; + margin: 2px 0 0 13px; + width: 11px; + height: 15px; +} + +.comments_list .comment_item .info .voting .mark +{ + float: right; + padding-top: 2px; + color: #A9A9A9; + font: 700 13px Arial,Helvetica,sans-serif; +} + +.comments_list .comment_item .info .voting .mark.positive span +{ + color: #390; +} + +.comments_list .comment_item .info a.avatar +{ + display: block; + float: left; + overflow: hidden; + margin: 0 10px 0 0; + width: 24px; + height: 24px; + border-radius: 3px; +} + +.comments_list .comment_item .info a.avatar img +{ + display: block; + width: 24px; + height: 24px; +} + +.comments_list .comment_item .info a.username +{ + display: block; + float: left; + margin: 3px 0 0 0; + color: #666; + font-weight: bold; +} + +.comments_list .comment_item .info a.username:hover +{ + color: #333; +} + +.comments_list .comment_item .info .comma +{ + display: block; + float: left; + margin: 3px 10px 0 0; + color: #666; + font-weight: 700; +} + +.comments_list .comment_item .info time +{ + display: block; + float: left; + margin: 3px 10px 0 0; + color: #666; + font-size: 10px; +} + +.comments_list .comment_item .info a.link_to_comment, .comments_list .comment_item .info a.to_parent +{ + text-decoration: none; +} + +.comments_list .comment_item .info a.link_to_comment +{ + display: block; + float: left; + margin: 3px 10px 0 0; + font-size: 11px; +} + +.comments_list .comment_item .info .to_chidren +{ + display: block; + float: left; + margin: 0 0 0 4px; +} + +.clear +{ + clear: both; +} + +.comments_list .comment_item .message +{ + padding: 10px 0 5px; + font: 13px/140% Arial,sans-serif; +} + +.comments_list .comment_item .reply_comments +{ + margin: 20px 0 0; +} + +.comments_list .comment_item .reply_comments .comment_item +{ + margin: 0 0 0 20px; +} \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..679b043 Binary files /dev/null and b/favicon.ico differ diff --git a/images/bg-author-link.gif b/images/bg-author-link.gif new file mode 100644 index 0000000..f70c208 Binary files /dev/null and b/images/bg-author-link.gif differ diff --git a/images/bg-folding-dot-light.png b/images/bg-folding-dot-light.png new file mode 100644 index 0000000..b11caa6 Binary files /dev/null and b/images/bg-folding-dot-light.png differ diff --git a/images/bg-tags2.gif b/images/bg-tags2.gif new file mode 100644 index 0000000..badff95 Binary files /dev/null and b/images/bg-tags2.gif differ diff --git a/images/bg-user2.gif b/images/bg-user2.gif new file mode 100644 index 0000000..66b20c2 Binary files /dev/null and b/images/bg-user2.gif differ diff --git a/images/comments.gif b/images/comments.gif new file mode 100644 index 0000000..ab2980d Binary files /dev/null and b/images/comments.gif differ diff --git a/images/favorite.gif b/images/favorite.gif new file mode 100644 index 0000000..8e65d3d Binary files /dev/null and b/images/favorite.gif differ diff --git a/images/hub.icon.png b/images/hub.icon.png new file mode 100644 index 0000000..d298d9b Binary files /dev/null and b/images/hub.icon.png differ diff --git a/images/icons_vote_posts.gif b/images/icons_vote_posts.gif new file mode 100644 index 0000000..e4ea1cb Binary files /dev/null and b/images/icons_vote_posts.gif differ diff --git a/images/loading.gif b/images/loading.gif new file mode 100644 index 0000000..b1d6c5e Binary files /dev/null and b/images/loading.gif differ diff --git a/images/pageviews.png b/images/pageviews.png new file mode 100644 index 0000000..dda5da8 Binary files /dev/null and b/images/pageviews.png differ diff --git a/images/share.icons.png b/images/share.icons.png new file mode 100644 index 0000000..7b67317 Binary files /dev/null and b/images/share.icons.png differ diff --git a/images/stub-user-small.gif b/images/stub-user-small.gif new file mode 100644 index 0000000..6440d22 Binary files /dev/null and b/images/stub-user-small.gif differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..6e12dc5 --- /dev/null +++ b/index.html @@ -0,0 +1,135 @@ + + + + + + + Бредогенератор | 3-oop-js-dom | Кузвесов Артём + + + + + + +
+ Загрузка +
+
+
+
+

Бредогенератор

+
+
+ + +
+
+
Слов в предложении:
+ + + + +
+
+
Предложений в абзаце:
+ + + + +
+
+
Количество абзацев:
+ + + + +
+
+
+ +
+
+
+
+
+
+

+ +
+ +
+
+ +
+ +777 +
+ +
+
7000000
+
+ +
+
400
+
+ + 345 +
+ +
+
+

+ комментарии () +

+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/js/ajaxLoad.js b/js/ajaxLoad.js new file mode 100644 index 0000000..3d54ccb --- /dev/null +++ b/js/ajaxLoad.js @@ -0,0 +1,73 @@ +/** + * Бредогенератор. Подгрузка средствами ajax + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [ajaxHabr подгружаем файл, парсим его и собираем из него словари] + * @param {[string]} link [файл, который подгружаем] + * @return [содержимое подгружаемой ссылки] + */ +function ajaxHabr(link) { + $('header').after(""); + $.ajax({ + url: link, + dataType: 'text', + beforeSend: function () { + $('#loading').css('display', 'block'); + $('#loading .textload').text('Подгружаем файл...'); + }, + success: function (answer) { + $('#habr').append(answer); + }, + complete: function () { + $('#loading .textload').text('Парсим...'); + parser(); + $('#loading .textload').text('Собираем словари...'); + articlesArr = dictionarys(articlesArr, npref); + indexArticlesArr = indexDictionary(articlesArr); + articlesSize = indexArticlesArr.length - 1; + commentsArr = dictionarys(commentsArr, npref); + indexCommentsArr = indexDictionary(commentsArr); + commentsSize = indexCommentsArr.length - 1; + $('#loading .textload').text(''); + $('#loading').css('display', 'none'); + generateArticleComments(); + } + }); +} + +/** + * [ajaxImage подгружаем картинку по заголовку] + * @param {[string]} query [запрос, по которому искать изображениее в google] + * @return {[string]} [изображение для статьи] + */ +function ajaxImage(query) { + $.ajax({ + url: 'https://ajax.googleapis.com/ajax/services/search/images', + type: 'GET', + data : { + v : '1.0', + q : query, + rsz : 1 // возвращаем только 1 результат + }, + dataType : 'jsonp', + success : function (answer) { + if (answer.responseData.results[0]) { + answer = answer.responseData.results[0] + if (answer.width > 880) answer.width = '880'; + + var img = $('', { + src : answer.url, + width : answer.width, + alt : answer.titleNoFormatting + }); + $('article .content').prepend(img); + } + } + }); +} \ No newline at end of file diff --git a/js/articleGenerator.js b/js/articleGenerator.js new file mode 100644 index 0000000..6cbf9a7 --- /dev/null +++ b/js/articleGenerator.js @@ -0,0 +1,117 @@ +/** + * Бредогенератор. Генератор статьи + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [titleGenerator генератор бредозаголовока] + * @param {[array]} dictionary [словарь, на основании которого будет генерироваться бред] + * @param {[array]} indexDictionary [вспомогательная индексированная версия этого же словаря] + * @param {[number]} dictionarySize [размер словаря] + * @return {[string]} [бредозаголовок] + */ +function titleGenerator(dictionary, indexDictionary, dictionarySize) { + var title = ''; + var minWordsTitle = 3; // минимальное количество слов в заголовке + var maxWordsTitle = 5; // максимальное количество слов в заголовке + var minProfferTitle = 1; // минимальное количество предложений в заголовке + var maxProfferTitle = 3; // максимальное количество предложений в заголовке + + title = bredogenerator(dictionary, indexDictionary, dictionarySize, minWordsTitle, maxWordsTitle, minProfferTitle, maxProfferTitle); + + title = title.join(' '); + + // убираем лишние пробелы + title = title.replace(/\s([.,:?!])\s?/g, '$1 '); + + return title; +} + +/** + * [paragraphGenerator генератор бредостатьи] + * @param {[array]} dictionary [словарь, на основании которого будет генерироваться бред] + * @param {[array]} indexDictionary [вспомогательная индексированная версия этого же словаря] + * @param {[number]} dictionarySize [размер словаря] + * @return {[string]} [бредостатья] + */ +function paragraphGenerator(dictionary, indexDictionary, dictionarySize) { + var countParagraph = randomizer(minParagraphCount, maxParagraphCount); // получаем количество параграфов в статье + var text = ''; + + for (var i = 1; i <= countParagraph; i++) { + text += combArticles(bredogenerator(dictionary, indexDictionary, dictionarySize, minWordsCount, maxWordsCount, minProfferCount, maxProfferCount)); + } + + return text; +} + +/** + * [combArticles приводим полученный бред в порядок] + * @param {[array]} text [бредотекст] + * @return {[string]} [бредотекст, с сылками, кодом] + */ +function combArticles(text) { + // добавляем ссылки в параграф + var addLink = randomizer(1, 10); + if (addLink < 3) { // с вероятностью 29% в абзаце будет ссылка + var textSize = text.length - 1; // длина полученного абзаца + var randomLink = randomizer(0, linksArrSize); // случайная ссылка + var addPlace = randomizer(0, textSize); // куда добавить ссылку + text.splice(addPlace, 0, linksArr[randomLink]); + } + + text = text.join(' '); + + // убираем лишние пробелы + text = text.replace(/\s([.,:?!])\s?/g, '$1 '); + + // делаем из полученного текста полноценный html-абзац + text = '

' + text + '

'; + + // добавлям код после параграфа + if (codeArr.length >= 0) { + var addCode = randomizer(1, 10); + if (addLink < 6) { // с вероятностью 59% проверим стоит ли вставить код после абзаца + if (text.search(/(bash)/gi )+1) { + text += randomCode('bash'); + } else if (text.search(/(cpp)/gi )+1) { + text += randomCode('cpp'); + } else if (text.search(/(css)/gi )+1) { + text += randomCode('css'); + } else if (text.search(/(diff)/gi )+1) { + text += randomCode('diff'); + } else if (text.search(/(html)/gi )+1) { + text += randomCode('html'); + } else if (text.search(/(javascript|js)/gi )+1) { + text += randomCode('javascript'); + } else if (text.search(/(php)/gi )+1) { + text += randomCode('php'); + } else if (text.search(/(python)/gi )+1) { + text += randomCode('python'); + } else if (text.search(/(ruby)/gi )+1) { + text += randomCode('ruby'); + } else { + text += ''; + } + } + } + + return text; +} + +/** + * [completeArticle генератор конечной статьи] + * @return [статья, с текстом, ссылками, кодом, картинкой, названием, датой написания, автором] + */ +function completeArticle() { + dateCreateArticle = randomDate(new Date(2008, 0, 1), new Date()); + $('article .published').text(getHabraDate(dateCreateArticle)); + $('article h1').text(titleGenerator(articlesArr, indexArticlesArr, articlesSize)); + ajaxImage($('article h1').text()); + $('article .content').html(paragraphGenerator(articlesArr, indexArticlesArr, articlesSize)); + $('article .infopanel .author a').text(randomUser()); +} \ No newline at end of file diff --git a/js/assemblingDictionary.js b/js/assemblingDictionary.js new file mode 100644 index 0000000..012f040 --- /dev/null +++ b/js/assemblingDictionary.js @@ -0,0 +1,38 @@ +/** + * Бредогенератор. Сборка словаря + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [dictionarys собираем словарь, опираясь на цепи маркова] + * @param {[array]} array [массив из которого нужно собрать словарь] + * @param {[number]} npref [число слов в префиксе] + * @return {[array]} [словарь] + */ +function dictionarys(array, npref) { + var dictionary = []; // словарь + var arrayLength = array.length; // длина входного массива + + for (var i = 0; i < arrayLength - npref; i++) { + var prefix = array[i]; // добавляем первое слова в перфикс + for (var j = 1; j < npref; j++) { + prefix += ' ' + array[i + j]; // добавляем еще слова в префикс + } + + var suffix = array[i + j]; // находим суффикс для данного префикса + + // добавляем префикс и суфикс в словарь + if (dictionary[prefix] === undefined) { + dictionary[prefix] = [suffix]; + } else { + dictionary[prefix].push(suffix); + } + } + flagNpref = npref; + + return (dictionary); +} \ No newline at end of file diff --git a/js/commentsGenerator.js b/js/commentsGenerator.js new file mode 100644 index 0000000..24947c1 --- /dev/null +++ b/js/commentsGenerator.js @@ -0,0 +1,104 @@ +/** + * Бредогенератор. Генератор комментариев + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [commentGenerator гененратор одного комментария] + * @param {[array]} dictionary [словарь, на основании которого будет генерироваться бред] + * @param {[array]} indexDictionary [вспомогательная индексированная версия этого же словаря] + * @param {[number]} dictionarySize [размер словаря] + * @return {[string]} [комментарий] + */ +function commentGenerator(dictionary, indexDictionary, dictionarySize) { // генерируем текст комментария + var comment = ''; + var minWordsComment = 3; // минимальное количество слов в комментарии + var maxWordsComment = 20; // максимальное количество слов в комментарии + var minProfferComment = 1; // минимальное количество предложений в комментарии + var maxProfferComment = 7; // максимальное количество предложений в комментарии + + comment = bredogenerator(dictionary, indexDictionary, dictionarySize, minWordsComment, maxWordsComment, minProfferComment, maxProfferComment); // гененрируем комментарии в виде массива + + comment = comment.join(' '); // преобразуем массив в строку + + // убираем лишние пробелы + comment = comment.replace(/\s([.,:?!])\s?/g, '$1 '); + + return comment; +} + +/** + * [commentsCollector собираем комментарии в дрквовидную структуру] + * @param {[array]} dictionary [словарь, на основании которого будет генерироваться бред] + * @param {[array]} indexDictionary [вспомогательная индексированная версия этого же словаря] + * @param {[number]} dictionarySize [размер словаря] + * @return {[string]} [древовидная структура комментариев] + */ +function commentsCollector(dictionary, indexDictionary, dictionarySize) { + var minCommentsCount = 25; // минимальное количество комментариев первого уровня + var maxCommentsCount = 70; // максимальное количество комментариев первого уровня + var countComments = randomizer(minCommentsCount, maxCommentsCount); // получаем случайное количество комментариев первого уровня + var countCommentsEnd = 0; // общее количество комментариев + + if (dateCreateArticle != '') { // проверяем есть ли у нас дата создания статьи + lastDate = dateCreateArticle; + } else { // если нет, гененрируем новую дату + lastDate = randomDate(new Date(2008, 0, 1), new Date()); + } + + for (var i = 1; i <= countComments; i++) { + countCommentsEnd++; + // обертка для комментраия + var commentWrap = "
0
,#
"; + var commentDate = randomDate(lastDate, getNewDateComment(lastDate)); // случайная дата написания комментария, приближенная к дате написания статьи + lastDate = commentDate; // обновляем дату последнего комментария + + $('article #comments h2').after(commentWrap); // добавляем комментарий + $('article #comments .comment_item:first .username').text(randomUser()); // добавляем логин автора комментария + $('article #comments .comment_item:first time').text(getHabraDate(commentDate)); // добавляем дату написания комментария + $('article #comments .comment_item:first .message').text(commentGenerator(dictionary, indexDictionary, dictionarySize)); // гененрируем текст комментария + + // определяем бедет ли ответ(ы) на текущий комментарий + var secondLevel = randomizer(1, 10); + if (secondLevel < 5) { // с вероятностью 49% будет ответ на текущий комментарий + var minCommentsSecondLevelCount = 1; // минимальное количество комментариев второго уровня + var maxCommentsSecondLevelCount = 5; // максимальное количество комментариев второго уровня + var countSecondLevelComments = randomizer(minCommentsSecondLevelCount, maxCommentsSecondLevelCount); // получаем случайное количество комментариев второго уровня + + for (var j = 1; j <= countSecondLevelComments; j++) { + countCommentsEnd++; + commentDate = randomDate(lastDate, getNewDateComment(lastDate)); + lastDate = commentDate; + + $('article #comments .comment_item:first .reply_comments:first').append(commentWrap); + $('article #comments .comment_item:first .reply_comments:first .comment_item:last .username').text(randomUser()); + $('article #comments .comment_item:first .reply_comments:first .comment_item:last time').text(getHabraDate(commentDate)); + $('article #comments .comment_item:first .reply_comments:first .comment_item:last .message').text(commentGenerator(dictionary, indexDictionary, dictionarySize)); + + // определяем бедет ли ответ(ы) на текущий комментарий + var thirdLevel = randomizer(1, 10); + if (thirdLevel < 4) { // с вероятностью 39% будет ответ на текущий комментарий + var minCommentsThirdLevelCount = 1; // минимальное количество комментариев трертьего уровня + var maxCommentsThirdLevelCount = 3; // максимальное количество комментариев трертьего уровня + var countSecondLevelComments = randomizer(minCommentsThirdLevelCount, maxCommentsThirdLevelCount); // получаем случайное количество комментариев третьего уровня + + for (var j = 1; j <= countSecondLevelComments; j++) { + countCommentsEnd++; + commentDate = randomDate(lastDate, getNewDateComment(lastDate)); + lastDate = commentDate; + + $('article #comments .comment_item:first .reply_comments:first .comment_item:first .reply_comments:first').append(commentWrap); + $('article #comments .comment_item:first .reply_comments:first .comment_item:first .reply_comments:first .comment_item:last .username').text(randomUser()); + $('article #comments .comment_item:first .reply_comments:first .comment_item:first .reply_comments:first .comment_item:last time').text(getHabraDate(commentDate)); + $('article #comments .comment_item:first .reply_comments:first .comment_item:first .reply_comments:first .comment_item:last .message').text(commentGenerator(dictionary, indexDictionary, dictionarySize)); + } + } + } + } + } + $('article #comments_count').text(countCommentsEnd); +} \ No newline at end of file diff --git a/js/deliriumGenerator.js b/js/deliriumGenerator.js new file mode 100644 index 0000000..cc4c3dc --- /dev/null +++ b/js/deliriumGenerator.js @@ -0,0 +1,96 @@ +/** + * Бредогенератор. Непосредственно сам генератор бреда + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [bredogenerator генератор бреда] + * @param {[array]} dictionary [словарь, на основании которого будет генерироваться бред] + * @param {[array]} indexDictionary [вспомогательная индексированная версия этого же словаря] + * @param {[number]} dictionarySize [размер словаря] + * @param {[number]} minWordsCount [минимальное количество слов в предложеннии] + * @param {[number]} maxWordsCount [максимальное количество слов в предложении] + * @param {[number]} minProfferCount [минимальное количество абзацев] + * @param {[number]} maxProfferCount [максимальное количество абзацев] + * @return {[array]} [бредотекст] + */ +function bredogenerator(dictionary, indexDictionary, dictionarySize, minWordsCount, maxWordsCount, minProfferCount, maxProfferCount) { // бредогенератор текста + var text = []; // массив для хранения итогового текста + var startWords = collocation(indexDictionary, dictionarySize); + startWords[0] = capitaliseFirstLetter(startWords[0]); + text = text.concat(startWords); + + var textSize = text.length-1; // длина массива, с текстом на выход + var doubleWords = text[textSize-1] + ' ' + text[textSize]; + var randomWords = randomizer(minWordsCount, maxWordsCount); // случайное количество слов в абзаце + var randomProffer = randomizer(minProfferCount, maxProfferCount); // случайное количество предложений в абзаце + var countWords = 2; // счечик слов + var countProffer = 0; // счечик предложений + var newCollocation = ''; + var generate = true; + + while(generate) { + if (dictionary[doubleWords]) { + var suffixN = 0; // порядковый номер суффикса в массиве по умолчанию + var suffixSize = dictionary[doubleWords].length - 1; + + if (suffixSize > 0) { + suffixN = randomizer(0, suffixSize); + }; + + text.push(dictionary[doubleWords][suffixN]); + textSize++; + countWords++; + + if (countWords >= randomWords) { + if ((text[textSize].search(/[.,:;!\?]/)+1) || (text[textSize-1].search(/[.,:;!\?]/)+1)) { + text.pop();text.pop(); + newCollocation = collocation(indexDictionary, dictionarySize); + text = text.concat(newCollocation); + } + + randomWords = randomizer(minWordsCount, maxWordsCount); + text.push('.'); + textSize++; + countProffer++; + + if (countProffer >= randomProffer) { + generate = false; + } else { + newCollocation = collocation(indexDictionary, dictionarySize); + newCollocation[0] = capitaliseFirstLetter(newCollocation[0]); + text = text.concat(newCollocation); + textSize += 2; + countWords = 2; + } + } else { + if ((text[textSize-1].search(/[.!\?]/)+1)) { + countProffer++; + if (countProffer >= randomProffer) { + text.pop(); + generate = false; + } else { + text[textSize] = capitaliseFirstLetter(text[textSize]); + randomWords = randomizer(minWordsCount, maxWordsCount); + countWords = 1; + } + } + } + } else { + newCollocation = collocation(indexDictionary, dictionarySize); + if(text[textSize].search(/[.,!\?]/)+1) { + newCollocation[0] = capitaliseFirstLetter(newCollocation[0]); + } + text = text.concat(newCollocation); + textSize += 2; + countWords += 2; + } + doubleWords = text[textSize-1] + ' ' + text[textSize]; + } + + return text; +} \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..9e177fa --- /dev/null +++ b/js/main.js @@ -0,0 +1,34 @@ +/** + * Бредогенератор. Обработка кнопок + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [generateArticleComments генерация статьи и комментариев] + * @return [сгенрированная сатья с комментариями] + */ +function generateArticleComments() { + $('#loading').css('display', 'block'); + $('#loading .textload').text('Генерируем статью с комментариями...'); + completeArticle(); + commentsCollector(commentsArr, indexCommentsArr, commentsSize); + $('#loading .textload').text(''); + $('#loading').css('display', 'none'); + $('article').show(); +} + +/** + * обрабатываем нажатие на кнопку "Сгенерировать новый текст" + */ +$('body').on('click', '#generate', function() { + getSettings(); + if ((flagNpref != npref)) { + ajaxHabr("habr.html"); + } else { + generateArticleComments(); + } +}); \ No newline at end of file diff --git a/js/moreFunctions.js b/js/moreFunctions.js new file mode 100644 index 0000000..80ab06b --- /dev/null +++ b/js/moreFunctions.js @@ -0,0 +1,120 @@ +/** + * Бредогенератор. Дополнительные функции + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [randomizer генератор случайных целых чисел] + * @param {[number]} min [минимальное значение] + * @param {[number]} max [максимальное значение] + * @return {[number]} [случайное число между min и max] + */ +function randomizer(min, max) { + return ((Math.floor(Math.random() * (Number(max) - Number(min) + 1))) + Number(min)); +} + +/** + * [indexDictionary генератор вспомогательного индексового массива для словаря] + * @param {[array]} dictionary [словарь] + * @return {[array]} [проидексированный массив, где value = dictionary[key]] + */ +function indexDictionary(dictionary) { + var indexArray = []; + + for (key in dictionary) { + indexArray.push(key); + } + return indexArray; +}; + +/** + * [capitaliseFirstLetter делаем первую букву в слове с большой буквы] + * @param {[string]} text [словосочетание, где все буквы написаны в нижнем регистре] + * @return {[string]} [словосочетание, где первая уква в верхнем регистре] + */ +function capitaliseFirstLetter(text) { + return text.charAt(0).toUpperCase() + text.slice(1); +} + +/** + * [collocation получение случайного словосочетания] + * @param {[array]} indexDictionary [индексированный массив словаря] + * @param {[number]} dictionarySize [размер словаря] + * @return {[string]} [случайное словосочетание из массива = случайное value в indexDictionary] + */ +function collocation(indexDictionary, dictionarySize) { + var newCollocation = ''; + + do { + newCollocation = indexDictionary[randomizer(0, dictionarySize)]; + } while((newCollocation.search(/[.,;:!\?]+/g)+1)); + + return newCollocation.split(' '); +} + +/** + * [randomCode получение случайного отрывок кода] + * @param {[string]} language [язык программирования для которого нужно подобрать случайный отрывок кода] + * @return {[string]} [случайный отрывок кода на указанном языке] + */ +function randomCode(language) { + var language = codeArr[language]; + var languageLength = language.length - 1; + + return language[randomizer(0, languageLength)] +} + +/** + * [randomUser получение логина случайного пользователя] + * @return {[string]} [логин пользователя] + */ +function randomUser() { + var randomUserId = randomizer(0, usernameArrSize); // генерируем случайный id пользователя из массива + + return usernameArr[randomUserId] +} + +/** + * [randomDate получение случайной даты] + * @param {[object]} start [начальная дата] + * @param {[object]} end [конечная дата] + * @return {[object]} [случайная дата между начальной и конечной датами] + */ +function randomDate(start, end) { + return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())) +} + +/** + * [getHabraDate приведение даты в читаемый хабра-вид] + * @param {[object]} date [дата, которую надо преобразовать] + * @return {[string]} [преобразованная, читаемая дата хаьра-вида] + */ +function getHabraDate(date) { + var months = ['января','февраля','марта','апреля','мая','июня','июля','августа','сентября','октября','ноября','декабря']; + var hourse = date.getHours(); + var minutes = date.getMinutes(); + + if ((hourse/10) < 1) { + hourse = '0' + hourse; + } + if ((minutes/10) < 1) { + minutes = '0' + minutes; + } + + return date.getDate() + ' ' + months[date.getMonth()] + ' ' + date.getFullYear() + ' в ' + hourse + ':' + minutes; +} + +/** + * [getNewDateComment получение новой даты для гененрации комментариев] + * @param {[object]} date [дата, которую надо преобразовать] + * @return {[object]} [преобразованная дата] + */ +function getNewDateComment(date) { + var newDate = new Date(); + newDate.setTime(date.getTime() + 700000); + return newDate; +} \ No newline at end of file diff --git a/js/processing.js b/js/processing.js new file mode 100644 index 0000000..6d4228f --- /dev/null +++ b/js/processing.js @@ -0,0 +1,62 @@ +/** + * Бредогенератор. Собираем данные, генерируем статью с комментариями + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [getSettings собираем и обрабатываем данные о размере текста] + */ +function getSettings() { + var prefixCount = Number($('#prefixCount option:selected').text()); + if ((prefixCount > 1) && (prefixCount < 6)) { + npref = prefixCount; + } else { + npref = 2; + } + + var minWords = Number($('#minWordsCount').val()); + if ((minWords > 0) && (minWords < 50)) { + minWordsCount = minWords; + } else { + minWordsCount = 3; + } + + var maxWords = Number($('#maxWordsCount').val()); + if ((maxWords >= minWordsCount) && (maxWords < 101)) { + maxWordsCount = maxWords; + } else { + maxWordsCount = minWordsCount + 5; + } + + var minProffer = Number($('#minProfferCount').val()); + if ((minProffer > 0) && (minProffer < 30)) { + minProfferCount = minProffer; + } else { + minProfferCount = 3; + } + + var maxProffer = Number($('#maxProfferCount').val()); + if ((maxProffer >= minProfferCount) && (maxProffer < 90)) { + maxProfferCount = maxProffer; + } else { + maxProfferCount = minProffer + 5; + } + + var minParagraph = Number($('#minParagraphCount').val()); + if ((minParagraph > 0) && (minParagraph < 30)) { + minParagraphCount = minParagraph; + } else { + minParagraphCount = 3; + } + + var maxParagraph = Number($('#maxParagraphCount').val()); + if ((maxParagraph >= minParagraphCount) && (maxParagraph < 90)) { + maxParagraphCount = maxParagraph; + } else { + maxParagraphCount = minParagraphCount + 5; + } +} \ No newline at end of file diff --git a/js/processingInputText.js b/js/processingInputText.js new file mode 100644 index 0000000..e76d062 --- /dev/null +++ b/js/processingInputText.js @@ -0,0 +1,170 @@ +/** + * Бредогенератор. Обработка входного текста + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +/** + * [parser парсим статьи, комменты, логины, код, ссылки] + */ +function parser() { + // Собираем логины пользователей + $('#habr .username').each(function(){ + var $username = $(this).html(); + usernameArr.push($username); + }); + + $('#habr .username').remove(); + usernameArrSize = usernameArr.length - 1; // считаем, сколько получили логинов + + // Собираем код + $('#habr pre code').each(function(){ + var $codeLanguage = $(this).attr('class'); + var $codeText = $(this).clone().wrap('

').parent().html(); + + if (codeArr[$codeLanguage]) { + codeArr[$codeLanguage].push($codeText); + } else { + codeArr[$codeLanguage] = []; + codeArr[$codeLanguage].push($codeText); + } + }); + + $('#habr pre code').remove(); + + // Собираем ссылки + $('#habr a').each(function(){ + var $linkHref = $(this).attr('href'); + var $link = $(this).clone().wrap('

').parent().html(); + if ($linkHref) { + linksArr.push($link); + } + }); + + $('#habr a').remove(); + linksArrSize = linksArr.length - 1; // считаем, сколько получилось ссылок + + // Собираем комментарии + var comments = '';// тут будут храниться все комментарии + $('#habr .message').each(function(){ + var $message = $(this).text(); + comments += $message; + }); + + $('#habr .comments').remove(); + comments = textClear(comments); + commentsArr = comments.split(' '); + + // Собираем статьи + var articles = ''; // тут будут храниться все статьи + $('#habr article').each(function(){ + var $article = $(this).text(); + articles += $article; + }); + + $('#habr').remove(); + articles = textClear(articles); + articlesArr = articles.split(' '); +} + +/** + * [textClear очищаем текст от лишнего перед сборкой словаря] + * @param {[string]} text [текст, который нужно обработать] + * @return {[string]} [обработаный текст] + */ +function textClear(text) { + // заменяем некоторые символы на пробел + text = text.replace(/\s\B[\_\-\—\=\*]\s\B/g, ' '); + + // удаляем лишние символы + text = text.replace(/[\(\)\{\}\"\«\»\+\↔\→\♫\►\•\/\>\<]/g, ''); + + // заменяем несколько знаков на один + text = text.replace(/([.,;:!?])+/g, '$1'); + + // удаляем очевидные ссылки + text = text.replace(/[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi, ''); + + // заменяем сокращенные проблемные словосочетания на полные слова + text = text.replace(/(т\.д\.|т\.е\.|т\.к\.|т\.п\.|т\.о\.|vs\.)/g, function(value) { + switch (value) { + case 'т\.д\.': + return 'так далее'; + case 'т\.е\.': + return 'то есть'; + case 'т\.к\.': + return 'так как'; + case 'т\.п\.': + return 'тому подобное'; + case 'т\.о\.': + return 'таким образом'; + case 'vs\.': + return 'versus'; + default: + return ' '; + } + }); + + // избавляемся от тэгов + text = text.replace( /<.*?>/gi, ''); + + // отделяем . , : ? ! пробелами, чтобы считать их отдельными словами + text = text.replace(/(\s*[.,:?!])/g, ' $1 '); + + // преобразуем повторяющиеся пробелы в один пробел + text = text.replace(/\s+/g, ' '); + + // убираем пробел из начала строки + text = text.replace(/^\s*/, ''); + + // переводим буrвы в начале предложений в нижний регистре + text = text.replace(/(?:^|!?.;) [A-ZА-ЯЁ]/g, function(value) { + return value.toLowerCase(); + }); + + // переводим все пропущенные большие русские буквы в нижний регистр + text = text.replace(/\s[А-ЯЁ]/g, function(value) { + return value.toLowerCase(); + }); + + // учим компьютер правильно писать сокращения + text = text.replace(/(сЧ гСУ|гУВД|моск|росси|сБ|тСО|джобс|сССР|нАИРИ|пВО|аНБ|0_0|мТС|гСУ|мВД)/g, function(value) { + switch (value) { + case 'сЧ гСУ': + return 'СЧ ГСУ'; + case 'гУВД': + return 'ГУВД'; + case 'моск': + return 'Моск'; + case 'росси': + return 'Росси'; + case 'сБ': + return 'СБ'; + case 'тСО': + return 'ТСО'; + case 'джобс': + return 'Джобс'; + case 'сССР': + return 'СССР'; + case 'нАИРИ': + return 'НАИРИ'; + case 'пВО': + return 'ПВО'; + case 'аНБ': + return 'АНБ'; + case 'мТС': + return 'МТС'; + case 'гСУ': + return 'ГСУ'; + case 'мВД': + return 'МВД'; + default: + return ' '; + } + }); + + return text; +} \ No newline at end of file diff --git a/js/variables.js b/js/variables.js new file mode 100644 index 0000000..34e5735 --- /dev/null +++ b/js/variables.js @@ -0,0 +1,32 @@ +/** + * Бредогенератор. Переменные + * + * @author Artem Kuzvesov + * @version 1.0 + * @copyright Artem Kuzvesov 2013 + * + */ + +var usernameArr = []; // массив со всеми никами пользователей +var codeArr = []; // массив с кодом +var linksArr = []; // массив ссылок +var commentsArr = []; // массив комментариев +var articlesArr = []; // массив статей +var indexCommentsArr = []; // индексовый массив комментариев для ускорения работы +var indexArticlesArr = []; // индексовый массив статей для ускорения работы + +var npref = ''; // количество слоов в префиксе по умолчанию +var flagNpref = ''; // флаг значения npref +var minWordsCount = ''; // минимальное количество слоов в предложении по умолчанию +var maxWordsCount = ''; // максимальное количество слоов в предложении по умолчанию +var minProfferCount = ''; // минимальное количество предложений в в абзаце по умолчанию +var maxProfferCount = ''; // максимальное количество предложений в абзаце по умолчанию +var minParagraphCount = ''; // минимальное количество абзацей в статье по умолчанию +var maxParagraphCount = ''; // максимальное количество абзацей в статье по умолчанию +var articlesSize = ''; // длина массива со статьями +var commentsSize = ''; // длина массива с комментариями +var linksArrSize = ''; // длина массива со ссылками +var usernameArrSize = ''; // длина массива с логинами пользователей +var authorName = ''; // имя автора статьи +var dateCreateArticle = ''; // дата написания статьи +var lastDate = ''; // дата последнего комментария \ No newline at end of file