code: function(str, options = {}) {
      var comment, current, data, lines, stack;
      lines = string.lines(str);
      current = data = {};
      stack = [current];
      comment = options.comment || ';';
      lines.forEach(function(line, _, __) {
        var depth, match, parent;
        if (!line || line.match(/^\s*$/)) {
          return;
        }
        // Category
        if (match = line.match(/^\s*(\[+)(.+?)(\]+)\s*$/)) {
          depth = match[1].length;
          // Add a child
          if (depth === stack.length) {
            parent = stack[depth - 1];
            parent[match[2]] = current = {};
            stack.push(current);
          }
          // Invalid child hierarchy
          if (depth > stack.length) {
            throw Error(`Invalid child ${match[2]}`);
          }
          // Move up or at the same level
          if (depth < stack.length) {
            stack.splice(depth, stack.length - depth);
            parent = stack[depth - 1];
            parent[match[2]] = current = {};
            return stack.push(current);
          }
        // comment
        } else if (comment && (match = line.match(RegExp(`^\\s*(${comment}.*)$`)))) {
          return current[match[1]] = null;
        // key value
        } else if (match = line.match(/^\s*(.+?)\s*=\s*(.+)\s*$/)) {
          return current[match[1]] = match[2];
        // else
        } else if (match = line.match(/^\s*(.+?)\s*$/)) {
          return current[match[1]] = null;
        }
      });
      return data;
    }
docs: /*
  
  Each category is surrounded by one or several square brackets. The number of brackets indicates
  the depth of the category.
  Options are
  
  `comment`   Default to ";"