I will outline the steps I use to create, display, and store, formatted programming code. Partly because I couldn't find such a summary myself, and partly because I'm quite pleased with my results.
It should be viewed as just an outline of the process, as there are details which will need to be filled in. In particular, creating a database, and creating the full HTML-output of, perhaps, a table to display the code aren't detailed in full.
A textarea (with name and id of
txtCode) within a form is used to enter the code. The only requirement is that
four spaces are used to provide the code's indenting. When the form is submitted I would normally trim data, but I only rtrim the code/textarea, as I need to preserve the spaces on the left.
[Note that sequences of spaces that are not at the beginning of the line will collapse to a single space. This could be resolved with a little effort, but I'm not too concerned about this for this demonstration. Added: simply replacing any other spaces with & nbsp; should fix this.]
PHP Code:
$trimmed_code = rtrim($_POST['txtCode']); // ..then escape for database insertion
$esc_code = mysqli_real_escape_string($dbc, $trimmed_code);
When I retrieve the data from the database I will display the code (having field-name '
code') in a table-row. However, I display it twice (two rows): once as plain text (with
display:none for the row), and once as formatted-code. This is not essential, but doing so allows me to add an Edit button to the table that will grab the (hidden) code and place it back into my form for editing. [It would be more complicated to convert the formatted code back to plain text, suitable for the textarea.]
PHP Code:
$rowh['code'] = htmlentities($row['code'], ENT_QUOTES); // for the hidden row
$html_code = nl2br($rowh['code']); // for formatted output
The following is the
css for the formatted-code. It is contained in a div with the class "
blogcode", and uses an ordered list (ol/li):
Code:
.blogcode {
margin: 10px 5px 20px 5px; padding: 0 0 0 8px;
background-color: #F6F3F3;
font-family: Consolas, 'Courier New', monospace;
font-size: smaller; color: green;
}
.blogcode ol {
list-style-position: outside;
margin: 0; padding: 0 0 0 30px;
}
.blogcode li {
padding: 3px 5px; margin: 0;
border-left: thin solid green;
}
.blogcode ol li:nth-child(odd) { background: white; }
/* nth-child doesn't work in some older browsers. */
.blogcode li.tab0 { padding-left: 5px; }
.blogcode li.tab1 { padding-left: 35px; }
.blogcode li.tab2 { padding-left: 65px; }
.blogcode li.tab3 { padding-left: 95px; }
.blogcode li.tab4 { padding-left: 125px; }
.blogcode li.tab5 { padding-left: 155px; }
.blogcode li.tab6 { padding-left: 185px; }
.blogcode li.tab7 { padding-left: 215px; }
.blogcode li.tab8 { padding-left: 245px; }
.blogcode li.tab9 { padding-left: 275px; }
I am using padding-left to indent it correctly, and will count the number of spaces (on the left) to determine which class to apply to the li's (tab0, tab1, etc.).
PHP Code:
// Having initiated an HTML-table..
// ..for each row fetched from the database
echo "<tr class=\"coded\"><td>$html_code</td></tr>";
echo "<tr class=\"thecode\"><td>";
if (!empty($html_code)) {
echo "<div class=\"blogcode\">";
echo "<ol start=\"1\">";
$html_lines = '';
$code_lines = explode("\n", $rowh['code']);
foreach ($code_lines as $line) {
// work out how many 'tabs' are needed (which class to use)
$count_fours = strlen($line) - strlen(ltrim($line, ' '));
$count_fours = ceil($count_fours / 4); // round up
$line = codeWords($line); // blue keywords (optional)
$html_lines .= "<li class=\"tab$count_fours\">$line</li>";
}
echo $html_lines;
echo "</ol></div>";
}
echo "</td></tr>";
// repeat for the next database row.
The above code optionally uses a PHP function named codeWords (shown below) which allows me to colour-code certain keywords - I use blue text
PHP Code:
// PHP function(s) to colour-code (blue) certain keywords.
function onlyWholeWords(&$value, $key) {
// Used by the following codeWords() function.
// Picks out whole-keywords, but NOT after // comment delimiters.
//$value = "/\b(" . $value . ")\b/";
$value = "/^(?:(?!\/\/).)*\K\b(" . $value . ")\b/";
}
function codeWords($code) {
// This could be adapted to handle different colours and
// programming languages.
$words = array('break', 'case', 'class', 'continue', 'default', 'do', 'elif',
'else', 'for', 'function', 'if',
'new', 'null', 'return', 'self', 'switch', 'this', 'typeof',
'var', 'void', 'while', 'with');
array_walk($words, 'onlyWholeWords');
$code = preg_replace($words, "<span style='color:blue'>$1</span>", $code);
return $code;
}
Additionally, I have an Edit button next to the code in the table. I use jQuery to grab text from the (hidden) code-row and place it in the form/textarea. This is easier to achieve if I've already given the td (that contains the hidden code) an id of 'bgCode1', 'bgCode2', etc. (I do this as I initially construct the table with PHP.)
Code:
// jQuery to grab the code from the table and insert it into the forms' textarea.
var code_text = $('#bgCode' + bID).text();
$('#txtCode').val(code_text); // 'txtCode' is the id of the textarea for the code
I welcome any feedback, comments or suggestions - although "I already know" that there are plug-ins, frameworks, etc., that can be used to achieve this: they are not as rewarding as doing it oneself!