Skip to content

Instantly share code, notes, and snippets.

@ckunte
Last active September 29, 2017 09:11
Show Gist options
  • Save ckunte/1bb616b89873a1f50cd5 to your computer and use it in GitHub Desktop.
Save ckunte/1bb616b89873a1f50cd5 to your computer and use it in GitHub Desktop.
Code transform (WordPress plugin)
<?php
/*
Plugin Name: Code transform
Plugin URI:
Description: Based on <a href="http://1976design.com/blog/archive/2004/07/29/redesign-tag-transform/">Dunstan Orchard's tag transformations</a>, this plugin now can pull and list code snippets from flat .txt files. The plugin code is based on <a href="http://mathiasbynens.be/archive/2005/06/tag-transformations">Mathias Bynens</a>. Syntax in the post: <code>&lt;codeins="filename" /&gt;</code>. Filename to be without the extension, e.g. if the filename is <code>test.txt</code>, then the code becomes <code>&lt;codeins="test" /&gt;</code>.
Version: 1.0
Author: ckunte
Author URI: http://ckunte.net/
*/
$dir = ABSPATH; // trailing slashed path to your WordPress installation
$iri = get_settings('siteurl') . '/';
/*
Code files should go in http://yoursite.com/path/to/wordpress/code/
ex. http://yoursite.com/blog/code/123a.txt
<codeins="123a" />
*/
// this function is used to find the last occurance of a string within another string
// it's used because strrpos() only looks for a single character, not a string
function strLastPos($haystack, $needle) {
// flip both strings around and search, then adjust position based on string lengths
return strlen($haystack) - strlen($needle) - strpos(strrev($haystack), strrev($needle));
}
function mj_code_transform($filename) {
global $dir, $iri;
$filename = 'inputfiles/' . $filename . '.txt';
// set vars
$list = '';
$cmnt = '';
$multi_line_cmnt = 0;
$tab = '';
$class = '';
// open the file
$file = fopen($dir . $filename, 'r')
or die('<p><strong>Error:</strong> No such file found! Please make sure <code>' . $iri . $filename . '</code> exists.</p>');
// for each line in the file
while (!feof($file)) {
// get line
$line = fgets($file, 4096);
// convert tags to safe entities for display
$line = htmlentities($line);
// count the number of tabs at the start of the line, and set the appropriate tab class
$tab = substr_count($line, "\t");
$tab = ($tab > 0) ? 'tab' . $tab : '';
// remove any tabs and whitespace at the start of the line
$line = ltrim($line);
// find position of comment characters
$slashslash_pos = strpos($line, '//');
$apos_pos = strpos($line, "'");
$slashstar_pos = strpos($line, '/*');
$starslash_pos = strLastPos($line, '*/');
// if it's an ongoing multi-line comment
if ($multi_line_cmnt == 1) {
$cmnt = 'cmnt';
$multi_line_cmnt = 1;
}
// if it's not an ongoing multi-line comment
if ($multi_line_cmnt <> 1) {
// if it's a single line comment
if (($slashslash_pos === 0) || ($apos_pos === 0)) {
$cmnt = 'cmnt';
$multi_line_cmnt = 0;
}
else {
$cmnt = '';
$multi_line_cmnt = 0;
}
// if it's potentially the start of a multi-line comment
if ($slashstar_pos === 0) {
$cmnt = 'cmnt';
// if multi-line comment end string is found on the same line
if ($starslash_pos == (strlen($line) - 3)) {
$multi_line_cmnt = 0;
}
// if the multi-line comment end string is not found on the same line
else {
$multi_line_cmnt = 1;
}
}
}
// if the line contains the multi-line end string
if ($starslash_pos == (strlen($line) - 3)) {
$cmnt = 'cmnt';
$multi_line_cmnt = 0;
}
// if both cmnt and tab classes are to be applied
if ( ($cmnt <> '') && ($tab <> '') ) {
$class = ' class="' . $tab . ' ' . $cmnt . '"';
}
// if only one class is to be applied
else if ( ($cmnt <> '') || ($tab <> '') ) {
$class = ' class="' . $tab . $cmnt . '"';
}
// if no classes are to be applied
else {
$class = '';
}
// remove return and other whitespace at the end of the line
$line = rtrim($line);
// if the line is blank, put a space in to stop some browsers collapsing the line
if ('' == $line) {
// insert all the information and close the list item
$list .= '<li>&#160;</li>' . "\n";
}
// otherwise insert the line contents
else {
// insert all the information and close the list item
$list .= '<li' . $class . '><code>' . ent2ncr($line) . '</code></li>' . "\n";
}
}
// close the file handle
fclose($file);
// add in the link to the file
$list .= '<li class="download">Download this example: <a href="' . $iri . $filename . '" title="Download the above code as a text file">/' . $filename . '</a></li>';
// build the list
$list = '<ol class="code">' . "\n" . $list . "\n" . '</ol>';
// return the list
return $list;
}
function mj_addtags($content) {
$content = preg_replace('!<codeins="(.*?)" />!ie', "mj_code_transform('$1')", $content);
return $content;
}
remove_filter('the_content', 'wpautop'); // must... remove... first
remove_filter('the_excerpt', 'wpautop');
add_filter('the_content', 'mj_addtags', 10);
add_filter('the_excerpt', 'mj_addtags', 10);
add_filter('the_content', 'wpautop', 11); // then bring it back
add_filter('the_excerpt', 'wpautop', 11);
?>
/* CSS for styling code examples */
/* Credits:
Dunstan Orchard
http://1976design.com/blog/code/456d.txt
*/
ol.code {
border: 1px solid #eee;
color: #333;
font: normal 98%/110% Courier, monospace;
margin: 0;
overflow: auto;
padding: 5px 5px 5px 45px;
}
ol.code li {
background-color: #f4f8fb;
margin: 0;
padding: 0 5px;
}
ol.code li.source {
background-color: #fff;
list-style-type: none;
padding: 5px;
text-align: center;
}
ol.code li+li {
margin-top: 2px;
}
ol.code li.tab1 {padding-left: 15px;}
ol.code li.tab2 {padding-left: 30px;}
ol.code li.tab3 {padding-left: 45px;}
ol.code li.tab4 {padding-left: 60px;}
ol.code li.tab5 {padding-left: 75px;}
ol.code li.tab6 {padding-left: 90px;}
ol.code li code {
color: #333;
}
ol.code li.cmnt code {
color: #824c88;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment