JSFiddle - React, Tailwind, and code Playground

by danneu

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.min.js"></script>
<div id="output"></div>
<button type="button">Generate Character</button>

CSS

#output {
    font-family: Georgia;
    margin-bottom: 20px;
    height: 50px;
    padding: 10px;
}
body {
    text-align: center;
    padding-top: 20px;
}

JavaScript

var seeds = {
  CHARACTER_ADJECTIVE: [
    'creepy',
    'untrusting'
  ],
  POSITIVE_ADJECTIVE: [
    'mighty',
    'girthy',
    'nimble',
    'heroic'
  ],
  NEGATIVE_ADJECTIVE: [
    'frail',
    'failing'
  ],
  BODYPART: [
    'torso',
    'feet',
    'hands',
    'lungs'
  ],
  ARCHETYPE: [
    'hobbit',
    'half-reptile, half-amphibian human'
  ],
  STRENGTH: [
    'isn\'t afraid of anything',
    'has <POSITIVE_ADJECTIVE> <BODYPART>'
  ],
  QUIRK: [
    'hates humans',
    'can\'t step on lava',
    'is obsessed with power',
    'drones on and on and on and on',
    'has sausage fingers'
  ]
};

function randNth(things) {
  return _.shuffle(things)[0];
}

// String -> Boolean
function isTemplate(str) {
  return /(?:<[^>]+>)/.test(str);
}

// Recursively processes a template, replacing all <...>
function processTemplate(template) {
  return template.replace(
    /(?:<([^>]+)>)/g,
    function(matchedSubstring, p1, offset, totalString) {
      var seed = randNth(seeds[p1]);
      if (isTemplate(seed))
        return processTemplate(seed);
      else
        return seed;
    });
}

var CHARACTER_TEMPLATE = 'This <CHARACTER_ADJECTIVE> <ARCHETYPE> <STRENGTH>, but <QUIRK>.';

// -> String
function generateCharacter() {
  return processTemplate(CHARACTER_TEMPLATE);
}

$('button').on('click', function() {
  $('#output').text(generateCharacter());
});

$('#output').text(generateCharacter());