Twee to Gemini Converter

Converts Twine's Twee markup to a series of navigable Gemini files so you can put your choose-your-own adventure games in Gemini space. Works best with simple games without macros, styling, scripting, or variables (basically, ones that function by using links only).

Info about Twee

Copy this code to a file called gemitwee.php. Used like `php gemitwee.php twee_file.twee output_dir`

❤️ Like this post
💬 Add a comment
 $line) {
  $results[$i] = array();
  preg_match('/:: (.+)\s?[\[{<]/', $line, $results[$i]['header']);
  if (count($results[$i]['header']) > 0) {
    // this is a section header
    print_r('Header: '.$currentheader."\n");
    if ($currentheader != "" && (!preg_match('/\[stylesheet\]/', $line, $results[$i]['stylesheet']) || !preg_match('/\[script\]/', $line, $results[$i]['script']))) {
      // skip and dump buffer if this is a stylesheet or script block
      // then write the content
      $sections[$currentheader] = $buffer;
      if ($endbuffer != "") {
        $sections[$currentheader] .= "\n".$endbuffer;
      }
    }
    // reset variables
    $footnotecounter = 1;
    $endbuffer = "";
    $buffer = "";
    $currentheader = trim($results[$i]['header'][1]);
    if (preg_match('/\[Start\]/', $currentheader, $isstart) == 1) {
      // if this is the start block, remember that
      $start = trim($currentheader);
    }
    $sections[$currentheader] = "";
  } else {
    // add line to buffer
    preg_match('/^\[\[(.+)->(.+)\]\]$/', $line, $results[$i]['standalone']);
    if (count($results[$i]['standalone']) > 0) {
    // this is a link on its own line
      $line = "=> !!".$results[$i]['standalone'][2]."!! ".$results[$i]['standalone'][1]."\n";
    }
    preg_match('/^\[\[(.+)\]\]$/', $line, $results[$i]['standalone_noarrow']);
    if (count($results[$i]['standalone_noarrow']) > 0) {
      // this is a link on its own line
      $line = "=> !!".$results[$i]['standalone_noarrow'][1]."!! ".$results[$i]['standalone_noarrow'][1]."\n";
    }
    $c = preg_match_all('/\[\[([\w\d\s,\.:!\"?+-]+)->([\w\d\s,\.:!\"?+-]+)\]\]/', $line, $results[$i]['inline_arrow']);
    if ($c > 0) {
      // this is a link in the middle of a line. we'll add a footnote
      for ($j = 0; $j < count($results[$i]['inline_arrow'][0]); $j++) {
        $linktext = $results[$i]['inline_arrow'][1][$j];
        $line = str_replace($results[$i]['inline_arrow'][0][$j], "$linktext"."[$footnotecounter]", $line);
        $endbuffer .= "=> !!".$results[$i]['inline_arrow'][2][$j]."!! [$footnotecounter] ".$results[$i]['inline_arrow'][1][$j]."\n";
        $footnotecounter++;
      }
    }
    $c = preg_match_all('/\[\[([\w\d\s,\.:!\"?+-]+)\]\]/', $line, $results[$i]['inline_noarrow']);
    if ($c > 0) {
      // this is a link in the middle of a line. we'll add a footnote
      for ($k = 0; $k < count($results[$i]['inline_noarrow'][0]); $k++) {
        $linktext = $results[$i]['inline_noarrow'][1][$k];
        $line = str_replace($results[$i]['inline_noarrow'][0][$k], "$linktext"."[$footnotecounter]", $line);
        $endbuffer .= "=> !!".$results[$i]['inline_noarrow'][1][$k]."!! [$footnotecounter] ".$results[$i]['inline_noarrow'][1][$k]."\n";
        $footnotecounter++;
      }
    }

    $buffer .= $line."\n";
  }
}


$sections[$currentheader] = $buffer;
if ($endbuffer != "") {
  $sections[$currentheader] .= "\n".$endbuffer;
}

$uuids = array();
foreach (array_keys($sections) as $key) {
  if ($key == $start) {
    $uuids[$key] = "index";
  } else {
    $uuids[$key] = uniqid("", true);
  }
}

foreach($sections as $key=>$section) {
  $c = preg_match_all('/!!([\w\s\d\.,:;"-+=]+)!!/', $section, $output_array);
  if ($c > 0) {
    for ($l = 0; $l < count($output_array[0]); $l++) {
      $search = $output_array[0][$l];
      $section = str_replace($search, $uuids[$output_array[1][$l]].".gmi", $section);
    }
  }
  file_put_contents(dirname(__FILE__)."/".$argv[2]."/".$uuids[$key].".gmi", $section);
}
echo "\nTwee > Gemini conversion complete.";
Main