minecraft-format-codes.phps

<?php

// Copyright (c) 2013 Scott Zeid.  Released under the X11 License.

function minecraft_format_to_html($s = "", $reset_css = true, $default_color = null,
                                  $shadow = false) {
 $COLOR_VALUES = [
  0x0 => "000000", 0x1 => "0000aa", 0x2 => "00aa00", 0x3 => "00aaaa",
  0x4 => "aa0000", 0x5 => "aa00aa", 0x6 => "ffaa00", 0x7 => "aaaaaa",
  0x8 => "555555", 0x9 => "5555ff", 0xa => "55ff55", 0xb => "55ffff",
  0xc => "ff5555", 0xd => "ff55ff", 0xe => "ffff55", 0xf => "ffffff"
 ];
 $SHADOW_VALUES = [
  0x0 => "000000", 0x1 => "00002a", 0x2 => "002a00", 0x3 => "002a2a",
  0x4 => "2a0000", 0x5 => "2a002a", 0x6 => "2a2a00", 0x7 => "2a2a2a",
  0x8 => "151515", 0x9 => "15153f", 0xa => "153f15", 0xb => "153f3f",
  0xc => "3f1515", 0xd => "3f153f", 0xe => "3f3f15", 0xf => "3f3f3f"
 ];
 $DEFAULT_COLOR = -1;
 
 # parse $default_color argument
 if ((is_int($default_color) || is_float($default_color)) && $default_color != -1) {
  $default_color_code = $default_color;
  $default_color = $COLOR_VALUES[$default_color];
  $COLOR_VALUES[$DEFAULT_COLOR] = $default_color;
  $SHADOW_VALUES[$DEFAULT_COLOR] = $SHADOW_VALUES[$default_color_code];
 } else {
  if (empty($default_color) || $default_color == -1) $default_color = "000000";
  if (is_string($default_color))
   $default_color = preg_replace("/(^#|;$)/", "", $default_color);
 
  $COLOR_VALUES[$DEFAULT_COLOR] = $default_color;
  $SHADOW_VALUES[$DEFAULT_COLOR] = $SHADOW_VALUES[0];
 }
 
 $r = "";
 $COLOR_TAG = 0;
 $MAGIC_TAG = 1;
 $BOLD_TAG = 2;
 $STRIKE_TAG = 3;
 $UNDERLINE_TAG = 4;
 $ITALIC_TAG = 5;
 $color = $DEFAULT_COLOR;
 $current_tags = [];
 $reading_format = false;
 
 # wrap output with a span tag containing default styles if $reset_css is true
 if ($reset_css) {
  $shadow_prop = ($shadow) ? " text-shadow: 1px 1px #{$SHADOW_VALUES[$DEFAULT_COLOR]};":"";
  $r .= "<span style=\"color: #{$COLOR_VALUES[$DEFAULT_COLOR]};$shadow_prop";
  $r .= " font-weight: normal; font-style: normal; text-decoration: none;\">";
 }
 
 $len = mb_strlen($s, "utf-8");
 for ($i = 0; $i <= $len; $i++) {
  if ($i == $len) {
   # invoke tag closing if at end of string
   $reading_format = true;
   $c = "r";
  } else
   $c = mb_substr($s, $i, 1, "utf-8");
  
  if (!$reading_format) {
   if ($c === "§" || $c === "&") {
    if ($i+1 < $len && preg_match("/^[0-9a-fkl-or]$/i", mb_substr($s, $i+1, 1, "utf-8"))) {
     $reading_format = true;
     continue;
    } else if ($c === "§")
     continue;
   }
   $r .= $c;
  } else {
   $c = strtolower($c);
   if ($c === "r" || preg_match("/^[0-9a-f]$/s", $c)) {
    # close all tags if the current format is RESET or a color
    $color = $DEFAULT_COLOR;
    for ($j = count($current_tags) - 1; $j >= 0; $j--) {
     switch ($current_tags[$j]) {
      case $COLOR_TAG:
      case $MAGIC_TAG:
      case $STRIKE_TAG:
       $r .= "</span>"; break;
      case $BOLD_TAG:
       $r .= "</b>"; break;
      case $UNDERLINE_TAG:
       $r .= "</u>"; break;
      case $ITALIC_TAG:
       $r .= "</i>"; break;
     }
    }
    $current_tags = [];
   }
   if (preg_match("/^[0-9a-f]$/s", $c)) {
    $color = (int) base_convert($c, 16, 10);
    $shadow_prop = ($shadow) ? " text-shadow: 1px 1px #{$SHADOW_VALUES[$color]};" : "";
    $r .= "<span style=\"color: #{$COLOR_VALUES[$color]};$shadow_prop\">";
    $current_tags[] = $COLOR_TAG;
   } else if ($c === "k" && !in_array($MAGIC_TAG, $current_tags)) {
    $shadow_prop = ($shadow) ? " text-shadow: 1px 1px #{$SHADOW_VALUES[$color]};" : "";
    $r .= "<span style=\"background: #{$COLOR_VALUES[$color]}; color: #{$COLOR_VALUES[$color]};$shadow_prop\">";
    $current_tags[] = $MAGIC_TAG;
   } else if ($c === "l" && !in_array($BOLD_TAG, $current_tags)) {
    $r .= "<b>";
    $current_tags[] = $BOLD_TAG;
   } else if ($c === "m" && !in_array($STRIKE_TAG, $current_tags)) {
    $r .= "<span style=\"text-decoration: line-through;\">";
    $current_tags[] = $STRIKE_TAG;
   } else if ($c === "n" && !in_array($UNDERLINE_TAG, $current_tags)) {
    $r .= "<u>";
    $current_tags[] = $UNDERLINE_TAG;
   } else if ($c === "o" && !in_array($ITALIC_TAG, $current_tags)) {
    $r .= "<i>";
    $current_tags[] = $ITALIC_TAG;
   }
   $reading_format = false;
  }
 }
 
 # close outer span tag
 if ($reset_css)
  $r .= "</span>";
 
 return $r;
}

