HR$RANDOMTEXT$VERSION = "1-00 [2005-01-06]"
// =====================================================================================================================
// Copyright (c) 2005  http://Henk-Reints.nl
// -----------------------------------------
// Dit is een zeer eenvoudige random tekst generator die (hopelijk) willekeurige betekenisloze woorden produceert die
// met een Nederlandse tongval redelijk uitspreekbaar zouden moeten zijn. Heeft geen enkele samenhang met statistische
// taalgegevens zoal b.v. letterfrequenties of wat dan ook. Enige wat ik probeer is om kreten op te bouwen die enigszins
// uitspreekbar zijn. Het resultaat zal zeer waarschijnlijk niet conform de Nederlandse spellingsregels zijn, hoewel er
// natuurlijk af en toe wel gewone bestaande woorden zullen worden geproduceerd. Je moet er echter niet op rekenen dat
// er via dit toevalsmechanisme ineens een diepzinnige filosofische uitspraak wordt gegenereerd. Hoewel?
//
// Eu bizut jia ij zoe chlou se lo ufvo jordeet ive giegots. Smaun au ofvevial bio inkuuko io uinneo wa go jea sja
// me igne. Atduufe ea eigge iendge ko eu he ja spia houvui ea tijnronea eudka ootga heu bui ughaveipdrea arwa.
// Ei voe etkoohifwia fo dou he ilm ijsguulhe alveu ia ea tandruikzij ippe ukaafge la. Heo gij io oetboe tje tag
// ugniseme vit ijlbe wo ba. Assee ef af bie iefdijtsufblea gwio oolrarwungst zo utzio fia ploe zeapreu ei ei
// isgenlee agme zupwa. Wo tie ans wie ounle wee ia ilgeve snapvaauw vui eitte be jea ada jea. Puidme lou urde no
// fe urwilap oelbepdresch ou antourseir epbui lee urbei zei ofep gui pioltoe. Veo utvui bo rufikgo heifblagd oupda
// leiho zia gwia geu vee ta edno erda disfigbo eiflea lozei grui so vo. Irufra ijmhuuputge tie zugna ou. Veu rat
// je sfer ertoennio olseemoum uimseutijsge ui auvedaje wafje mo. Aafdefleavio ka ve ga umvo uitsosupjou efmof
// ongaffendgie ea two vio hedhunt orn. Schoe wa bee fla jeisegpe ie kiad ui krulo meu wuuja ea ogja jee jattoe
// uirno iba. Ie fiko ats se eulja imhe ui afbliod to weat nui undreaf oepjeuk en assad bakijgha sij weu. Ekdeovean
// ze eughe ja smeo klo horvoe naus ve no anbou zuug zeo wo afker ea ia vo. Liba abo ho glui otlar ra kna odkia
// siolvul wup gla. Nia geo zovei ikge leo itma ui zee ou se eim ive ea udoessethe amza op ka we imveuza io ad.
// Lo agis leo eo woe updreo trea wo. Sloom rui zo wa peem zege.
//
// Principe:
// - twee lijsten, een met klinker(combinatie)s en een met medeklinker(combinatie)s;
//   per item is in de lijst aangegeven wat er eventueel voor en/of achter moet of niet mag;
// - bepaal naar willekeur hoeveel medeklinkers er in het woord komen, minimaal 1 en maximaal 3,
//   met P(1)=1/2, P(2)=1/3, P(3)=1/6 (P(n) = kans op aantal medeklinkers), dus voorkeur voor korte woorden;
// - als meer dan 1 medeklinker dan daartussen willekeurige toegestane klinkers zetten;
// - als voorste medeklinker een voorloopklinker MOET hebben dan altijd klinker ervoor,
//   anders naar willekeur (met kans van 20%) een klinker ervoor zetten;
// - als laatste medeklinker een naloopklinker MOET hebben dan altijd klinker erachter,
//   anders naar willekeur (met kans van 20%) een klinker erachter zetten;
// - af en toe (kans = 0.5%) zal een getal van max. 4 cijfers worden geretourneerd i.p.v. een woord van letters;
// - de gedefinieerde combinaties van twee verschillende klinkers kunnen ook als zelfstandig woord optreden (10%);
// - af en toe (30%) een woord van 1 medeklinker en 1 klinker;
// - bij selecteren willekeurige (mede)klinker 50% voorkeur voor eenletterige.
// =====================================================================================================================


