21

21Displaying code fragmentse

21.5

Code fragment enhancements

I expect you’ve had enough of code fragments, this is the last bit.

21.5.1

Colouring particular lines in a code fragment

If you look at all the code fragments within this document, several have green lines to show where I’ve made some modification or other, and I want this facility on the website. Look at the following code fragment (from 99-00-typicals):

html
<nav>                            <!-- TOP NAVIGATION BAR -->
    <div class="top-nav">
        <div class="rg-row">
            <a class="nav-wide" href="#"><span class="top-nav-icon">l</span><span class="top-nav-text">Prev. section</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-icon">u</span><span class="top-nav-text">Prev. chapter</span></a>
            <a class="nav-wide nav-home" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-narrow js--sc-top" href="#"><span class="top-nav-icon">t</span><span class="top-nav-text">Top</span></a>
            <a class="nav-narrow" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next chapter</span><span class="top-nav-icon">d</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next section</span><span class="top-nav-icon">r</span></a>
        </div>
    </div>
</nav>                            <!-- END OF TOP NAVIGATION -->
Code 99.1   Code Fragment — html extract

I do this by having a specific CSS file for each page with code fragments; it is called cc-ss-codelines.css and it live in the 01-pages/cc-ss-pagename/01-local-css directory. In this case it is 01-pages/99-00-typicals/01-local-css/99-00-codeline.css (where cc and ss are the chapter and sections numbers for the web page).

Create the file cc-ss-codelines.css in the correct directory 01-pages/cc-ss-pagename/01-local-css but leave it empty.

The file is loaded in the <head> area of the page:

codelines.css file load html
<!-- **************************************************************************
     HEAD CSS LOAD
     ***********************************************************************-->
<link rel="stylesheet" type="text/css" href="21-global/03-fonts/ps-fonts.css">
<link rel="stylesheet" type="text/css" href="21-global/01-css/normalise.css">
<link rel="stylesheet" type="text/css" href="21-global/01-css/lightbox.css">
<link rel="stylesheet" type="text/css" href="11-resources/01-css/grid.css">
<link rel="stylesheet" type="text/css" href="11-resources/01-css/style.css">
<link rel="stylesheet" type="text/css" href="01-pages/99-00-typicals/01-local-css/99-00-codelines.css">
Code 21.16   Loading the codeline.css file

So how to colour the lines?

Look at the HTML for the code fragment (it’s the same code we used in the previous sections):

Standard code fragment HTML
<div class="code-extract">                          <!-- Start of code fragment -->
    <div class="code-header">html</div>             <!-- Code file name -->
    <div class="code-area">                         <!-- Start of code extract holder -->
        <pre class="prettyprint linenums lang-html" id="js--c99-01">
&lt;nav&gt;                            &lt;!-- TOP NAVIGATION BAR --&gt;
    &lt;div class="top-nav"&gt;
        &lt;div class="rg-row"&gt;
            &lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;l&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. section&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;u&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. chapter&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-wide nav-home" href="#"&gt;&lt;span class="top-nav-text"&gt;Home&lt;/span&gt;&lt;span class="top-nav-icon"&gt;h&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-narrow js--sc-top" href="#"&gt;&lt;span class="top-nav-icon"&gt;t&lt;/span&gt;&lt;span class="top-nav-text"&gt;Top&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-narrow" href="#"&gt;&lt;span class="top-nav-text"&gt;Home&lt;/span&gt;&lt;span class="top-nav-icon"&gt;h&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-text"&gt;Next chapter&lt;/span&gt;&lt;span class="top-nav-icon"&gt;d&lt;/span&gt;&lt;/a&gt;
            &lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-text"&gt;Next section&lt;/span&gt;&lt;span class="top-nav-icon"&gt;r&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/nav&gt;                            &lt;!-- END OF TOP NAVIGATION --&gt;
        </pre>
    </div>                                              <!-- End of code extract holder -->
    <div class="code-caption">Code 99.1 &emsp; Code Fragment &mdash; html extract</div>
</div>                                              <!-- End of code fragment -->
Code 21.17   Standard code fragment HTML

As it stands it looks like this:

