├── sample ├── index.html └── corpus.js ├── README.md ├── markov.js └── json2.js /sample/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Markov Sample 4 | 5 | 6 | 7 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Markov Text Generator 2 | ===================== 3 | 4 | Why? 5 | ---- 6 | 7 | Because to understand markov chains I needed to hack something together. And to be honest, it produces some pretty interesting little stories, given the right input. 8 | 9 | How? 10 | ---- 11 | 12 | After including json2.js and markov.js in your page... 13 | 14 | var test = new markov(text, type, regex); 15 | 16 | The text can be anything you so desire. 17 | The type should be "string" or "json". 18 | And the regex should always be global. All matches are used. 19 | 20 | Methods 21 | ------- 22 | 23 | to generate a phrase of a given length: 24 | 25 | test.gen(length); 26 | 27 | to see the object containing the data: 28 | 29 | test.data; 30 | 31 | to get the JSON generated by JSON2.js of the data: 32 | 33 | test.getJson(); 34 | 35 | A warning though, you probably only want to use the JSON for making things a bit faster on the processing end with long text, as the JSON tends to be an order of magnitude greater in file size than the input text. 36 | 37 | Copyright 38 | --------- 39 | 40 | This is all open source, you can use it however you like. Especially to learn. 41 | 42 | That said, I would enjoy it if you would send me a sample to work produced by this. 43 | 44 | Oh, and JSON2.js isn't mine, the source can be found at http://www.json.org/json2.js -------------------------------------------------------------------------------- /markov.js: -------------------------------------------------------------------------------- 1 | /*sample regexes: 2 | 3 | /./g - every letter 4 | /../g - every two letter 5 | /[.,?"();\-!':—^\w]+ /g - every word 6 | /([.,?"();\-!':—^\w]+ ){2}/g - every two words 7 | 8 | */ 9 | var markov = function(input, type, reg) { 10 | var data; 11 | if (type == "string") { 12 | data = {}; 13 | s = input.match(reg); 14 | for (var i = 0; i < s.length-1; i++) { 15 | if(s[i] in data) { 16 | if (s[i+1] in data[s[i]]) { 17 | data[s[i]][s[i+1]]++; 18 | } else { 19 | data[s[i]][s[i+1]] = 1; 20 | } 21 | } else { 22 | data[s[i]] = new Object(); 23 | data[s[i]][s[i+1]] = 1; 24 | } 25 | } 26 | } else if (type == "json") { 27 | data = eval("(" + input + ")"); 28 | } 29 | this.data = data; 30 | 31 | var gen = function(l) { 32 | var sanitycheck = false; 33 | var out = new Array(); 34 | while (sanitycheck == false) { 35 | sanitycheck = true; 36 | var rProperty = findRandomProperty(data); 37 | var rList = expand(rProperty); 38 | var l1 = rList.length; 39 | out[0] = rList[Math.round(Math.random() * l1)]; 40 | if (typeof out[0] == "undefined") { sanitycheck = false; } 41 | if (sanitycheck) { 42 | for (var i = 0; i < l-1; i++) { 43 | var usableLength = expand(data[out[i]]).length-1; 44 | var randomInt = Math.round(Math.random() * usableLength); 45 | var nextLetter = expand(data[out[i]])[randomInt]; 46 | out.push(nextLetter); 47 | } 48 | } 49 | } 50 | return out.join(""); 51 | } 52 | this.gen = gen; 53 | 54 | var findRandomProperty = function(o) { 55 | l1 = 0; 56 | for (i in o) { 57 | l1++; 58 | } 59 | var r1 = Math.round(Math.random() * l1); 60 | l2 = 0; 61 | for (i in o) { 62 | l2++; 63 | if (l2 == r1) { 64 | return o[i]; 65 | } 66 | } 67 | } 68 | 69 | var expand = function(obj) { 70 | oArray = new Array(); 71 | for (var prop in obj) { 72 | for (var i = 0; i < obj[prop]; i++) { 73 | oArray.push(prop); 74 | } 75 | } 76 | return oArray; 77 | } 78 | 79 | var getJson = function() { 80 | if (typeof JSON === "object") { 81 | return JSON.stringify(data); 82 | } 83 | } 84 | this.getJson = getJson; 85 | } -------------------------------------------------------------------------------- /json2.js: -------------------------------------------------------------------------------- 1 | /* 2 | * http://www.JSON.org/json2.js 3 | * 2010-03-20 4 | * 5 | * Public Domain. 6 | * 7 | * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 8 | * 9 | * See http://www.JSON.org/js.html 10 | * 11 | */ 12 | if(!this.JSON){this.JSON={};} 13 | (function(){function f(n){return n<10?'0'+n:n;} 14 | if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+ 15 | f(this.getUTCMonth()+1)+'-'+ 16 | f(this.getUTCDate())+'T'+ 17 | f(this.getUTCHours())+':'+ 18 | f(this.getUTCMinutes())+':'+ 19 | f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};} 20 | var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';} 21 | function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);} 22 | if(typeof rep==='function'){value=rep.call(holder,key,value);} 23 | switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';} 24 | gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i