Preview files with syntax highlighting.
Features
✔ Flexible: Can preview items which are dropped on it or those selected when running.
✔ Prettify: This uses Google's Prettify for color highlighting which has a few themes, works surprisingly well for XYplorer scripts already, and can color even non-source files like INI, Markdown, or bizarre proprietary formats.
✔ Customizable: In addition to the easily accessible options there are also some user tweaks for further fine-tuning.
General structure
For the most part all this does is read in the contents of the dropped, selected, or focused items and then displays them in an HTML preview. The real bulk is in just generating the HTML and parsing back the form response.
As stated above I tried to keep it flexible and customizable, so while it gives preference to storing settings in a permanent variable it can also store them in an INI file, and can play nice if you want to share that INI file with other scripts.
It does make use of _Initialize, but as there is only one entry point it can manage calling it on its own for older versions of XY.
Usage
Select some files to preview and then run the script.
Or add the script to your toolbar or catalog and drop items on it.
If you're completely new to scripting I strongly suggest you read:
Stephen's How to use and execute a script ? and my own Tips: Managing Scripts.
Tested on
* Microsoft® Windows® 7 Professional SP1 x64
* XYplorer v12.30.0002.
Requirements
+ XYplorer (version 12.30.0002 or greater) with
- scripting enabled
+ Internet connection
Notes
* This was developed in response to a wish.
Possible future updates
* Self-Update Checking
Release notes
Code: Select all
Rev. 1.00 / 2013-03-25
* Initial Release
![]()
![]()
Special thanks to...
* Marco, for coming up with the forum template.
Code
Code: Select all
/*##############################################################################
## CodePreview.xys
##
## This script file previews code with syntax highlighting via
## Google's Prettify ( https://code.google.com/p/google-code-prettify/ ).
##
## By default it will use a permanent variable if the user has XY
## configured to retain them across sessions. Otherwise, it will create a
## folder "<xyscripts>\.config" and store them within a file there.
##
## However there are tweaks in the script which allow you to force the use of
## an INI file and define its path.
##
##
## Author: TheQwerty
## Version: 1.0
## Date: 2013-03-25 T19:00Z;
## Requires: XY (Currently only tested on v12.30.0002.)
##############################################################################*/
/*******************************************************************************
** User Tweaks
*******************************************************************************/
"User Tweaks||4 : _getTweaks"
Global $G_FORCE_INI_USE = false;
// Set to 'true' to force the script to use an INI file for settings.
// This causes it to bypass checking if permanent variables are retained.
// Default: false
Global $G_INI_FILE = "<xyscripts>\.config\TheQwertysScripts.ini";
// Set to the path to the INI settings file.
// Used when G_FORCE_INI_USE is true or permanent variables are not retained.
// Default: "<xyscripts>\.config\TheQwertysScripts.ini"
Global $G_INI_SECTION = 'CODE_PREVIEW';
// Set to the INI file section.
// This allows you to have multiple scripts share an INI file.
// Default: 'CODE_PREVIEW'
/************************************************************* END _getTweaks */
"- : _-" //---------------------------------------------------------------------
/*******************************************************************************
** Initialize
*******************************************************************************/
"Initialize||4 : _Initialize"
Sub('_readOptions');
Global $G_INITIALIZED = True;
/************************************************************ END _Initialize */
/*******************************************************************************
** Get Configuration
** Reads settings from permanent variables or INI file depending on
** circumstances.
*******************************************************************************/
"Get Configuration||4 : _readOptions"
Status 'Reading configuration...',, 'progress';
// Retrieve internal script tweaks.
Sub('_getTweaks');
Global $G_INI_FILE, $G_FORCE_INI_USE, $G_INI_SECTION;
//FORMAT: Warn|WarnLimit|SkipEmpty|Sounds|Width|Height|LineNums|Skin
Global $G_OPTIONS = "1|10|0|1|60%|60%|0|Default";
// Skip permanent variable check if user is forcing INI use.
if ($G_FORCE_INI_USE) {
$ScriptRetainPVs = false;
} else {
$ScriptRetainPVs = GetKey('ScriptRetainPVs', 'Settings');
}
// Use permanent variables if the user has XY retain them.
if ($ScriptRetainPVs && $P_THEQWERTY_PREVIEW_CODE__OPTIONS) {
Status 'Read configuration from permanent variables.',, 'progress';
$G_OPTIONS = $P_THEQWERTY_PREVIEW_CODE__OPTIONS;
// Use an INI file.
} else {
if (1 == Exists($G_INI_FILE)) {
$iniOptions = GetKey('Options', $G_INI_SECTION, $G_INI_FILE);
if ($iniOptions) {
Status 'Read configuration from INI file.',, 'progress';
$G_OPTIONS = $iniOptions;
}
}
}
/*********************************************************** END _readOptions */
/*******************************************************************************
** Set Configuration
** Writes settings to permanent variables or INI file depending on
** circumstances.
*******************************************************************************/
"Set Configuration||4 : _setOptions"
Status 'Saving configuration...',, 'progress';
// Retrieve internal script tweaks.
Sub('_getTweaks');
Global $G_INI_FILE, $G_FORCE_INI_USE, $G_INI_SECTION;
Global $G_OPTIONS;
// Skip permanent variable check if user is forcing INI use.
if ($G_FORCE_INI_USE) {
$ScriptRetainPVs = false;
} else {
$ScriptRetainPVs = GetKey('ScriptRetainPVs', 'Settings');
}
// Use permanent variables if the user has XY retain them.
if ($ScriptRetainPVs) {
perm $P_THEQWERTY_PREVIEW_CODE__OPTIONS = $G_OPTIONS;
Status 'Saved configuration to permanent variable.',, 'progress';
// Use an INI file.
} else {
if (1 != Exists($G_INI_FILE)) {
Status 'Creating INI file...',, 'progress';
New($G_INI_FILE, 'file');
}
SetKey $G_OPTIONS, 'Options', $G_INI_SECTION, $G_INI_FILE;
Status 'Saved configuration to INI file.',, 'progress';
}
/************************************************************ END _setOptions */
"- : _-" //---------------------------------------------------------------------
/*******************************************************************************
** Preview Code
** Displays a preview for the dropped, selected, or focused items using
** syntax highlighting.
*******************************************************************************/
"Preview Code||1 : previewCode"
// Ensure _Initialize was executed.
Global $G_INITIALIZED;
if (! $G_INITIALIZED) {
Sub '_Initialize';
}
Unset $G_INITIALIZED;
// Extract Options.
Global $G_OPTIONS;
$optSep = '|';
$optI = 0;
$optWarn = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optWarnLimit = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optSkipEmpty = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optSounds = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optWidth = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optHeight = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optLineNums = GetToken($G_OPTIONS, $optI++, $optSep, 't');
$optSkin = GetToken($G_OPTIONS, $optI++, $optSep, 't', 2);
$optLineNumValue = ($optLineNums) ? 'linenums' : '';
$optSkinValue = ($optSkin LikeI 'Default') ? '' : Recase($optSkin, 'lower');
Unset $optSep, $optI;
// Guesses which items the user wants us to handle.
// Precedence: Dropped > Selected > Focused
$files = Get('Drop');
if (! $files) {
$files = Get('SelectedItemsPathNames');
if (! $files) {
$files = Get('Item');
Status 'Previewing Focused Item...',, 'progress';
} else {
Status 'Previewing Selection...',, 'progress';
}
} else {
Status 'Previewing Dropped...',, 'progress';
}
// Warn user when previewing many items.
$fileCount = GetToken($files, 'Count', "<crlf>");
if ($optWarn && $fileCount > $optWarnLimit) {
$res_OK = Confirm(<<<#HEREDOC
Preparing this preview may take some time.
Are you sure you want to preview $fileCount items?
#HEREDOC);
if (! $res_OK) {
Status 'Aborted Preview',, 'stop';
if ($optSounds) { Sound 'SystemHand'; }
End true;
}
Unset $res_OK;
}
// Collect the contents of each file.
Status 'Checking items...',, 'progress';
$content = '';
// Track whether we got any true contents.
$noFiles = True;
// If we see the emptyMsg something went horribly wrong above.
foreach($file, $files, "<crlf>",, 'No file to preview.') {
if (! $file) {
continue;
}
// Check if item is not a text file....
$fileType = FileType($file);
if (RegexMatches($fileType, 'Binary|Empty|Cannot|NoFile')) {
$fileType = ReplaceList( $fileType,
'Cannot|NoFile',
'Could not open|File not found', '|');
$fileContent = " Skipped – $fileType.<BR />";
// Otherwise get its contents....
} else {
$noFiles = False;
$fileName = GetPathComponent($file, 'file');
Status "Reading $fileName...",, 'progress';
$fileContent = ReadFile($file);
// Lazy, half-hearted sanitation.
$fileContent = ReplaceList($fileContent, '<|>', '<|>', '|');
$fileContent = <<<#HEREDOC
<PRE class='prettyprint $optLineNumValue'>
<CODE>$fileContent</CODE>
</PRE>
#HEREDOC;
}
$content = $content . "<H4>$file:</H4>$fileContent";
}
Unset $file, $fileType, $fileContent, $fileName, $optLineNumValue;
// Skip empty previews.
if ($optSkipEmpty && $noFiles) {
Status 'Skipped empty preview.',, 'stop';
if ($optSounds) { Sound 'SoundNotification'; }
End true;
}
Unset $noFiles;
Status 'Generating preview...',, 'progress';
// Initialize form.
$optWarnChecked = ($optWarn == 1) ? 'checked' : '';
$optWarnLimitDisabled = ($optWarn != 1) ? 'disabled' : '';
$optSkipEmptyChecked = ($optSkipEmpty == 1) ? 'checked' : '';
$optSoundsChecked = ($optSounds == 1) ? 'checked' : '';
$optLineNumsChecked = ($optLineNums == 1) ? 'checked' : '';
// Generate options for Width & Height Selection
$i = 10;
$widthOptions = '';
$heightOptions = '';
while ($i <= 100) {
if ($optWidth == "$i%") {
$widthOptions = "$widthOptions<OPTION selected>$i%</OPTION>";
} else {
$widthOptions = "$widthOptions<OPTION>$i%</OPTION>";
}
if ($optHeight == "$i%") {
$heightOptions = "$heightOptions<OPTION selected>$i%</OPTION>";
} else {
$heightOptions = "$heightOptions<OPTION>$i%</OPTION>";
}
$i = $i + 5;
}
Unset $i;
// Generate options for Skin / Theme Selection
$skinOptions = '';
foreach ($skin, 'Default|Desert|Sunburst|Sons-Of-Obsidian|Doxy') {
if ($skin) {
$selected = ($optSkin == $skin) ? ' selected' : '';
$skinOptions = $skinOptions . "<OPTION$selected>$skin</OPTION>";
}
}
Unset $skin, $selected;
$html = <<<#HEREDOC
<!DOCTYPE html>
<BODY>
<DIV align='right'>
<A href='javascript:document.getElementById("Options").scrollIntoView(true);'>
Options
</A>
</DIV>
$content
<HR />
<DIV id='Options'>
<H3>Options:</H3>
<SCRIPT type='text/javascript'>
function cbx(cb, ctrlID) {
document.getElementById(ctrlID).disabled = ! cb.checked;
}
function val() {
var f = document.getElementById('optWarnLimit');
var n = parseInt(f.value, 10);
if (isNaN(n) || n < 0) {
alert('The count of items must be a positive integer or zero.');
f.focus();
return false;
}
f.value = n;
f.disabled = false;
return true;
}
</SCRIPT>
<FORM method='GET' action='xys:' onsubmit='return val();'>
<LABEL for='optWarn'>
<INPUT id='optWarn' name='optWarn' type='checkbox' value='1'
onchange='cbx(this,"optWarnLimit");'
onclick='cbx(this,"optWarnLimit");'
$optWarnChecked>Show warning when previewing more than
<INPUT id='optWarnLimit' name='optWarnLimit' type='text' size='3'
value='$optWarnLimit' $optWarnLimitDisabled /> items.
</INPUT>
</LABEL>
<BR />
<LABEL for='optSkipEmpty'>
<INPUT id='optSkipEmpty' name='optSkipEmpty' type='checkbox' value='1'
$optSkipEmptyChecked>Skip showing empty previews.</INPUT>
</LABEL>
<BR />
<LABEL for='optSounds'>
<INPUT id='optSounds' name='optSounds' type='checkbox' value='1'
$optSoundsChecked>Play Sounds.</INPUT>
</LABEL>
<BR />
<LABEL for='optLineNums'
title='Disable this if the code does not display properly.'>
<INPUT id='optLineNums' name='optLineNums' type='checkbox' value='1'
title='Disable this if the code does not display properly.'
$optLineNumsChecked>Display line numbers.</INPUT>
</LABEL>
<BR />
<BR />
<LABEL for='optWidth'>Width: </LABEL>
<SELECT id='optWidth' name='optWidth'>$widthOptions</SELECT>
<LABEL for='optHeight'>Height: </LABEL>
<SELECT id='optHeight' name='optHeight'>$heightOptions</SELECT>
<BR /><BR />
<LABEL for='optSkin'>Theme: </LABEL>
<SELECT id='optSkin' name='optSkin'>$skinOptions</SELECT>
<BR /><BR />
<INPUT type='submit' value='Exit Preview & Save Settings' />
</FORM>
</DIV>
<SCRIPT src='https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?autoload=true&skin=$optSkinValue'></SCRIPT>
</BODY>
</HTML>
#HEREDOC;
Unset $content, $optWarnLimitDisabled, $optLineNumsChecked, $optWarnChecked,
$optSkipEmptyChecked, $optSoundsChecked, $widthOptions, $heightOptions,
$skinOptions, $optSkinValue;
Status 'Showing preview...',, 'progress';
// Generate the window caption.
if ($fileCount > 1) {
$caption = "Code Preview: $fileCount items.";
} else {
$caption = "Code Preview: $files";
}
Unset $fileCount, $files;
// Display preview(s).
if ($optSounds) { Sound 'SystemExclamation'; }
$res = HTML($html, $optWidth, $optHeight, $caption);
Unset $html, $caption;
// Update options...
if ($res) {
$res = SubStr($res, 1);
// Reset boolean options.
// When unchecked they won't be part of the form response,
// so assume they are disabled to begin with.
$optWarn = 0;
$optSkipEmpty = 0;
$optSounds = 0;
$optLineNums = 0;
foreach ($resOpt, $res, '&') {
if (! $resOpt) {
continue;
}
$resName = GetToken($resOpt, 1, '=', 't');
$resValue = GetToken($resOpt, 2, '=', 't');
$resValue = UrlDecode($resValue);
if ($resName LikeI 'optWarn' ) { $optWarn = $resValue; }
elseif ($resName LikeI 'optWarnLimit') { $optWarnLimit = $resValue; }
elseif ($resName LikeI 'optSkipEmpty') { $optSkipEmpty = $resValue; }
elseif ($resName LikeI 'optSounds' ) { $optSounds = $resValue; }
elseif ($resName LikeI 'optWidth' ) { $optWidth = $resValue; }
elseif ($resName LikeI 'optHeight' ) { $optHeight = $resValue; }
elseif ($resName LikeI 'optLineNums' ) { $optLineNums = $resValue; }
elseif ($resName LikeI 'optSkin' ) { $optSkin = $resValue; }
// else { Echo $resOpt; }
}
$G_OPTIONS = "$optWarn|$optWarnLimit|$optSkipEmpty|$optSounds";
$G_OPTIONS = "$G_OPTIONS|$optWidth|$optHeight|$optLineNums|$optSkin";
Sub('_setOptions');
}
Unset $res, $resOpt, $resName, $resValue, $G_OPTIONS;
Status 'Preview Complete!',, 'ready';
if ($optSounds) { Sound 'SystemExit'; }
Unset $optWarn, $optWarnLimit, $optSkipEmpty, $optSounds,
$optWidth, $optHeight, $optLineNums, $optSkin;
/************************************************************ END previewCode */
"- : _-" //---------------------------------------------------------------------
/*******************************************************************************
** Internal Variables
** For storing some information about this script.
*******************************************************************************/
"Internal Variables||4 : _aboutMe"
Global $G_AUTHOR = 'TheQwerty';
Global $G_VERSION = 1.0;
Global $G_DATE = '2013-03-25T19:00Z';
/*************************************************************** END _aboutMe */
XYplorer Beta Club