-- Leo's gemini proxy

-- Connecting to tilde.pink:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini;

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


<?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

-- Response ended

-- Page fetched on Sun May 19 18:18:06 2024