html
<nav>                            <!-- TOP NAVIGATION BAR -->
    <div class="top-nav">
        <div class="rg-row">
            <a class="nav-wide" href="#"><span class="top-nav-icon">l</span><span class="top-nav-text">Prev. section</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-icon">u</span><span class="top-nav-text">Prev. chapter</span></a>
            <a class="nav-wide nav-home" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-narrow js--sc-top" href="#"><span class="top-nav-icon">t</span><span class="top-nav-text">Top</span></a>
            <a class="nav-narrow" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next chapter</span><span class="top-nav-icon">d</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next section</span><span class="top-nav-icon">r</span></a>
        </div>
    </div>
</nav>                            <!-- END OF TOP NAVIGATION -->
Code 99.1   Code Fragment — html extract

Exactly what you would expect, no line colouring. This is because although I’ve loaded the codelines.css file, it is empty and doesn’t do anything.

To add the artificial line colouring, we are going to change things in the codelines.css file. But before we do, just look at the <pre> element again for this code fragment:

        <pre class="prettyprint linenums lang-html" id="js--c99-01"> 

I’ve given the code fragment an ID, in this case js--c99-01; this is similar to what we did with tables and figures (and sections &c.), it is used for slow scrolling, see Table 17.1.

However, because the code fragment has a unique ID, it means I can modify it with some CSS.

Open codelines.css in Brackets.

You are going to be surprised by just how easy this is.

Add the following code

html
/* ******************************************************************
   CODE FRAGMENT c99-01 - FORMATTING
   *************************************************************** */
#js--c99-01 li:nth-child(2) { background: #EAF1DD }
/* *************************************************************** */
Code 21.18   Codelines CSS

Now look at the result:

html
<nav>                            <!-- TOP NAVIGATION BAR -->
    <div class="top-nav">
        <div class="rg-row">
            <a class="nav-wide" href="#"><span class="top-nav-icon">l</span><span class="top-nav-text">Prev. section</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-icon">u</span><span class="top-nav-text">Prev. chapter</span></a>
            <a class="nav-wide nav-home" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-narrow js--sc-top" href="#"><span class="top-nav-icon">t</span><span class="top-nav-text">Top</span></a>
            <a class="nav-narrow" href="#"><span class="top-nav-text">Home</span><span class="top-nav-icon">h</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next chapter</span><span class="top-nav-icon">d</span></a>
            <a class="nav-wide" href="#"><span class="top-nav-text">Next section</span><span class="top-nav-icon">r</span></a>
        </div>
    </div>
</nav>                            <!-- END OF TOP NAVIGATION -->
Code 99.1   Code Fragment — html extract

Line 2 has gone green. Why?

Look at the CSS:

