CodeBlock en Ubb classes
Auteur: Thomas - 27 december 2013 - 22:24 - Gekeurd door: UpLink - Hits: 4704 - Aantal punten: (0 stemmen)
Update 2014-10-07:
- breedtes compleet verwijderd uit classes, de code-wrapper div vult nu automatisch de maximale beschikbare breedte uit
Update 2014-09-16:
- horizontale scrollbalk nu alleen zichtbaar indien nodig
- hoogtes verwijderd uit template
- CSS aanpassingen
Noot 2014-03-05:
Let op bij het gebruik van de htmlspecialchars() aanroepen in de onderstaande code. Hier is geen encoding (3e parameter) opgegeven. Wellicht doe je er verstandig aan deze expliciet op te geven. Afhankelijk van je PHP versie kan de default waarde van deze parameter verschillen.
Korte uitleg
Dit script bevat twee classes en wat CSS code.
De CodeBlock class gebruik je om code af te drukken in een nette (div-)tabel compleet met regelnummers. Meestal is de breedte voor content op een webpagina beperkt. Deze class speelt hier op in: je kunt een vaste breedte instellen voor deze codeblokken.
De CSS code is bedoeld voor het opmaken van de codeblokken.
De Ubb class geeft een (voorbeeld)implementatie van UBB-functionaliteit met hierin ondersteuning voor CodeBlocks, maar je hoeft deze niet per sé te gebruiken - je kunt de CodeBlock class ook in afzondering gebruiken of combineren met je eigen UBB-functionaliteit. Ook kun je deze Ubb class uitbreiden door hier je eigen UBB-functionaliteit in op te nemen (op de daarvoor aangegeven plaats).
Installatie
Include de CodeBlock of beide classes in je code en zorg dat je de CSS laadt als je CodeBlock gebruikt.
Gebruik
Zie hieronder voor voorbeelden van gebruik. De code zelf is voorzien van redelijk wat commentaar (in het Engels).
|
Code: |
Class CodeBlock (heeft CSS nodig):
<?php
/*
* Class for printing code in a HTML formatted block, complete with line numbers.
* It is also suited to be included in other UBB-like functionality.
*/
class CodeBlock
{
protected $options;
protected $output;
public function __construct($text, $options=array()) {
// Set options; first overwrites second (the defaults).
$this->options = $options + self::getDefaultOptions();
// Do we still need to strip tags?
if (!$this->options['tags_stripped'] && ini_get('magic_quotes_gpc')) {
$returnText = stripslashes($text);
} else {
$returnText = $text;
}
// Convert any tabs to spaces.
$returnText = str_replace("\t", str_repeat(' ', $this->options['tabspaces']), $returnText);
// Convert all linebreaks to "\n".
$returnText = str_replace("\r\n", "\n", $returnText);
// Remove all whitespace characters from the end of each line, this will also trim empty lines.
$lines = explode("\n", $returnText);
$returnText = implode("\n", array_map('rtrim', $lines));
// Do we want to apply PHP code highlighting?
if ($this->options['highlight']) {
$returnText = @highlight_string($returnText, true); // suppress possible errors
// Clean up some of the HTML generated by highlight_string():
// Replace all <br /> tags with "\n" and fix the start and end of the returned HTML.
$returnText = str_replace(
array('<br />', '<code><span style="color: #000000">'."\n", '</span>'."\n".'</code>'),
array("\n", '<span style="color: #000000">', '</span>'),
$returnText
);
} else {
// Just neutralize everything.
$returnText = htmlspecialchars($returnText, ENT_QUOTES, 'UTF-8');
}
// Create the code block, starting with linenumbers.
$nrs = implode("\n", range(1, count($lines))); // seems faster than a for-loop, alternatively: use <br /> instead of \n for implosion
ob_start();
?><div class="code-wrapper">
<div class="index"><pre><?php echo $nrs ?></pre></div>
<div class="code"><pre><?php echo $returnText ?></pre></div>
</div><?php
$this->output = ob_get_clean();
} // __construct
public static function getDefaultOptions() {
return array(
'tabspaces' => 4, // number of spaces that tab-characters are replaced with
'highlight' => true, // whether to use the PHP function highlight_string() for highlighting code
// The next default should not be changed here unless you use the CodeBlock class directly,
// or when magic_quotes_gpc is on but you already stripped these extra slashes before you
// passed the input to this class.
'tags_stripped' => false, // keeps track of whether we already stripped tags for when magic_quotes_gpc is on
);
} // getDefaultOptions
public function getOutput() {
return $this->output;
} // getOutput
} // class
?>
<?php /* * Class for printing code in a HTML formatted block, complete with line numbers. * It is also suited to be included in other UBB-like functionality. */ class CodeBlock { protected $options; protected $output; public function __construct ($text, $options=array()) { // Set options; first overwrites second (the defaults). $this->options = $options + self::getDefaultOptions(); // Do we still need to strip tags? if (!$this->options['tags_stripped'] && ini_get('magic_quotes_gpc')) { } else { $returnText = $text; } // Convert any tabs to spaces. // Convert all linebreaks to "\n". // Remove all whitespace characters from the end of each line, this will also trim empty lines. $lines = explode("\n", $returnText); // Do we want to apply PHP code highlighting? if ($this->options['highlight']) { // Clean up some of the HTML generated by highlight_string(): // Replace all <br /> tags with "\n" and fix the start and end of the returned HTML. array('<br />', '<code><span style="color: #000000">'."\n", '</span>'."\n".'</code>'), array("\n", '<span style="color: #000000">', '</span>'), $returnText ); } else { // Just neutralize everything. } // Create the code block, starting with linenumbers. $nrs = implode("\n", range(1, count($lines))); // seems faster than a for-loop, alternatively: use <br /> instead of \n for implosion ?><div class="code-wrapper"> <div class="index"><pre> <?php echo $nrs ?></pre></div> <div class="code"><pre> <?php echo $returnText ?></pre></div> </div><?php } // __construct public static function getDefaultOptions () { 'tabspaces' => 4, // number of spaces that tab-characters are replaced with 'highlight' => true, // whether to use the PHP function highlight_string() for highlighting code // The next default should not be changed here unless you use the CodeBlock class directly, // or when magic_quotes_gpc is on but you already stripped these extra slashes before you // passed the input to this class. 'tags_stripped' => false, // keeps track of whether we already stripped tags for when magic_quotes_gpc is on ); } // getDefaultOptions public function getOutput() { return $this->output; } // getOutput } // class ?>
Bijbehorende CSS:
@CHARSET "UTF-8";
div.code-wrapper { display: block; margin: 0; padding: 0; border: 1px solid #cccccc; background-color: #eeeeee; position: relative; overflow-x: auto; overflow-y: hidden; }
div.code-wrapper pre { font-family: monospace; font-size: 13px; margin: 0; padding: 2px 5px; border: 0; line-height: 15px; }
div.code-wrapper div { margin: 0; padding: 0; border: 0; }
div.code-wrapper div.index { display: block; width: 40px; text-align: right; background-color: #cccccc; color: #333333; }
div.code-wrapper div.code { display: block; position: absolute; top: 0px; left: 40px; color: #000000; }
@CHARSET "UTF-8"; div.code-wrapper { display: block; margin: 0; padding: 0; border: 1px solid #cccccc; background-color: #eeeeee; position: relative; overflow-x: auto; overflow-y: hidden; } div.code-wrapper pre { font-family: monospace; font-size: 13px; margin: 0; padding: 2px 5px; border: 0; line-height: 15px; } div.code-wrapper div { margin: 0; padding: 0; border: 0; } div.code-wrapper div.index { display: block; width: 40px; text-align: right; background-color: #cccccc; color: #333333; } div.code-wrapper div.code { display: block; position: absolute; top: 0px; left: 40px; color: #000000; }
Class Ubb:
<?php
/*
* Class for formatting output, codeblocks can be picked up as well.
*/
class Ubb
{
protected $options;
protected $output;
protected $codeBlocks; // stack (array) of CodeBlock objects
protected $tag; // shorthand for $this->options['code_block_tag'], used for delimiting blocks of code
public function __construct($text, $options=array()) {
$this->codeBlocks = array();
$this->options = $options + array(
'allow_html' => false, // allow HTML outside code blocks? be VERY careful with this
'use_code_block' => true, // use CodeBlock class for formatting blocks of code?
'code_block_tag' => 'code', // name of the UBB-tag for delimiting blocks of code, it will also enable us to print this code using this class :)
'code_block_options' => array(), // styling options for code blocks, see CodeBlock::getDefaultOptions()
);
$this->options['code_block_options'] = $this->options['code_block_options'] + CodeBlock::getDefaultOptions();
$this->tag = $this->options['code_block_tag'];
// Strip slashes if magic_quotes_gpc is on.
if (ini_get('magic_quotes_gpc')) {
$returnText = stripslashes($text);
} else {
$returnText = $text;
}
// We stripped tags; do not strip them again in CodeBlock calls.
$this->options['code_block_options']['tags_stripped'] = true;
if ($this->options['use_code_block']) {
// Backup code blocks, it needs separate treatment from the rest of the UBB-code).
// preg_replace() will become deprecated in PHP 5.5.0, we use preg_replace_callback instead.
$returnText = preg_replace_callback(
'#\['.$this->tag.'](.*)\[/'.$this->tag.']#sU',
array($this, 'backupCodeBlock'),
$returnText
);
}
// Perform the rest of the UBB formatting, starting with (dis)allowing HTML.
if ($this->options['allow_html'] == false) {
// No HTML allowed, neutralize all HTML and convert newline characters to linebreak-tags.
$returnText = nl2br(htmlspecialchars($returnText, ENT_QUOTES, 'UTF-8'));
if ($this->options['use_code_block']) {
// Some extra styling: remove the <br /> after the closing tag of a code block.
$returnText = str_replace('[/'.$this->tag.']<br />', '[/'.$this->tag.']', $returnText);
}
} // allow_html false
// Put the rest, if any, of your own UBB-styling here.
if ($this->options['use_code_block']) {
// Restore code blocks.
$returnText = preg_replace_callback(
'#\['.$this->tag.'](\d+)\[/'.$this->tag.']#sU',
array($this, 'restoreCodeBlock'),
$returnText
);
}
// Store the processed input in $this->output.
$this->output = $returnText;
} // __construct
// Callback function for storing blocks of code.
protected function backupCodeBlock($matches) {
$currentBlock = count($this->codeBlocks);
$this->codeBlocks[$currentBlock] = new CodeBlock(
// Note: strip backslash from escaped double quotes due to /e-switch is no longer necessary
// because we do not use preg_match anymore.
$matches[1],
$this->options['code_block_options']
);
// Return a HTML-safe placeholder to indicate where the codeblock should be placed back after
// processing the rest of the UBB-code.
return '['.$this->tag.']'.$currentBlock.'[/'.$this->tag.']';
} // backupCodeBlock
// Callback function for restoring code blocks after the rest of the UBB-code is applied.
protected function restoreCodeBlock($matches) {
return $this->codeBlocks[$matches[1]]->getOutput();
} // restoreCodeBlock
public function getOutput() {
return $this->output;
}
} // class
?>
<?php /* * Class for formatting output, codeblocks can be picked up as well. */ class Ubb { protected $options; protected $output; protected $codeBlocks; // stack (array) of CodeBlock objects protected $tag; // shorthand for $this->options['code_block_tag'], used for delimiting blocks of code public function __construct ($text, $options=array()) { $this->codeBlocks = array(); $this->options = $options + array( 'allow_html' => false, // allow HTML outside code blocks? be VERY careful with this 'use_code_block' => true, // use CodeBlock class for formatting blocks of code? 'code_block_tag' => 'code', // name of the UBB-tag for delimiting blocks of code, it will also enable us to print this code using this class :) 'code_block_options' => array(), // styling options for code blocks, see CodeBlock::getDefaultOptions() ); $this->options['code_block_options'] = $this->options['code_block_options'] + CodeBlock::getDefaultOptions(); $this->tag = $this->options['code_block_tag']; // Strip slashes if magic_quotes_gpc is on. } else { $returnText = $text; } // We stripped tags; do not strip them again in CodeBlock calls. $this->options['code_block_options']['tags_stripped'] = true; if ($this->options['use_code_block']) { // Backup code blocks, it needs separate treatment from the rest of the UBB-code). // preg_replace() will become deprecated in PHP 5.5.0, we use preg_replace_callback instead. '#\['.$this->tag.'](.*)\[/'.$this->tag.']#sU', array($this, 'backupCodeBlock'), $returnText ); } // Perform the rest of the UBB formatting, starting with (dis)allowing HTML. if ($this->options['allow_html'] == false) { // No HTML allowed, neutralize all HTML and convert newline characters to linebreak-tags. if ($this->options['use_code_block']) { // Some extra styling: remove the <br /> after the closing tag of a code block. $returnText = str_replace('[/'.$this->tag.']<br />', '[/'.$this->tag.']', $returnText); } } // allow_html false // Put the rest, if any, of your own UBB-styling here. if ($this->options['use_code_block']) { // Restore code blocks. '#\['.$this->tag.'](\d+)\[/'.$this->tag.']#sU', array($this, 'restoreCodeBlock'), $returnText ); } // Store the processed input in $this->output. $this->output = $returnText; } // __construct // Callback function for storing blocks of code. protected function backupCodeBlock($matches) { $currentBlock = count($this->codeBlocks); $this->codeBlocks[$currentBlock] = new CodeBlock( // Note: strip backslash from escaped double quotes due to /e-switch is no longer necessary // because we do not use preg_match anymore. $matches[1], $this->options['code_block_options'] ); // Return a HTML-safe placeholder to indicate where the codeblock should be placed back after // processing the rest of the UBB-code. return '['.$this->tag.']'.$currentBlock.'[/'.$this->tag.']'; } // backupCodeBlock // Callback function for restoring code blocks after the rest of the UBB-code is applied. protected function restoreCodeBlock($matches) { return $this->codeBlocks[$matches[1]]->getOutput(); } // restoreCodeBlock public function getOutput() { return $this->output; } } // class ?>
Gebruik:
Voor het afdrukken van één groot codeblock:
<?php
// creeer een CodeBlock object
$code = new CodeBlock('je_code_hier');
// afdrukken!
echo $code->getOutput();
?>
<?php // creeer een CodeBlock object $code = new CodeBlock('je_code_hier'); // afdrukken! ?>
Voor het adrukken van een UBB-tekst met hierin codeblokken:
<?php
// creeer een Ubb object
$ubb = new Ubb('je_tekst_met_codeblokken_hier');
// afdrukken!
echo $ubb->getOutput();
?>
<?php // creeer een Ubb object $ubb = new Ubb('je_tekst_met_codeblokken_hier'); // afdrukken! ?>
Je kunt ook een aantal opties meegeven (in zowel CodeBlock als Ubb), bijvoorbeeld je staat HTML toe (buiten codeblokken), je wilt geen highlight_string gebruiken voor PHP-code:
<?php
// aanmaken en instellen
$ubb = new Ubb('je_tekst_met_codeblokken_hier', array(
'allow_html' => true,
'code_block_options' => array(
'highlight' => false,
),
));
// afdrukken
echo $ubb->getOutput();
?>
<?php // aanmaken en instellen $ubb = new Ubb ('je_tekst_met_codeblokken_hier', array( 'allow_html' => true, 'code_block_options' => array( 'highlight' => false, ), )); // afdrukken ?>
Download code (.txt)
|
|
Stemmen |
Niet ingelogd. |
|