function test_minecraft_format_to_html($s, $reset_css = true, $default_color = "000000",
                                       $shadow = false) {
 echo $s."\n";
 for ($i = 0; $i < ((mb_strlen($s, "utf-8") !== 0) ? mb_strlen($s, "utf-8") : 4); $i++) {
  echo "-";
 }
 echo "\n";
 
 echo minecraft_format_to_html($s, $reset_css, $default_color, $shadow)."\n\n";
}

if (isset($_SERVER["argc"])) {
 test_minecraft_format_to_html('');
 test_minecraft_format_to_html('hi');
 test_minecraft_format_to_html('§4hi');
 test_minecraft_format_to_html('§kbnay');
 test_minecraft_format_to_html('§lhello');
 test_minecraft_format_to_html('§mtesting');
 test_minecraft_format_to_html('§nminceraft');
 test_minecraft_format_to_html('§ocontainers');
 test_minecraft_format_to_html('§n1 §m2 §k3 §o4 §l5 §r6');
 test_minecraft_format_to_html('§N1 §M2 §K3 §64 §O5 §L6 §R7', true, "123456");
 test_minecraft_format_to_html('&4Hello&r & welcome!');
 test_minecraft_format_to_html('Bare section signs§ §should be removed from the output string.');
 test_minecraft_format_to_html('No reset CSS for me! :D', false);
 test_minecraft_format_to_html('Extra characters in $default_color', true, "#123456;");
 test_minecraft_format_to_html('$default_color set to a color code', true, 0x4);
 test_minecraft_format_to_html('$default_color set to -1', true, -1);
 test_minecraft_format_to_html('Shadows! §4Y§2a§1y§6!', true, null, true);
 test_minecraft_format_to_html('§k§k §r§l§lRepeated §m§mformat §n§ncodes §o§oshould §lbe §ncollapsed!  §4§4(Except for color codes.)§r§r');
}

?>