Files
MagicSetEditor2/tools/website/drupal/mse-drupal-modules/highlight.inc
T
2025-05-22 12:39:09 +02:00

245 lines
8.3 KiB
PHP

<?php
// Syntax highlighting of script and reader code
global $built_in_functions;
$built_in_functions = array(
// conversion
'to_string' =>'',
'to_int' =>'',
'to_real' =>'',
'to_number' =>'',
'to_boolean' =>'',
'to_color' =>'',
'to_image' =>'',
'to_date' =>'',
// numbers
'abs' =>'',
'random_int' =>'',
'random_real' =>'',
'random_boolean' =>'',
// text
'to_upper' =>'',
'to_lower' =>'',
'to_title' =>'',
'reverse' =>'',
'substring' =>'',
'format' =>'', 'format_rule' =>'format',
'curly_quotes' =>'',
'replace' =>'', 'replace_rule' => 'replace',
'filter_text' =>'', 'filter_rule' => 'filter_text',
'break_text' =>'', 'break_rule' => 'break_text',
'split_text' =>'',
'sort_text' =>'', 'sort_rule' => 'sort_text',
'contains' =>'',
'match' =>'', 'match_rule' => 'match',
'trim' =>'',
'regex_escape' =>'',
'check_spelling' =>'',
// tags
'tag_contents' =>'', 'tag_contents_rule'=>'tag_contents',
'remove_tag' =>'', 'tag_remove_rule' =>'remove_tag',
'remove_tags' =>'',
// lists
'postion' =>'',
'length' =>'',
'number_of_items' =>'',
'sort_list' =>'',
'filter_list' =>'',
'random_shuffle' =>'',
'random_select' =>'',
'random_select_many' =>'',
'get_card_styling' =>'',
'get_card_stylesheet' =>'',
// keywords
'expand_keywords' =>'', 'expand_keywords_rule'=>'expand_keywords',
'keyword_usage' =>'',
// english
'english_number' =>'',
'english_number_a' =>'english_number',
'english_number_multiple'=>'english_number',
'english_number_ordinal' =>'english_number',
'english_plural' =>'',
'english_singular' =>'english_plural',
'process_english_hints' =>'',
// fields and values
'forward_editor' =>'combined_editor',
'combined_editor' =>'',
'primary_choice' =>'',
'chosen' =>'',
'count_chosen' =>'',
'require_choice' =>'',
'exclusive_choice' =>'',
'require_exclusive_choice'=>'',
'remove_choice' =>'',
// images
'linear_blend' =>'',
'masked_blend' =>'',
'combine_blend' =>'',
'set_mask' =>'',
'set_alpha' =>'',
'set_combine' =>'',
'saturate' =>'',
'invert_image' =>'',
'recolor_image' =>'',
'resize_image' =>'',
'enlarge' =>'',
'crop' =>'',
'flip_horizontal' =>'',
'flip_vertical' =>'',
'rotate' =>'',
'drop_shadow' =>'',
'symbol_variation' =>'',
'import_image' =>'',
'built_in_image' =>'',
// cards
'new_card' =>'',
// html export
'to_html' =>'',
'symbols_to_html' =>'',
'to_text' =>'',
'copy_file' =>'',
'write_text_file' =>'',
'write_image_file' =>'',
'write_set_file' =>'',
// other
'get_mse_version' =>'',
'get_mse_path' =>'',
'trace' =>'',
'assert' =>'',
'exists_in_package' =>'',
);
function syntax_highlight($code) {
if (preg_match("@^(\s*#.*\n)*\s*[-a-zA-Z0-9 _/,]+:([^=]|$)@", $code)) {
return highlight_reader($code);
} else if (preg_match("@^&lt;[^&>]*?(&gt;|>)$@", $code)) {
return "<span class='hl-tag'>$code</span>";
} else {
return highlight_script($code);
}
}
function highlight_reader($code) {
$ret = '';
$lines = explode("\n",$code);
$in_script = false;
for ($i = 0 ; $i < count($lines) ; ++$i) {
if ($i > 0) $ret .= "\n";
preg_match("@^(\s*)(.*)@",$lines[$i],$matches);
$indent = $matches[1];
$ret .= $indent;
$rest = $matches[2];
if ($in_script !== false) {
if (strlen($indent) <= strlen($in_script)) $in_script = false;
}
if ($in_script !== false) {
$ret .= highlight_script($rest);
} else {
if (preg_match("@^#@",$rest,$matches)) {
$ret .= "<span class='hl-comment'>$rest</span>";
} else if (preg_match("@^([a-zA-Z0-9 _/,]+):(.*)@",$rest,$matches)) {
$key = $matches[1];
$value = $matches[2];
if (preg_match("@script|default@", $key)) $in_script = $indent;
if (strpos($value,"{")!==false) $in_script = $indent;
if ($in_script !== false) {
$value = highlight_script($value);
} else if (preg_match("@^(\s*)script:(.*)@",$value,$matches)) {
$value = $matches[1] . "<span class='hl-key'>script:</span>" . highlight_script($matches[2]);
//} else if (preg_match("@\\s*rgb\\([0-9]+,[0-9]+,[0-9]+\\)\\s*@",$value,$matches)) {
// $value = highlight_script($value);
}
$ret .= "<span class='hl-key'>$key:</span>$value";
} else {
// not valid reader code
if (strpos($rest,"{")!==false) $in_script = substr($indent,0,-1);
if ($in_script !== false) $rest = highlight_script($rest);
$ret .= $rest;
}
}
}
return $ret;
}
function highlight_script($code) {
global $built_in_functions;
global $current_doc_file;
$ret = '';
$string = ''; // inside "{..}" braces? b for braces, s for string
while(strlen($code)) {
if (preg_match("@^<[^>]+>@",$code, $matches)) {
$ret .= $matches[0]; // plain tag
} else if (preg_match("@^(rgb)[(]([0-9]+),([0-9]+),([0-9]+)[)]@",$code, $matches)) {
$ret .= "<span class='hl-rgb'><span class='popup' style='background:" . $matches[0] . "'></span>"
. "<span class='hl-kw'>rgb</span>("
. "<span class='hl-num'>" . $matches[2] . "</span>,"
. "<span class='hl-num'>" . $matches[3] . "</span>,"
. "<span class='hl-num'>" . $matches[4] . "</span>)</span>";
} else if (preg_match("@^(if|then|else|for( each)?|in(?= )|do|div|mod|and|or|xor|not|rgb|rgba|from|to|min|max)\b(?!:)@",$code, $matches)) {
$ret .= "<span class='hl-kw'>" . $matches[0] . "</span>";
} else if (preg_match("@^(include localized file:)(.*)@",$code, $matches)) {
$ret .= "<span class='hl-key'>" . $matches[1] . "</span>" . $matches[2];
} else if (preg_match("@^(include file:)(.*)@",$code, $matches)) {
$ret .= "<span class='hl-key'>" . $matches[1] . "</span>" . $matches[2];
} else if (preg_match("@^([0-9][0-9.]*|true|false)@",$code, $matches)) {
$ret .= "<span class='hl-num'>" . $matches[0] . "</span>";
// } else if (preg_match("@^(\"|&quot;)(\\\\.|[^\\\\])*?(\"|&quot;)@",$code, $matches)) {
// $ret .= "<span class='hl-str'>" . $matches[0] . "</span>";
} else if (preg_match("@^(\"|&quot;)(\\\\.|[^\\\\{])*?(\"|&quot;|{)@",$code, $matches)) {
$ret .= "<span class='hl-str'>" . highlight_script_string($matches[0]) . "</span>";
if ($matches[3] == '{') $string .= 's';
} else if ($string != '' && $string{strlen($string)-1}=='s' &&
preg_match("@^}(\\\\.|[^\\\\{])*?(\"|&quot;|{)@",$code, $matches)) {
// return from string quote
$ret .= "<span class='hl-str'>" . highlight_script_string($matches[0]) . "</span>";
$string = substr($string,0,-1);
if ($matches[2] == '{') $string .= 's';
} else if (preg_match("@^\\#.*@",$code, $matches)) {
$ret .= "<span class='hl-comment'>" . $matches[0] . "</span>";
} else if (preg_match("@^([-+*/=!.\@^]|&lt;|&gt;)+|^:=@",$code, $matches)) {
$ret .= "<span class='hl-op'>" . $matches[0] . "</span>";
} else if (preg_match("@^([\\(\\)\\[\\],]+)@",$code, $matches)) {
$ret .= "<span class='hl-paren'>" . $matches[0] . "</span>";
} else if (preg_match("@^[{}]@",$code, $matches)) {
$ret .= "<span class='hl-fun-paren'>" . $matches[0] . "</span>";
if ($matches[0] == '{') $string .= 'b';
elseif ($matches[0] == '}') $string = substr($string,0,-1);
} else if (preg_match("@^[a-zA-Z_][a-zA-Z0-9_]*:@",$code, $matches)) {
$ret .= "<span class='hl-ckey'>" . $matches[0] . "</span>";
} else if (preg_match("@^([a-zA-Z0-9_]+|\s+|&#?[a-zA-Z0-9]+;)@",$code, $matches)) {
$m = $matches[0];
// function call?
if (isset($built_in_functions[$m]) && // to built in function
preg_match("@\s*[+(){}]@",substr($code, strlen($matches[0]))) // in a function context
) {
$f = $built_in_functions[$m];
if ($f == '') $f = $m;
$f = 'function/' . $f;
if (!isset($current_doc_file) || $current_doc_file != $f) {
$ret .= "<a class='hl-fun' href='" . url('doc/' . $f) . "'>" . $m . "</a>";
} else {
$ret .= "<span class='hl-this'>$m</span>"; // current function
}
} else {
$ret .= $m;
//$ret .= '[' . $m . ']';
}
} else {
// fallback
$matches = array($code[0]);
//$ret .= '{{{' . $matches[0] . '}}}';
$ret .= $matches[0];
}
$code = substr($code, strlen($matches[0]));
}
return $ret;
}
function highlight_script_string($code) {
$code = preg_replace("@&lt;.*?(&gt;|>)@", "<span class='hl-tag'>\\0</span>", $code);
return $code;
}
?>