corz.org uses cookies to remember that you've seen this notice explaining that corz.org uses cookies, okay!
<?php /* --- ۞---> text { encoding:utf-8;bom:no;linebreaks:unix;tabs:4sp; } */
$textview['version'] = '1.4.2';
/*
textview.php
a fun, simple highlighting text handler, from corz.org.
This script makes the text smaller, which I like, and does some source
highlighting too, which I tag on for fun sometimes. So far it does # and
// single-line comments, c-style/php multi-line comments (i can't do them
here, because I'm already inside a multi-line comment!) looks cool. It also
highlights $variables, and now ":" Windows .bat files comments, strings, as
well as AutoIt scripts, CSS and other stuff. It doesn't pretent to be very
clever, just makes stuff more readable.
I use it (and its services) to embed highlughted source code into my pages.
It is not a replacement for GeSHi, or similar. If you need full-blown source
highlighting for technical purposes, this probably isn't the script you are
looking for.
Usage:
Either call directly, specifying the file in the URL, e.g..
http://example.com/textview.php?txtfile=/public/scripts/script.sh
or else include for highlighted() function.
Automatic File Highlighting:
For this to work all swimming you need this in your .htaccess file..
RewriteEngine on
RewriteRule ^(.+)\.txt$ /inc/textview.php?txtfile=/$1.txt [nc,l,qsa]
altering the path to wherever you keep this handler, of course.
depending on what was requested, the text viewer presents either a
highlighted, formatted version, or a raw version, which essentially
bypasses processing altogether. For example..
If you had some text files living inside /public/scripts/, with
extensions, .sh, .txt, and .bat, something like this** could go inside
/public/scripts/.htaccess
RewriteEngine on
RewriteRule ^(.+)\.sh$ /inc/textview.php?txtfile=/public/scripts/$1.sh [NC,L,QSA,NS,NE,B]
RewriteRule ^(.+)\.txt$ /inc/textview.php?txtfile=/public/scripts/$1.txt [NC,L,QSA,NS,NE,B]
RewriteRule ^(.+)\.bat$ /inc/textview.php?txtfile=/public/scripts/$1.bat [NC,L,QSA,NS,NE,B]
DO *NOT* put this in your root, but instead in top level folders, or
sub-folders, editing the rules to whatever path it's in, and whatever file
types live in that area..
a) it allows greater control,
b) this helps prevent deeper rewrite rules from obliterating your
redirections. By the way, if that ever happens, you simply add
further rules in the affected sub-folder, adding the extra
paths, as above. And most crucially;
c) files like "robots.txt" *MUST* presented as plain text!
*** REMEMBER ***
KEEP THESE REWRITE RULES OUT OF YOUR ROOT!!
Actually, the root .htaccess is absolutely the best place to keep *all*
your rewrite directives, BUT, you still need to keep the *rules* out of
your root. In other words, if these rules go in your root .htaccess,
you need to put some of the path into the rule itself...
RewriteRule ^server/(.*)\.c$ /inc/textview.php?txtfile=/server/$1.c [NC,L,QSA,NS,NE,B]
So that the rule doesn't catch your robots.txt, abuse.txt, and so on.
And don't forget to start the target with a forward slash "/".
For a demo, go here..
https://corz.org/server/resources/file_view.htaccess.conf
;o)
** Yes, of course you can combine them if you wish! Something like..
RewriteRule ^public/scripts/(.*)\.(au3|ahk|bat|c|cfg|conf|cpp|pl|sh|txt|com|net|org|nfo)$ /inc/textview.php?txtfile=/public/scripts/$1.$2 [NC,L,QSA,NS,NE,B]
(c) 2004->tomorrow! ~ cor + corz.org ;o)
Please view the license for this free software, here:
https://corz.org/free-scripts-licence.nfo
*/
//*> prefs..
// I load my site prefs like so..
//require_once $_SERVER['DOCUMENT_ROOT'].'/inc/init.php';
/*
missing pages
In the event of the requested file being missing for some reason, the user's
browser is sent a pseudo-fake 404 error, which *should* take them to your
404 error page, wherever that is, with a meaningful path to play with.
If you set this to true, the user will instead get textview's built-in demo page.
do this if you're kinky, or are messing with the highlighting, or have a crap 404
page. hit a 404 at corz.org for a decent one.
*/
$textview['demo_on_404'] = true;
/*
line-break
if all your users have nice standards-compliant browsers, you can use "\n" here,
and nice PRE white-spacing in the output (css), but probably you will need to
use '<br />', so it doesn't look like shi*e in **I*E. Or use both!
*/
$textview['line_break'] = '<br />'."\n";
/*
security */
/*
Allowed Extensions
which extensions are they allowed to view?
*/
$textview['extensions'] = 'arse,au3,ahk,bat,c,cfg,cpp,conf,ini,nfo,pl,sh,txt,com,net,org,css';
// note commas *between* entries.
/*
Banned Folders
We will NOT show files from these folders..
*/
$textview['banned'] = 'inc,data,cgi,includes';
/*
Note, this is a Case Sensitive Match. */
// optionally include your site header..
// this location is taken from the root of your site (or enter the complete system path)..
$textview['site_header'] = '';
// optionally include your site footer.. (same path rules as header)
$textview['site_footer'] = '';
// CSS to use for the text viewer..
// (separate multiple sheets with commas)
$textview['styles'] = '/inc/css/textview.css';
/*
end prefs */
// we may need to send headers in the middle somewhere..
ob_start();
$textview['root'] = $_SERVER['DOCUMENT_ROOT'];
$textview['clean'] = $textview['bad'] = false;
$textview['file_name'] = $textview['fext'] = $textview['txt_file'] = $textview['file_path'] = '';
if (!empty($_GET['raw'])) $textview['clean'] = true;
$is_404 = false;
// we'll grab $textview['file_path'] before we manipulate $textview['txt_file']..
if (isset($_GET['txtfile'])) {
$textview['txt_file'] = trim(fix_slashes($_GET['txtfile']));
if (!file_exists($textview['root'].$textview['txt_file'])) {
$textview['txt_file'] = str_replace(' ', '+', $textview['txt_file']);
if (!file_exists($textview['root'].$textview['txt_file'])) {
$is_404 = true;
}
}
$textview['file_path'] = $textview['txt_file'];
}
// split prefs into an array..
$textview['extensions'] = explode(',',$textview['extensions']);
$textview['banned'] = explode(',',$textview['banned']);
// when included for the highlighted() function, this section won't wun..
//
if (realpath($_SERVER['SCRIPT_FILENAME']) == realpath(__FILE__)) {
if ($textview['txt_file'] !== '') {
// basename
$textview['file_name'] = basename($textview['txt_file']);
// get the extension..
$textview['fext'] = substr($textview['txt_file'], strrpos($textview['txt_file'], '.')+1);
if (!is_good_extension($textview['fext'])) {
die('your bad');
}
if (!$is_404) {
$textview['clean_link'] = rawurlencode($textview['file_name']).'?raw=true';
}
}
//*> "clean" (raw) version..
//
if ($textview['clean']) {
// just in case its set, mine is; saves bandwidth.
ini_set('zlib.output_compression', 0);
// you may want a different encoding, but then, why?
header('Content-type: text/plain; charset=utf-8');
if ($is_404) {
die("\n\n\tThis file..\n\n\t".$textview['txt_file']."\n\n\tdoes not exist! :/");
}
if (is_readable($textview['root'].$textview['txt_file'])) {
$tv_get_it = fopen($textview['root'].$textview['txt_file'], 'rb');
header('Content-Type: text/plain; charset=utf-8'); // save-as *should* show original extension..
header('Content-Disposition: inline; filename='.basename($textview['txt_file']));
fpassthru($tv_get_it);
} else {
die('something bad happened reading '.$textview['txt_file'].' :/');
}
} else {
//*> Do Page..
do_textview_header(); // my own site header now, if available.. or yours. ;o)
if (isset($textview['site_header']) and $textview['site_header'] != '') { // normalize the path..
$textview['site_header'] = str_replace($_SERVER['DOCUMENT_ROOT'], '', $textview['site_header']);
if (file_exists($_SERVER['DOCUMENT_ROOT'].$textview['site_header'])) {
include $_SERVER['DOCUMENT_ROOT'].$textview['site_header'];
}
}
//*> Built-In Demo..
if (empty($textview['file_path'])) {
$tv_nav_title = 'built-in demo';
$textview['clean_link'] = '';
// 404..
} elseif ($is_404) {
$tv_nav_title = $textview['txt_file'].' = NON-EXISTENT FILE!';
} else { // OK!
$tv_dir_paths = explode('/', dirname($textview['file_path']));
$tv_nav = 'http://'.$_SERVER['HTTP_HOST'];
$tv_links = array();
// path of links to all the parent dirs..
foreach ($tv_dir_paths as $tv_sumdir) {
$tv_nav .= $tv_sumdir.'/';
$tv_links[] = '<a href="'.$tv_nav.'" title="go up to '.$tv_nav.'">'.$tv_sumdir.'/</a>';
}
$tv_nav_title = implode(' ', $tv_links).' <a href="'.$tv_nav.$textview['clean_link'].
'" title="You can click here to see the raw text version">'.$textview['file_name'].' - raw</a>';
}
echo '
<div class="content super-wide">
<div class="textview-main-title">
',$_SERVER['HTTP_HOST'],' text viewer..';
if (!empty($_GET['version'])) echo ' v'.$textview['version'];
echo '<br />
<small>[currently viewing: ',$tv_nav_title,']</small>
</div>';
echo '
<div class="clear"></div>
<div class="textview-body">';
echo highlighted($textview['file_path']);
echo '
</div>
<div class="clear"></div>
<div class="textview-engine-link">
<a href="https://corz.org/server/tools/">click here for more groovy stuff like this</a>
</div>
</div>';
if (!empty($textview['clean_link'])) {
echo '
<div class="toplinks">
<a href="',$textview['clean_link'],'" title="Yes. You will have to change the file extension when you get it home!" id="plain-text-link">click here for plain text</a>
</div>';
}
//*> Footer..
if (isset($textview['site_footer']) and $textview['site_footer'] != '') {
// normalize path..
$textview['site_footer'] = str_replace($_SERVER['DOCUMENT_ROOT'], '', $textview['site_footer']);
if (file_exists($_SERVER['DOCUMENT_ROOT'].$textview['site_footer'])) {
include $_SERVER['DOCUMENT_ROOT'].$textview['site_footer'];
}
} else {
echo '
<script nonce="'.$_SERVER['CSP_NONCE'].'">
parent.document.body.style.webkitTextSizeAdjust = "auto";
parent.document.body.style.zoom = "100%";
</script>';
}
echo '
</body>
</html>';
}
}
/*
fin
*/
/*
highlighted a text file
send it a file path (from your site root)
and get back a highlighted string of its contents.
this will do more and more in time, I guess.
*/
function highlighted($textfile) {
global $textview;
//echo '<pre>textview:',htmlentities(print_r($textview,true)),'</pre>';//:debug
// grab this before we manipulate it.
$textview['file_name'] = basename($textfile);
$file_ext = substr($textfile, strrpos($textfile, '.') + 1);
if (substr($textfile, 0, 1) != '/') { $token = '/'; } else { $token = ''; }
$textfile = $textview['root'].$token.$textfile;
// no text file at the given location..
if (!file_exists($textfile) or !is_file($textfile) ) {
//send a 404..
if (!$textview['demo_on_404']) {
// might as well bin this stuff.
ob_clean();
// not really needed when sending the fake location, but harmless to leave in
header('http/1.1 404 Not Found');
//send them a location header with the filename in it
header('Location: http://'.$_SERVER['HTTP_HOST'].'/'.$textview['file_name']);
// or you could just send them a generic 404..
// header('Location: 404');
ob_end_flush();
exit;
} else {
// built-in demo..
$string_to_highlight = do_test_string();
}
} else { // okay, we have a valid text file..
$string_to_highlight = file_get_contents($textfile);
}
$highlighted = trim(switch_entities($string_to_highlight), "\n\r"); // php5.4+
// $highlighted = trim(htmlentities($string_to_highlight), "\n\r");
// there's probably a smart way to do this..
$old_chrs = array("\r\n", "\r", " ", "\t"); // convert linebreaks and stuff
$new_chrs = array("\n", "\n", " ", " "); // not exactly accurate
$highlighted = str_replace($old_chrs, $new_chrs, $highlighted);
// let's highlight!
$highlighted = process_lines($highlighted, $file_ext);
// back to a plain string now, but with our own line-break.
// from now on we will process the string as a whole.
$highlighted = highlight_c_comments($highlighted, $file_ext);
if ($file_ext == 'au3') {
$highlighted = highlight_au3_comments($highlighted);
}
$highlighted = highlight_quotes($highlighted);
if ($file_ext == 'css') {
$highlighted = highlight_CSS($highlighted);
$highlighted = highlight_variables($highlighted, '#');
} else {
$highlighted = highlight_variables($highlighted);
}
// we may plug in something else right here.
return $highlighted;
}
/*
we'll use a few different techniques to highlight our parts,
just for fun.
*/
// damn php 5.3!
function switch_entities($string) {
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
if (PHP_VERSION_ID >= 50390) {
return htmlentities($string, ENT_COMPAT|ENT_SUBSTITUTE, 'UTF-8');
} else {
return @htmlentities($string, ENT_COMPAT, 'UTF-8'); // poor systems will fall-back to Latin1
}
}
/*
single line comments
*/
function process_lines($tring, $fext) {
// convert our text into an array of "lines"..
$tv_lines = explode("\n", $tring);
// process comments..
while (list($key, $val) = each($tv_lines)) {
switch (true) {
// single line shell/perl/php comments: (#)..
case (stristr($tv_lines[$key], '#') and $fext !== 'css'):
$pre_str = substr($tv_lines[$key], 0, strpos($tv_lines[$key], '#')); // before '#', possibly
$apr_str = substr($tv_lines[$key], strlen($pre_str) + 1); // after '#'
$tv_lines[$key] = $pre_str.'<span class="textview-comment">#'.$apr_str.'</span>';
break;
// single line ini/AutoIt comments: (;).. (messy, but works great!)
// the trouble is the ";" is in *every* html entity!
case (($fext == 'au3') or ($fext == 'ini')):
// case (ext in $semicolon_comments_array or something)
$tv_lines[$key] = @html_entity_decode($tv_lines[$key], ENT_COMPAT, 'UTF-8');
if (stristr($tv_lines[$key], ';')) {
$pre_str = substr($tv_lines[$key], 0, strpos($tv_lines[$key], ';'));
$apr_str = substr($tv_lines[$key], strlen($pre_str) + 1);
$tv_lines[$key] = $pre_str.'**start-ac**'.$apr_str.'***end-ac***';
}
$tv_lines[$key] = switch_entities($tv_lines[$key]);
$tv_lines[$key] = str_replace('**start-ac**', '<span class="textview-comment">;', $tv_lines[$key]);
$tv_lines[$key] = str_replace('***end-ac***', '</span>', $tv_lines[$key]);
break;
// single line batch file comments: (:).. [only if they are first on the line]
case ($fext == 'bat'):
if (substr(trim(str_replace(' ', '', $tv_lines[$key])),0,1) == ':') {
$pre_str = substr($tv_lines[$key], 0, strpos($tv_lines[$key], ':'));
$apr_str = substr($tv_lines[$key], strlen($pre_str) + 1);
$tv_lines[$key] = $pre_str.'<span class="textview-comment">:'.$apr_str.'</span>';
break;
}
}
}
// back to a string, but with our custom line-break..
return implode($GLOBALS['textview']['line_break'], $tv_lines);
}
/*
highlight CSS directives..
Note: Some styles of CSS coding will evade the highlighter!
*/
function highlight_CSS($tring) {
$outer_lines = explode('<br />', $tring);
while (list($outerkey, $outerval) = each($outer_lines)) {
if (strstr($outerval, ':') and !strstr($outerval, '{')) {
$outer_lines[$outerkey] = '<span class="textview-keyword">'.substr($outerval, 0, strpos($outerval, ':')).'</span>'.
substr($outerval, strpos($outerval, ':'));
}
}
return implode('<br />', $outer_lines);
}
/*
highlight c-style multi-line comments..
*/
function highlight_c_comments($tring, $fext='') {
if ($fext == 'conf') { return $tring; }
$lines = explode('/*', $tring);
next($lines); // advance the array by 1
while (list($key, $val) = each($lines)) {
$end_pos = strpos($val, '*/'); // position of the end of the comment
$lines[$key] = '<span class="textview-comment">/*'
.substr($val, 0, $end_pos).'*/</span>'.substr($val, $end_pos + 2);
}
return implode('', $lines);
}
/*
highlight AutoIt multi-line comments..
*/
function highlight_au3_comments($tring) {
if (isset($GLOBALS['textview']['fext'])) {
if ($GLOBALS['textview']['fext'] != 'au3') { return $tring; }
}
$lines = explode('#cs', $tring);
next($lines); // advance the array by 1
while (list($key, $val) = each($lines)) {
$end_pos = strpos($val, '#ce'); // position of the end of the comment
$lines[$key] = '<span class="textview-comment">#cs'
.substr($val, 0, $end_pos).'#ce</span>'.substr($val, $end_pos + 3);
}
return implode('', $lines);
}
/*
highlight quoted strings..
*/
function highlight_quotes($tring) {
// strings inside quotes (.. and the procedural prize goes to ..)
$lines = explode('"', $tring);
$b = true;
while (list($key, $val) = each($lines)) {
if (!$b) { // this is fun!
$lines[$key] = '<span class="textview-strings">"'.$lines[$key].'"</span>';
}
// kinda like a good fart.. heh
if (!$b) { $b = true; } else { $b = false; }
}
return implode('', $lines);
}
/*
highlight variables..
*/
function highlight_variables($tring, $delim='$') {
$first_non_alumn_pos = 0;
$var_strings = explode($delim, $tring);
next($var_strings); // advance the array.
while (list($key, $some_string) = each($var_strings)) {
// get the position of the end of the variable "word"
for ($i=0, $limit=strlen($some_string); $i<$limit; $i++) {
// we allow "_" characters inside the variable names..
if ((!ctype_alnum($some_string[$i])) and ($some_string[$i] != '_')) {
$first_non_alumn_pos = $i;
break; // only out of the for-loop.
}
}
$var_strings[$key] = '<span class="textview-variable">'.$delim.substr($some_string, 0, $first_non_alumn_pos).
'</span>'.substr($some_string, $first_non_alumn_pos);
}
return implode('', $var_strings);
}
// add slashes to a string, or else don't..
function fix_slashes($string) {
if (get_magic_quotes_gpc()) {
return trim(stripslashes($string));
} else {
return trim($string);
}
}
/*
check the file extension is allowed
*/
function is_good_extension($extension) {
global $textview;
if (!in_array($extension, $textview['extensions'])) {
return false;
}
foreach ($textview['banned'] as $banned) {
if (strstr($textview['file_path'], $banned.'/')) {
return false;
}
}
return true;
}
function do_test_string() {
return '
no text file was present in the given location.
you have reached..
"the textview test page"..
Let\'s go..
ßetas from a ßeta.. (weird entity test)
Some plain "text" here. a "nice" mod_rewrite # rule..
RewriteRule ^(.*)\.t(.*)xt /inc/textview.php?txtfile=/$1.t$2xt [nc]
# did you notice that the $variables are green?
# this is just a single line comment, like the one above.
back to reality..
/*
v0.2
"textview.php" - >>
for a "demo", go here..
<https://corz.org/public/linux/usr/local/bin/mysql_backup.sh>
;o)
*/
this is just a test file!
no, really..
/* and this is "indented" comment */
got my own style, I like /* comments here */ sometimes.
normality # this is *my* text viewer, don\'t forget.
normality
Now I will be sneaky, and have a "quotation that
spans new-lines
just for" FUN!
# some more
# single line comments
: this isn\'t considered a comment, because the extension isn\'t ".bat"
ok, back to text
and then somewhere around here start a multi-line comment.. here->/*
end function:do_textview_header()
still in the comments
*/<- and end it there!
AOK!
We have TEXT!';
}
/*
do a page header
*/
function do_textview_header() {
global $textview;
if (empty($GLOBALS['textview']['file_name'])) {
$title_str = 'built-in demo';
} else { $title_str = $GLOBALS['textview']['file_name']; }
echo '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<title>text view of '.$title_str.'</title>';
echo '
<meta name="description" content="text files served with love and simple formatting" />
<meta name="generator" content="textviewer, by Cor @ corz.org" />';
$style_sheets = explode(',', $textview['styles']);
foreach ($style_sheets as $my_sheet) {
echo '
<link rel="stylesheet" href="',$my_sheet,'" type="text/css" media="screen"/>';
}
echo '
</head>
<body>';
}
/*
changes.
1.3
Added basic CSS haighlighting.
1.2.6
Improved entity encoding - some other stuff.
1.2.5
Improved the system for printing out the parent path. It is simpler, uses
less code, and will not break the "raw" link when the URI is via mod_rewrite
or similar mechanism where the URI and path do not match.
It's also formatted better, better spaced, more clickable.
1.2
Improved entitiy decoding under different php environments.
Added fix for certain browser's default zoom. Bah!
Incorporated multiple style sheet handling (separate sheets with commas).
1.0.3
Improved formatting.
1.0.2
removed debugging lines - would throw up an error when trying to view the raw version
of a non-existent page, or rather, the *wrong* error!
1.0.1
minor imporvements to some of the highlighting routines
1.0
new release extension overhaul version
deprecated the old .txt -> .text mapping, which was confusing, even for me
we now use $_GET variables to specify the "clean" version. works great.
0.7.3
added highlighting for ini and au3 (AutoIt) files. big fun!
0.7.2
improved the batch file comment logic.
0.7.1
improved the single-line commenting. now you can only have one kind on each line
so they won't interfere with each other. "#" comments can also start on any position
on the line (c-style comments always could.) and indenting them no longer screws them up.
by the way, if the file extension is ".conf", no c-style highlighting is applied.
it's not uncommon to have config lines ending "/*" :/
removed "//" type comment highlighting. they are only for php, afaik.
while I'm here, ".bat" file comments must be first on the line to be considered valid
comments, though they may be indented by spaces or tabs. This line would be highlighted..
:I am a comment
this one would not..
I am a command :I am a comment
This only applies to windows .bat files. A unix shell script would get highlighting
applied to this line..
I am a command # I am a comment
0.7
added headers so that the raw version arrives in the browser with its original file
extension. although when the user clicks the "clean" link, ".bash" may appear in the
address bar (our virtual "clean" link), if the user saves the file, it will be saved
as ".sh", neat!
fixed a bug where dots in the filename would cause problems when you tried to view
the "raw" version.
left in the debugging lines, you may find useful.
improved the file name logic, made this much more flexible and fluid.
changed the way extension preferences are set. it's now an array.
0.6.8
more minor clean-ups and tweaks
added the neat switch for the css. this makes distribution super-easy.
I'll use this again!
0.6.7
I decided to go with "fake PRE" output, which, when you look at it, isn't dissimilar
to php's built-in php source highlighting function, full of characters!
This provides the most even cross-browser viewing experience.
textviewer now correctly handles c-style multi-line comments. previously
certain conditions needed to be satisfied in order for the comment to be
considered so. this has also made the code a lot smaller.
0.6.6
minor clean-ups and tweaks.
0.6.5
made the extension handling somewhat more robust. a file called my.text.txt will
no longer give "interesting" effects.previously,
"nakedness and the finnish sauna.txt"
would get a "clean" link something like..
"nakedness and the finnibash sauna.text" (note "finnibash")
All better now. In fact, this has turned into quite a robust wee handler.
0.6.3
made the path information into a series of links all the way up the tree. nice.
fixed the bug where a file with one of your banned folders in its name would
give you the "your bad" error. for instance, "opium_eater-quincey.txt", which
contains the term "inc". Now we check for "inc/".
0.6:
made it drop-dead easy for you to add new extensions to the mix, and to prove
the point, added ".bat" (Windows shell batch (script)) and ".nfo" (information)
file handling. I think I have now covered all the text file types in the
corz.org public archives.
added some information to the main title. there's now a sub-title showing where
you currently are in the document tree and offering a link back up to the
containing folder, and an alternative link to the raw version, embedded in the
path text.
Added z-index to the css, most browsers can handle it okay, even IE.
you can now configure what is used to break the lines. I noticed IE squishing
all the text if I used '\n', and '<br />' works better, but it's your call.
0.5:
made it xhtml 1.0 strict, along with everything else at the org, in time.
added rudimentary ".sh" (UNIX shell script) file capabilities; the highlighting
mechanism covers them nicely.
I also added $variable highlighting, which works rather well. Like the quotes
highlighting, it works inside other highlighting, so you can see, for instance
green variables inside grey comments. Variables can contain alphanumerics or
"_" (underscore) characters. essentially, [_a-z0-9]/i.
Added some security measures. Previously it would let you view pretty much any
file you pointed it at. Incredible that no one logged into my admin page and
did nefarious stuff. :/
0.4:
fixed a potential issue with saving "plain" text files. if your server
was using gzip compression, the user got a gz version. very few would figure
this out though, as the extension remains .text
0.3.3:
added "quotes" highlighting. text inside quotes, that is.
0.3.2:
now we only highlight c-style comments if they begin on a new line.
makes more sense. the htaccess files make more sense now.
0.3.1:
if there is no text file, the browser is sent a 404, rather than nothing.
0.3:
added single-line # // comment and c-style /* comment highlighting
0.2:
added "plain text" link, the user can get the raw version, too.
0.1:
with mod_rewrite's help, we got a text handler, basic, but effective.
*/
?>