💾 Archived View for tilde.pink › ~smallbird › tweetogemini.gmi captured on 2024-03-21 at 16:16:01. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2024-05-10)

-=-=-=-=-=-=-

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`

<?php
// converts twee markup to gemini files
// note: does not consider markup, formatting, etc. most gemini clients will not parse
// markdown and instead leave it verbatim. this works best with games that use no logic
// and don't rely on styling, macros, or additional scripting to work.

if ($argc < 2) {
  echo "Error: No twee file provided in arguments";
  die(1);
}

if ($argv[1] == "--help") {
  echo "SYNTAX: php gemitwee.php twee_file_name.twee [output_directory]\n";
  die(1);
}

$gamefile = explode("\n", file_get_contents($argv[1]));
if (!$gamefile) {
  echo 'Error: File not read. Check permissions and file format';
  die(1);
}
$buffer = "";
$sections = array();
$currentheader = "";
$endbuffer = "";
$results = array();
$footnotecounter = 1;
$start;
foreach ($gamefile as $i => $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