Random Syntax Engine is a library that lets you create randomly generated strings from a corpus object. Extensible, lightweight and very powerful. https://code.patxipierce.com/rasyen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
22KB

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width" />
  7. <link rel="shortcut icon" href="http://patxipierce.com/assets/img/favicons/favicon.ico"/>
  8. <title>RaSyEn - Random Syntax Engine Tests</title>
  9. <meta name="description" content="RaSyEn is a Random Syntax Engine" />
  10. <meta name="keywords" content="random generation, random syntax engine, random phrase generator" />
  11. <style type="text/css">
  12. /* reset */
  13. html{color:#000;background:#fff}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;*font-size:100%}legend{color:#000}#yui3-css-stamp.cssreset{display:none}
  14. /* Styles */
  15. body {
  16. height: 100%;
  17. min-height: 100%;
  18. margin: 0;
  19. padding: 0;
  20. color: #ddd;
  21. font-family: Hack, "Andale Mono", "Lucida Console", Helvetica, Arial, monospace;
  22. font-size: 12px;
  23. background-color: #7d7e7d; /* Fallback */
  24. background-image: -webkit-gradient(linear, left top, left bottom, from(#7d7e7d), to(#0e0e0e));
  25. background-image: -webkit-linear-gradient(top, #7d7e7d 0%, #0e0e0e 100%);
  26. background-image: -moz-linear-gradient(top, #7d7e7d 0%, #0e0e0e 100%);
  27. background-image: -ms-linear-gradient(top, #7d7e7d 0%, #0e0e0e 100%);
  28. background-image: -o-linear-gradient(top, #7d7e7d 0%, #0e0e0e 100%);
  29. background-image: linear-gradient(to bottom, #7d7e7d 0%, #0e0e0e 100%);
  30. background-repeat: no-repeat;
  31. background-attachment: fixed;
  32. }
  33. h1, h2, h3, h4 { margin: 15px 0; }
  34. h1 { font-size: 200%; }
  35. h2 { font-size: 180%; }
  36. h2 { font-size: 160%; }
  37. h3 { font-size: 140%; }
  38. h4 { font-size: 120%; }
  39. a { color: #fff; }
  40. p { padding: 15px; }
  41. ul { padding: 15px; }
  42. header pre { font-size: 9px; }
  43. header h1 { letter-spacing: 3px; }
  44. h1 span.acronym { border-bottom: 1px solid #ddd; }
  45. footer,header { text-align: center; margin: 0 2% 0 2%; }
  46. header, section, footer { background-color: #111; padding: 2%; }
  47. section, article { margin: 2%; }
  48. section h2 { text-align: center; }
  49. footer nav ul li { display: inline; }
  50. button { padding: 15px 0; border-radius: 4px; font-size: 140%; width: 75%; background-color: #111; color: #ddd; border: 1px solid #ddd; cursor: pointer; }
  51. button:hover { background-color: #444; color: #fff; }
  52. .test-button-box { text-align: center; position: fixed; bottom: 0; left: 0; right: 0; width: 100%; background-color: #111; }
  53. #list-data ul > li { list-style-type: none; }
  54. #tests { padding: 0; margin: 0; }
  55. #tests li { list-style: none; width: 100%; margin-bottom: 45px;}
  56. #tests li div { width: 100%; }
  57. #tests h3 { width: auto; border-bottom : 1px solid #ddd; text-align: left; padding-left: 1%;}
  58. #tests .template:before,
  59. #tests .result:before { display: block; padding: 15px 0; }
  60. #tests .template:before { content: 'Template:'; }
  61. #tests .result:before { content: 'Result:'; }
  62. #tests .template input,
  63. #tests .result p { font-size: 140%; background-color: #333; color: #ddd; text-align: left; margin: 15px 0; padding: 15px; width: 90%; border: 1px solid #ddd; }
  64. /* Formatting Data Sample */
  65. ul.object,
  66. ul.array { padding: 5px 15px; }
  67. ul.array > li { display: inline; }
  68. span.object-item.string:before,
  69. li.array-item.string:before { content: ' "'; }
  70. span.object-item.string:after,
  71. span.object-item:after,
  72. li.array-item:after { content: ', '; }
  73. span.object-item:after,
  74. li.array-item.string:after { content: '", '; }
  75. span.object-item:last-of-type:after,
  76. li.array-item:last-of-type:after { content: ' '; }
  77. span.object-item.string:last-of-type:after,
  78. li.array-item.string:last-of-type:after { content: '" '; }
  79. span.object-key { margin: 5px; display: block; }
  80. span.object-key:before { content: '@' }
  81. span.object-key:after { content: ' : ' }
  82. ul.array:before { content: '['; }
  83. ul.array:after { content: '],'; }
  84. ul.object:before { content: "{\A"; }
  85. ul.object:after { content: '},'; }
  86. ul.first > li > span.object-key:before { content: '%' }
  87. ul.first > li > span.object-key:after { content: '%'; }
  88. ul.first.object:before { content: ''; }
  89. ul.first.object:after { content: ''; }
  90. footer nav ul li { list-style: none; text-align: right; padding: 15px; }
  91. </style>
  92. </head>
  93. <body>
  94. <header>
  95. <pre>__________ _________ ___________
  96. \______ \_____ / _____/__.__.\_ _____/ ____
  97. | _/\__ \ \_____ < | | | __)_ / \
  98. | | \ / __ \_/ \___ | | \ | \
  99. |____|_ /(____ /_______ / ____|/_______ /___| /
  100. \/ \/ \/\/ \/ \/ </pre>
  101. <h1><span class="acronym">Ra</span>ndom <span class="acronym">Sy</span>ntax <span class="acronym">En</span>gine</h1>
  102. </header>
  103. <section>
  104. <h2>Tests and demonstrations - <span id="rasyen-version"></span></h2>
  105. <p>This document is intended for testing the functionality of RaSyEn as well as demonstrating its usage.</p>
  106. <article id="list-data">
  107. <h3>List data in use:</h3>
  108. <p>These are the lists used in all the tests below.</p>
  109. <div id="lists"></div>
  110. </article>
  111. <article>
  112. <h3>The tests:</h3>
  113. <p class="test-button-box"><button onclick="test_all();">Test Again...</button></p>
  114. <!-- The templates are in the values of the inputs of the list below -->
  115. <ul id="tests">
  116. <li>
  117. <h3>Callback test:</h3>
  118. <p>Every time a callback is called we add to the total count of templates, tags, lists and filters called.</p>
  119. <div class="result"><p>Templates: <span id="count-templates">0</span>, Tags: <span id="count-tags">0</span>, Lists: <span id="count-lists">0</span>, Filters: <span id="count-filters">0</span>.</p></div>
  120. </li>
  121. </ul>
  122. </article>
  123. </section>
  124. <footer>
  125. <nav>
  126. <ul>
  127. <li><a href="http://patxipierce.com">Patxi Pierce</a></li>
  128. <li><a href="https://github.com/patxipierce/rasyen">Fork RaSyEn on Github.</a></li>
  129. </ul>
  130. </footer>
  131. <!-- Core RaSyEn library -->
  132. <script src="rasyen.js"></script>
  133. <!-- Load the language filters we will use -->
  134. <script src="filters/en_US-filters.js"></script>
  135. <script>
  136. /*
  137. * Load Test Data
  138. */
  139. // Loads version
  140. function load_version(){
  141. document.getElementById('rasyen-version').innerHTML = 'version '+Rasyen.version;
  142. }
  143. // Load test lists
  144. function load_lists(){
  145. // Loads a JSON object with keys as list names.
  146. Rasyen.lists_load({
  147. // A list called %number%
  148. "number": [
  149. "one",
  150. "two",
  151. "three"
  152. ],
  153. // A list called %digit%
  154. "digit": [
  155. "1",
  156. "2",
  157. "3"
  158. ],
  159. // For category tests
  160. "geography": {
  161. "water": [
  162. "gulf",
  163. "lake",
  164. "river",
  165. "sea",
  166. "ocean"
  167. ],
  168. "land": [
  169. "cliff",
  170. "desert",
  171. "canyon",
  172. "mountain"
  173. ]
  174. },
  175. // For filter parameter test
  176. "kung-fu": [
  177. "blind mantis fist",
  178. "drunken master style",
  179. "angry tiger style",
  180. "spinning ostrich kick"
  181. ],
  182. // For automatic filter example
  183. "color": [
  184. [
  185. "red",
  186. "#c00"
  187. ],
  188. [
  189. "green",
  190. "#0c0"
  191. ],
  192. [
  193. "blue",
  194. "#00c"
  195. ]
  196. ],
  197. // For meta filter example
  198. "animal": [
  199. "%color% dog and %animal=a-or-an%",
  200. "%color% cat",
  201. "goat from the %geography@land%",
  202. "goldfish from the %geography@water%"
  203. ],
  204. // Pronoun tests
  205. "pronoun": ["he","she","they","fae","ae","ey","per","ve","xe","ze"],
  206. "person" : ["Sam","Ryan","Peach"],
  207. "opinion" : [
  208. "It's His; they said.",
  209. "The pronoun card is theirs.",
  210. "His favourite color is unknown.",
  211. "They tried to convince HER that asexuality does not exist.",
  212. "He laughed at the notion of gender binary."
  213. ],
  214. // Irregular / Regular nouns
  215. "nouns" : {
  216. "irregular" : ["ox","tomato","tooth","sky","day","monkey"],
  217. "regular" : ["beach","banana","bat"]
  218. }
  219. });
  220. }
  221. // Template examples
  222. function load_tempates(){
  223. return {
  224. "simple-test" : {
  225. name : "Simple test",
  226. description : "Get a random number and a random digit.",
  227. template : "%number% %digit%"
  228. },
  229. "category-test" : {
  230. name : "Category test",
  231. description : "Search for a specific property of a sub-divided list and return a value from it.",
  232. template : "%geography@water% %geography@land%"
  233. },
  234. "concatenation-test" : {
  235. name : "Concatenation test",
  236. description : "Join two lists or more and return one of the pooled results.",
  237. template : "%number|digit|person% %geography@water|geography@land%"
  238. },
  239. "filter-test" : {
  240. name : "Upper and Lower Case Filter test",
  241. description : "Apply some basic modifications to the template results.",
  242. template : "%geography=to-upper=first-to-lower% %geography=to-lower=first-to-upper%"
  243. },
  244. "filter-param-test" : {
  245. name : "Filter per Words test",
  246. description : "The words filter applied one or more filter for every word in the template.",
  247. template : "%kung-fu=words=first-to-upper%"
  248. },
  249. "auto-filter-test" : {
  250. name : "Automatic Filter test",
  251. description : "A custom filter named \"color\" has been defined to be called every time the color list is used.",
  252. template : "%color%"
  253. },
  254. "filter-save-test" : {
  255. name : "Filter save-result, random-category and category test",
  256. description : "Saves a category name to a list called 'saved-key' and the uses it to retrieve a result",
  257. template : "%geography=random-category=save-result=saved-key% %geography=category=saved-key%"
  258. },
  259. "mixed-save-filter-test" : {
  260. name : "Save-result with several mixed lists",
  261. description : "Mix two lists and expect the result of both to be the same.",
  262. template : "%geography|digit|number|=save-result=number-or-digit% == %number-or-digit%"
  263. },
  264. "filter-alone-test" : {
  265. name : "Filter alone test",
  266. description : "Sans-list filter, and a way to include percent signs in templates.",
  267. template : "%=range=2-24% &#37;"
  268. },
  269. "filter-remove-result" : {
  270. name : "Remove result filter test",
  271. description : "Results cannot be the same, because they have been removed from the list when used.",
  272. template : "%number=remove-result% =/= %number=remove-result% =/= %number=remove-result%"
  273. },
  274. "tag-meta-test" : {
  275. name : "Tag meta filter test",
  276. description : "Get a result from the animal list, and parse it again, and again until no tags are found, then add 'a' or 'an' (from en_US-filters) before the result.",
  277. template : "Its %animal=meta=a-or-an%"
  278. },
  279. "filter-inline-test" : {
  280. name : "In-line filter test",
  281. description : "A filter that requires no list but can save a list.",
  282. template : "%[\"Hello\",\"Hey\",\"Greetings\"]=inline=inline-list%, said Arthur. %inline-list%, replied Guinevere."
  283. },
  284. "filter-plural-singular-test" : {
  285. name : "Plural to singular test (en_US-filters)",
  286. description : "A very simple (and not very thorough) function convert from singular to plural and back.",
  287. template : "%nouns=to-plural=save-result=plu% %plu=to-singular%"
  288. },
  289. "filter-pronoun-swap-test" : {
  290. name : "Pronoun swap test (en_US-filters)",
  291. description : "Searches for the first pronoun in a phrase and changes to a designated pronoun in an entire phrase.",
  292. template : "\"%opinion=save-result=op%\" + \"%pronoun|person|=save-result=pn%\" = \"%op=pronoun-swap=pn%\""
  293. },
  294. "filter-number-to-words-test" : {
  295. name : "Number to Words test (en_US-filters)",
  296. description : "Converts digits (up to 10^303) to their word equivalent.",
  297. template : "%=range=100-10000=save-result=n% = %n=number-to-words%"
  298. },
  299. "filter-quiet-test" : {
  300. name : "Test the quiet filer",
  301. description : "Will output nothing but still parse any filters before the quiet filter was called.",
  302. template : "%geography=save-result=n=quiet% %n%"
  303. }
  304. };
  305. }
  306. /*
  307. * Load behaviour
  308. */
  309. // Create the elements for testing
  310. function create_template_html(templates){
  311. var ul = document.getElementById('tests');
  312. for(var tpl in templates){
  313. if(!templates.hasOwnProperty(tpl)) continue;
  314. var li = document.createElement('li');
  315. li.id = tpl;
  316. // Title h3
  317. var h3 = document.createElement('h3');
  318. h3.innerHTML = templates[tpl].name;
  319. li.appendChild(h3);
  320. // description p
  321. var p = document.createElement('p');
  322. p.innerHTML = templates[tpl].description;
  323. li.appendChild(p);
  324. // Template div
  325. var div_template = document.createElement('div');
  326. div_template.className = 'template';
  327. var input = document.createElement('input');
  328. input.type = 'text';
  329. input.id = tpl+'-tpl';
  330. input.value = templates[tpl].template;
  331. div_template.appendChild(input);
  332. li.appendChild(div_template);
  333. // Result div
  334. var div_result = document.createElement('div');
  335. div_result.className = 'result';
  336. var out = document.createElement('p');
  337. out.id = tpl+'-out';
  338. div_result.appendChild(out);
  339. li.appendChild(div_result);
  340. // Finally
  341. ul.appendChild(li);
  342. }
  343. }
  344. /*
  345. * Filter examples
  346. */
  347. function load_filters(){
  348. // Load custom filters
  349. // The filter "color" is called the same name as the "color" list,
  350. // so it will be applied automatically when the %color% tag is called.
  351. Rasyen.filters['color'] = function(list){
  352. if(typeof Rasyen.lists['color'] !== 'undefined'){
  353. var color_list = Rasyen.list_get('color');
  354. var col = Rasyen.rai(color_list);
  355. list.replace = '<span style="color:'+col[1]+';">'+col[0]+'</span>';
  356. }
  357. return list;
  358. }
  359. }
  360. /*
  361. * Callback examples
  362. */
  363. function load_callbacks(){
  364. // Will run once for every template
  365. Rasyen.callback.parse_template = function(parsed){
  366. var tpl_count = document.getElementById('count-templates');
  367. tpl_count.innerHTML = Number(tpl_count.innerHTML) + 1;
  368. return parsed;
  369. };
  370. // Will run on every tag in a template
  371. Rasyen.callback.parse_tag = function(tag_obj){
  372. var tag_count = document.getElementById('count-tags');
  373. tag_count.innerHTML = Number(tag_count.innerHTML) + 1;
  374. return tag_obj;
  375. };
  376. // Will run on every list in a tag
  377. Rasyen.callback.parse_list = function(list_obj){
  378. var tag_count = document.getElementById('count-lists');
  379. tag_count.innerHTML = Number(tag_count.innerHTML) + 1;
  380. return list_obj;
  381. };
  382. // Will run on every filter
  383. Rasyen.callback.parse_filters = function(list_obj){
  384. var tag_count = document.getElementById('count-filters');
  385. tag_count.innerHTML = Number(tag_count.innerHTML) + 1;
  386. return list_obj;
  387. };
  388. }
  389. // Parse the content of the text inputs
  390. function test_all(){
  391. var tpls = load_tempates();
  392. for(var tpl in tpls){
  393. if(!tpls.hasOwnProperty(tpl)) continue;
  394. document.getElementById(tpl+'-out').innerHTML = Rasyen.parse(document.getElementById(tpl+'-tpl').value);
  395. }
  396. }
  397. /*
  398. * Start tests
  399. */
  400. function rasyen_tests_init(){
  401. // Start with loading version
  402. load_version();
  403. // Load templates
  404. var tpls = load_tempates();
  405. create_template_html(tpls);
  406. // Load data
  407. load_lists();
  408. // Load custom data filters
  409. load_filters();
  410. // Load callbacks
  411. load_callbacks();
  412. // Start
  413. show_lists();
  414. test_all();
  415. }
  416. // Go!
  417. window.onload = rasyen_tests_init;
  418. /*
  419. *
  420. * Non essential demo code
  421. *
  422. */
  423. // Print JSON as an HTML <ul> list
  424. function show_lists(){
  425. // Recursively creates an unordered list
  426. function json_to_ul(obj, parent) {
  427. // Create the list element
  428. if(typeof parent == 'undefined'){
  429. parent = document.createElement('ul');
  430. if(obj instanceof Array){
  431. parent.className = 'array first';
  432. }else if(obj instanceof Object){
  433. parent.className = 'object first';
  434. }
  435. }
  436. if(obj instanceof Array){
  437. for(var i = 0; i < obj.length; i++) {
  438. var new_li = document.createElement('li');
  439. if(obj[i] instanceof Array){
  440. var new_ul = document.createElement('ul');
  441. new_ul.className = 'array';
  442. new_li.appendChild(json_to_ul(obj[i], new_ul));
  443. parent.appendChild(new_li);
  444. }else if(obj[i] instanceof Object){
  445. var new_ul = document.createElement('ul');
  446. new_ul.className = 'object';
  447. new_li.appendChild(json_to_ul(obj[i], new_ul));
  448. parent.appendChild(new_li);
  449. }else{
  450. new_li.className = 'array-item ' + (typeof obj[i]);
  451. parent.appendChild(json_to_ul(obj[i], new_li));
  452. }
  453. };
  454. }else if(obj instanceof Object){
  455. for(var key in obj){
  456. if(!obj.hasOwnProperty(key)) continue;
  457. if(obj[key] instanceof Array){
  458. var new_ul = document.createElement('ul');
  459. new_ul.className = 'array';
  460. }else if(obj[key] instanceof Object){
  461. var new_ul = document.createElement('ul');
  462. new_ul.className = 'object';
  463. }else{
  464. var new_ul = document.createElement('span');
  465. new_ul.className = 'object-item ' + (typeof obj[key]);
  466. }
  467. var new_li = document.createElement('li');
  468. new_li.className = 'object-pair';
  469. var new_span = document.createElement('span');
  470. new_span.className = 'object-key';
  471. new_span.appendChild(document.createTextNode( key ));
  472. new_li.appendChild(new_span);
  473. new_li.appendChild( json_to_ul(obj[key], new_ul) );
  474. parent.appendChild(new_li);
  475. }
  476. }else{
  477. var new_span = document.createElement('span');
  478. new_span.className = (typeof obj)+'';
  479. // does not check for other wonderful js types
  480. parent.appendChild(
  481. new_span.appendChild(document.createTextNode(obj))
  482. );
  483. }
  484. return parent;
  485. }
  486. var lists = json_to_ul(Rasyen.lists);
  487. document.getElementById('lists').appendChild(lists);
  488. }
  489. </script>
  490. </body>
  491. </html>