js--c99-01 li:nth-child(2) { background: #EAF1DD }

This is one of those nth-child pseudo elements we looked at way back in section § 8.3.4 (when I was a golden-haired stripling, not the silver-haired dotard I am now); it allows us to identify a particular occurrence of some element.

In this case I’m looking for the second occurrence — nth-child(2) — of the li element in something with the ID js--c99-01; that something is our code fragment, and since I’ve got line numbers active, each line of the code is within its own li element, I just picked the 2nd one and made it go green (background: #EAF1DD).

If I wanted the fourth line to go green too, I add another line to codelines.css.

#js--c99-01 li:nth-child(2) { background: #EAF1DD }
#js--c99-01 li:nth-child(4) { background: #EAF1DD }

If I wanted line 1 and then every line between line 5 and line 10, the CSS would be:

#js--c99-01 li:nth-child(2) { background: #EAF1DD }
#js--c99-01 li:nth-child(n+5):nth-child(-n+10) { background: #EAF1DD }

Where nth-child(n+5):nth-child(-n+10) is the shorthand for line 5 to line 10 (I refer you to § 8.3.4 for the selection options).

  • If you use false numbering, the nth-child(n) still starts at 1, if you applied the class linenums:25 to start the numbering at 25, the first line in the code fragment would be nth-child(1) as far as the CSS in codeline is concerned.

Artificial line colouring only works with numbered code fragments, if there is no linenums class in the <pre> element it won’t work, there will be no ordered list.

If you still want coloured lines but no line numbers, there is a bit of messing about, in the first instance line numbers must be turned on by adding the linenums class to the <pre> element; the next thing is to make those numbers invisible by adding the following to the odelines.css:

#js--c99-01 ol.linenums {color: transparent;}

This makes the numbers transparent and stops them being displayed.

21.5.2

Fixing problems with line wrap for indented sections

I was a bit glib in § 21.4.2 when I talked about wrapping text in a code fragment, the code was like this:

code fragment html
<div class="code-extract">                          <!-- Start of code fragment -->
    <div class="code-header">filename.ext</div>     <!-- Code file name -->
    <div class="code-area">                         <!-- Start of code extract holder -->
       <pre class="prettyprint linenums wrap lang-html" id="js--c99-03">
&lt;nav&gt;                            &lt;!-- TOP NAVIGATION BAR --&gt;
    &lt;div class="top-nav"&gt;
        &lt;div class="rg-row"&gt;
&lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;l&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. section&lt;/span&gt;&lt;/a&gt;
&lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;u&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. chapter&lt;/span&gt;&lt;/a&gt;
    &lt;/div&gt;
&lt;/nav&gt;                            &lt;!-- END OF TOP NAVIGATION --&gt;
        </pre>
    </div>                                          <!-- End of code extract holder -->
    <div class="code-caption">Code 99.3 &emsp; Caption</div>  <!-- Code caption -->
</div>                                              <!-- End of code fragment -->
Code 21.19   HTML code fragment — line numbers and text wrap

I’ve shortened it to just have two nav-wide anchor elements and I’ve given it the ID js--c9903. It looks like this in a browser:

Figure 21.35 - Unadjusted indented and wrapped text
Figure 21.35   Unadjusted indented and wrapped text

It doesn’t look right, those two anchor lines have wrapped (they occupy two lines each) and the numbering is right (it doesn’t number the wrapped bits), but the indentation is all screwed up.

The first bit works, the <a on lines 4 and 5 is indented to the correct position, but the wrapped bit just starts at the beginning of the line (it is not, in typographical terms, what one would call a hanging indent).

To get around this we have to do a bit of fucking about. The first thing is to take the leading spaces out of the lines that wrap:

<div class="code-extract">                          <!-- Start of code fragment -->
    <div class="code-header">filename.ext</div>     <!-- Code file name -->
    <div class="code-area">                         <!-- Start of code extract holder -->
        <pre class="prettyprint lang-html wrap" id="js--c9903">
&lt;nav&gt;                            &lt;!-- TOP NAVIGATION BAR --&gt;
    &lt;div class="top-nav"&gt;
        &lt;div class="rg-row"&gt;
&lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;l&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. section&lt;/span&gt;&lt;/a&gt;
&lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;u&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. chapter&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/nav&gt;                            &lt;!-- END OF TOP NAVIGATION --&gt;
        </pre>
    </div>                                          <!-- End of code extract holder -->
    <div class="code-caption">Code 99.3 &emsp; Caption</div>  <!-- Code caption -->
</div>                                              <!-- End of code fragment -->

To make it clearer, I’ve shown the original and modified version of the first line below:

            &lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;l&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. section&lt;/span&gt;&lt;/a&gt;
&lt;a class="nav-wide" href="#"&gt;&lt;span class="top-nav-icon"&gt;l&lt;/span&gt;&lt;span class="top-nav-text"&gt;Prev. section&lt;/span&gt;&lt;/a&gt;

In the second version, the &lt; is up against the left edge.

It looks like this now:

Figure 21.36 - Wrapped text with leading spaces removed
Figure 21.36   Wrapped text with leading spaces removed

You might think this is worse, now there is no indentation at all. It does look worse, but at least everything matches.

The next bit is in codelines.css, this table has the ID js--c9903, so we can do things to it. Add the following to codelines.css:

/* *******************************************************************
   CODE FRAGMENT c9903 - FORMATTING
   *************************************************************** */
#js—-c9903 li:nth-child(4) {padding-left: 4.4rem;}
#js—-c9903 li:nth-child(5) {padding-left: 4.4rem;}
/* *************************************************************** */

This puts the padding back in for those two lines; it looks like this:

Figure 21.37 - Wrapped text with leading spaces removed
Figure 21.37   Wrapped text with leading spaces removed

It gets there in the end.

The problem with this is that each indentation level needs to be coded individually, padding of 4.4rems won’t be right for the next indentation level.

I realise that this is a pain in the arse, but I can’t think of another solution.



End flourish image