function RandomTextGenerator100(rng)	// met 'rng' kun je een random number generator aangeven, default = Math.random
{					// 'rng' moet dus een functie zijn (de definitie, niet de aanroep)

	var random = (arguments.length > 0 ? rng : Math.random)
	var klink,mklink

// ---------------------------------------
// klinker(combinatie)s:
// 1: mag niet aan begin van woord
// 2: mag niet aan einde van woord
// 3: mag niet aan begin en niet aan einde
// ---------------------------------------
	klink  = "| a | e | i2| o | u2|"
	klink += "|aa2|ee |    oo2|uu2|"
	klink += "|au2|ea1|ei |eo1|eu |ia1|ie |ij |io1|oe |ou |ui |"

// ---------------------------------------------------------
// medeklinker(combinatie)s, niet gebruikt: c, q, x, y
// 1: er moet een klinker voor
// 2: er moet een klinker achter
// 3: er moet een klinker voor en een klinker achter
// 4: er mag geen klinker voor
// 6: er mag geen klinker voor en er moet een klinker achter
// ---------------------------------------------------------
	mklink  = "|b2|bb3|bd3|   |   |   |   |   |bl2|   |   |   |br2|   |bt1|   |   |   |"
	mklink += "|d |db3|dd3|df3|dg3|dh3|dj3|dk3|dl3|dm3|dn3|dp3|dr2|ds1|dt1|dv3|dw2|dz3|"
	mklink += "|f |fb3|fd1|ff3|fg3|fh3|fj3|fk3|fl2|fm3|fn2|fp3|fr2|fs1|ft1|fv3|fw3|fz3|"
	mklink += "|g |gb3|gd1|gf3|gg3|gh3|gj3|gk3|gl2|gm3|gn3|gp3|gr2|gs1|gt3|gv3|gw2|gz3|"
	mklink += "|h2|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |"
	mklink += "|j2|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |"
	mklink += "|k |kb3|kd3|kf3|kg3|   |kj3|kk3|kl2|km3|kn2|kp3|kr2|   |kt1|kv3|kw2|kz3|"
	mklink += "|l |lb3|ld1|lf3|lg1|lh3|lj3|lk1|ll3|lm1|ln3|lp1|lr3|ls1|lt1|lv3|   |lz3|"
	mklink += "|m |mb3|md1|mf3|mg3|mh3|mj3|mk3|ml3|mm3|mn3|mp1|mr3|ms1|mt3|mv3|mw3|mz3|"
	mklink += "|n |nb3|nd1|nf3|ng1|nh3|nj3|nk1|nl3|nm3|nn3|np3|nr3|ns1|nt1|nv3|nw3|nz3|"
	mklink += "|p |pb3|pd3|pf3|pg3|ph3|pj3|pk3|pl2|pm3|pn2|pp3|pr2|ps |pt |pv3|pw3|pz3|"
	mklink += "|r |rb3|rd3|rf1|rg1|rh3|rj3|rk1|rl3|rm3|rn1|rp1|rr3|rs1|rt1|rv3|rw3|rz3|"
	mklink += "|s |sb3|sd3|sf2|sg3|   |sj2|sk |sl2|sm2|sn2|sp2|   |ss3|st |   |sw2|   |"
	mklink += "|t |tb3|td3|tf3|tg3|th2|tj2|tk3|tl3|tm3|tn3|tp3|tr2|ts1|tt3|tv3|tw2|tz3|"
	mklink += "|v2|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |"
	mklink += "|w6|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |"
	mklink += "|z2|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |"

// ----------------------------
// speciale medeklinkercombi's:
// ----------------------------
	mklink += "|ch|chl2|chr2|sch|schr2|ndg3|ndr3|ngst1|ngt1|fbl3|pbl3|pdr3|uw|"

// ---------------------------------
// opschonen en er arrays van maken:
// ---------------------------------
	var  klinkarray =  klink.replace(/\s+/g,"").replace(/\|+/g,"|").replace(/^\|+/,"").replace(/\|+$/,"").split("|")
	var mklinkarray = mklink.replace(/\s+/g,"").replace(/\|+/g,"|").replace(/^\|+/,"").replace(/\|+$/,"").split("|")

// ----------------------------------------------
// nu ff beide arrays flink door elkaar huzzelen:
// ----------------------------------------------
	function huzzel(a) {var i,j,k,m,x; for(i=0,m=a.length; i<m; j=ran(m),k=ran(m),x=a[j],a[j]=a[k],a[k]=x,i++);}
	huzzel( klinkarray)
	huzzel(mklinkarray)

// --------------------------
// maak woorden voor cijfers:
// --------------------------

	var cijfer	// wordt een array
	maakCijfers()

// ==========================================
// EINDE INITIALISATIE VAN INTERNE VARIABELEN
// ==========================================

// -------------------
// random generatoren:
// -------------------
	function ran(N) {return Math.floor(random()*N)%N}	// geeft willekeurig geheel getal in [0,N)
	function RAN(array)					// geeft willekeurige (mede)klinker + bijbehorende code
	{	var r = ran(100)
		do {	var x = array[ran(array.length)]
			var c = x.slice(-1)
			if ("0123456789".indexOf(c) < 0) c = "0"
			else x = x.slice(0,-1)
		} while (r > 50 && x.length > 1)
		return [x,parseInt(c,10)]
	}

// ---------------------------------
// regel uitvullen tot vaste lengte:
// ---------------------------------
	function justify(x,m)
	{	var n = m - x.length		// aantal toe te voegen spaties
		var a = x.split(" ")		// splist in woorden
		var k = a.length - 1		// laatste mag geen extra spatie krijgen
		while (n >= k) {for (var i = 0; i < k; a[i] += " ", n--, i++);}		// overvloed gelijk verdelen
		for (var b = []; b.length < k; b.push(0) );	// init lijst ter voorkoming duplicaten
		for (var i = 0; i < n; i++)			// rest toevoegen
		{	do {var j = ran(k)} while (b[j])	// zoek item waar nog niet toegevoegd
			a[j] += " "				// voeg toe
			b[j]  = 1				// en verbied verdere toevoeging
		}
		return a.join(" ")
	}

// -------------------------------------------
// tekst indelen in regels van gegeven lengte:
// -------------------------------------------
	function wrap(tekst,regellengte,uitvullen)
	{	var x = (""+tekst).replace(/^\s+/,"").replace(/\s+$/,""), m = regellengte, r = "", nl = ""
		if (x == "") return x
		for (; x != ""; nl = "\n")
		{	if (x.length <= m)
			{	r += nl + x
				x = ""
			} else
			{	for (var i = m; --i >= 0 && x.charAt(i) != " "; );	// zoek laatste spatie op regel
				if (i < 0)						// geen spatie gevonden?
				{	r += nl + x.slice(0,m-1) + "-"			// dan hard afbreken
					x = x.slice(m-1)
				} else							// anders bij spatie afbreken
				{	var y = x.slice(0,i).replace(/\s+$/,"")		// geen naloopspaties
					if (uitvullen) y = justify(y,m)			// evt. uitvullen
					r += nl + y					// regel toevoegen
					x = x.slice(i).replace(/^\s+/,"")		// geen voorloopspaties in rest
				}
			}
		}
		return r
	}

// -------------------------------------
// willekeurig uitspreekbaar onzinwoord:
// -------------------------------------
	function Woord(geengetal)	// geengetal is boolean, true betekent dat GEEN getal mag worden geproduceerd
	{	var nn = ran(6), n = (nn < 3 ? 1 : nn < 5 ? 2 : 3)	// 1, 2 of 3 mklinkers, voorkeur voor korte woorden
		var kans = random()
		if (kans < (geengetal ? kans - 1 : 0.005) ) return ""+ran(10000)	// af en toe getal, max. 4 cijfers
		if (kans >= 0.90)					// af en toe alleen een dubbelklinker
		{	for (var kl = ""; kl.length != 2 || kl.charAt(0) == kl.charAt(1); kl = RAN(klinkarray)[0] );
			return kl
		}
		if (kans >= 0.60)						// af en toe mk+k of k+mk
		{	do {var mk = RAN(mklinkarray)} while (mk[1]&3 == 3);	// zoek mk die niet tussen 2 kl MOET
			if (mk[1]&4) mk[1] = 6					// mag niet voor? dan achter
			if (mk[1]&3 == 0) mk[1] = 1+ran(2)			// mag voor of achter
			if (mk[1]&1)
			{	for (var kl = ["",1]; kl[1]&1; kl = RAN(klinkarray) );	// klinker die voorop mag
				return kl[0] + mk[0]
			}
			if (mk[1]&2)						
			{	for (var kl = ["",2]; kl[1]&2; kl = RAN(klinkarray) );	// kl die achteraan mag
				return mk[0] + kl[0]
			}
		}
		for (var i = 0, j = 0, w = []; i < n; i++)
		{	var mk = RAN(mklinkarray)					// willekeurige medeklinker
			if (i == 0)							// eerste?
			{	if ( (mk[1]&1) != 0 || ( (mk[1]&4) == 0 && ran(100) < 20) )	// klinker ervoor?
				{	for (var kl = ["",1]; kl[1]&1; kl = RAN(klinkarray) );	// klinker die voorop mag
					w[j++] = kl[0]
				}
			} else							// volgende medeklinkers
			{	for (; mk[1]&4; mk = RAN(mklinkarray) );	// andere als er geen klinker voor mag
				kl = RAN(klinkarray)				// willekeurige klinker
				w[j++] = kl[0]
			}
			w[j++] = mk[0]						// plaats de medeklinker
		}
		if (j == 1 || (mk[1]&2) != 0 || ran(100) < 20)			// klinker na laatste medeklinker?
		{	for (var kl = ["",2]; kl[1]&2; kl = RAN(klinkarray) );	// zoek klinker die achteraan mag
			w[j++] = kl[0]
		}
		return w.join("")	// retourneer het geproduceerde woord
	}

// ----------------------------------------------------------------
// zin van max. L tekens, maar minimaal 1 woord ongeacht de lengte:
// ----------------------------------------------------------------
	function Zin(L)
	{	var woord = Woord(true)
		if (woord.slice(0,2) == "ij") woord = "IJ" + woord.slice(2)	// this is Dutch...
		else woord = woord.charAt(0).toUpperCase() + woord.slice(1)
		var len = woord.length, woorden = [woord]
		var gg = false
		var cont = true
		while (cont)
		{	var woord = Woord(gg)
			for (var i = 0; i < 10 && !(cont=(len+1+woord.length<L) ); woord = Woord(gg), i++);
			if (cont) {woorden.push(woord); len += 1+woord.length}
			gg = isFinite(1*woord)
		}
		var k = woorden.length - 2
		for (var i = 1; i < k; i++) {if (ran(6) == 3) {woorden[i] += ","; i++} }
		var i = ran(50)
		return woorden.join(" ") + (i == 0 ? "?" : i == 1 ? "!" : ".")
	}

// -----------------------------------------------------------------------------------------------------------------
// paragraaf van meerdere zinnen, max. L tekens, evt. opbreken in regels van max. W tekens, F = uitvullen (boolean):
// -----------------------------------------------------------------------------------------------------------------
	function Paragraaf(L,W,F,V)
	{	var tekst = Zin(Math.min(23+ran(71),L))
		var cont = true
		while (cont)
		{	var zL = Math.min (31+ran(81), L - tekst.length - 2)
			var zin = Zin(zL)
			for (var i = 0; i < 10 && !(cont=(tekst.length+zin.length+2<=L) ); zin = Zin(zL), i++);
			if (cont) tekst += "  " + zin
		}
		if	(arguments.length > 3)		tekst = VertaalGetallen(tekst,V)[0]
		if	(arguments.length > 2 && W > 0)	return wrap(tekst,W,F)
		else if	(arguments.length > 1 && W > 0)	return wrap(tekst,W)
		else					return tekst
	}

// -----------------------------------------------------------------------
// functie om lijst van cijferwoorden te maken (0 t/m 10, tig, 100, 1000):
// -----------------------------------------------------------------------
	function maakCijfers()
	{	for (cijfer = []; cijfer.length < 14; )
		{	for (var x = Woord(); x.length > 5 || x.search(/[0-9]+/) >= 0; x = Woord() );
			for (var i = 0; i < cijfer.length && x != cijfer[i]; i++);
			if (i < 11 || "aeiou".indexOf(x.charAt(0)) < 0) cijfer[i] = x
		}
	}

// ---------------------------------------------
// functie om de lijst van cijfers op te vragen:
// ---------------------------------------------
	function Cijferlijst()
	{	var lijst = ""
		for (var i = 0; i < 11; lijst += "" + i + "=" + cijfer[i++] + " ");
		return lijst + '"tig"='  + cijfer[11] + " 100=" + cijfer[12] + " 1000=" + cijfer[13]
	}

// ---------------------------------------------
// functie om een getal naar tekst om te zetten:
// ---------------------------------------------
	function Getal (getal)
	{	var N = (arguments.length > 0 ? Math.abs(Math.round(1*getal)%10000) : ran(10000) )
		if (N == 0) return cijfer[0]
		var x = (""+N).split("").reverse()
		var y = []
		for (var i = 0; i < x.length; i++)
		{	if (x[i] != "0")
			{	c = 1*x[i]
				if (c == 1)
				{	if	(i==0)	n = cijfer[1]
					else if	(i==1)	n = cijfer[10]
					else		n = cijfer[10+i]
				} else
				{	n = cijfer[c]
					if (i > 0) n += "-" + cijfer[10+i]
				}
				y.push(n)
			}
		}
		return y.reverse().join(" ")
	}

// ----------------------------------------------------------------------------------------------------
// functie om in een tekst getallen (max. 4 cijfers) te vervangen door een getaltekst;
// resultaat is array:
// r[0]    = formaat met daarin "#" vervangen door getal zelf en "$" door getalnaam, "@" door GETALNAAM
// r[1..n] = [getal,getalnaam]
// ----------------------------------------------------------------------------------------------------
	function VertaalGetallen (intext, formaat)
	{	var txt = "" + intext, fmt = (arguments.length > 1 ? formaat : "")
		if (fmt == "") fmt = "# [$]"
		function isCijfer(txt,i) {return ("0123456789".indexOf(txt.charAt(i)) >= 0) }
		for (var a = [], x = "", i = 0, j = 0; i < txt.length; i++)
		{	if (isCijfer(txt,i))
			{	x += txt.substring(j,i)
				for (j = i + 1; j < txt.length && isCijfer(txt,j); j++);
				var getal = txt.substring(i,j)
				var getalnaam = Getal(getal), GETALNAAM = getalnaam.toUpperCase()
				x += fmt.replace(/#/g,getal).replace(/\$/g,getalnaam).replace(/@/g,GETALNAAM)
				a.push([("    "+getal).slice(-4),getalnaam])
				i = j
			}
		}
		a.sort()
		var r = [x + txt.slice(j)]
		for (var i = 0; i < a.length; i++)
		{	if (i < 1 || a[i] != a[i-1]) {x = a[i]; x[0] = x[0].replace(/^\s+/,""); r.push(x)}
		}
		return r
	}

// ----------------------
// aan te roepen methods:
// ----------------------
	this.Woord		= Woord
	this.Zin		= Zin
	this.Paragraaf		= Paragraaf
	this.maakCijfers	= maakCijfers	// voor her-initialisatie van de cijferlijst
	this.Cijferlijst	= Cijferlijst
	this.Getal		= Getal
	this.VertaalGetallen	= VertaalGetallen
}

// =====================================================================================================================
// [end of file]  --  Copyright (c) 2005  http://Henk-Reints.nl

