Skip to main content
\(\require{cancel}\newcommand{\definiteintegral}[4]{\int_{#1}^{#2}\,#3\,d#4} \newcommand{\myequation}[2]{#1\amp =#2} \newcommand{\indefiniteintegral}[2]{\int#1\,d#2} \newcommand{\testingescapedpercent}{ \% } \newcommand{\lt}{<} \newcommand{\gt}{>} \newcommand{\amp}{&} \)

Section20Program Listings

Sage cells can be used for Python examples, but Sage uses a mild amount of pre-parsing, so that might not be a wise decision, especially in instructional settings. We might implement Skulpt or Brython (in-browser Python) or the Python language argument to the Sage Cell Server. To see examples of authoring Sage cells, have a look at Section 3.

In the meantime, program listings, especially with syntax highlighting, is useful all by itself. The “R” language might not be a bad stand-in for pseudo-code, as it supports assignment with a left arrow and has fairly generic procedural syntax for control structures and data structures. Or maybe Pascal would be a good choice? Here is an example of R. Note in the source that the entire block of code is wrapped in a CDATA section due to the four left angle brackets. We do not recommend this technique for isolated problem characters, but it is a life-saver for situations like the XSLT code just following.

n_loops <- 10
x.means <- numeric(n_loops)  # create a vector of zeros for results
for (i in 1:n_loops){
    x <- as.integer(runif(100, 1, 7))  # 1 to 6, uniformly
    x.means[i] <- mean(x)
}
x.means

And some self-referential XSL:

<xsl:template match="biblio" mode="number">
    <xsl:apply-templates select="." mode="structural-number" />
    <xsl:text>.</xsl:text>
    <xsl:number from="references" level="any" count="biblio" />
</xsl:template>

You can write made-up pseudo-code and get reasonable syntax highlighting, but you might explain to a reader what your symbols all mean. This routine takes the \(m\times n\) marix \(A\) to reduced row-echelon form. Note in the source the use of escaped characters for the four angle brackets.

input m, n and A
r := 0
for j := 1 to n
   i := r+1
   while i <= m and A[i,j] == 0
       i := i+1
   if i < m+1
       r := r+1
       swap rows i and r of A (row op 1)
       scale A[r,j] to a leading 1 (row op 2)
       for k := 1 to m, k <> r
           make A[k,j] zero (row op 3, employing row r)
output r and A

Look in the mathbook-common.xsl file to see the strings to use to identify languages. Always all-lowercase, no symbols, no punctuation.

Note that the above examples all have slightly different widths (theser are very evident in print with the frames). As 2-D atomic objects, to place them in the narrative requires the layout features of a sidebyside element. Then width and/or margin attributes will influence the width of the panel.

A program may also be nested inside a listing, which behaves similar to a figure. You can provide a caption, and the listing will be numbered along with tables and figures. This then makes it possible to cross-reference the listing, such as Listing 20.1. It also removes the requirement of wrapping the program in a sidebyside. For technical reasons, the three examples above will not split across a page break in PDF output, but the placement inside a listing will allow splits, as you should see in at least one example following.

/* Hello World program */

#include<stdio.h>

main()
{
    printf("Hello, World!");
}
Listing20.1C Version of “Hello, World!”

If you are discussing algorithms in the abstract (or even concretely), you can set them off like a theorem, with a number, a title and a target for cross-references. Sometimes you claim an algorithm produces something in particular, or has certain properties, such as a theoretical run time, so a proof may be included. See the discussion just preceding about (limited) options for pseudo-code.

If you are writing about system-level software, you may need to write numbers in hexadecimal or binary. Here we use a numbered, displayed equation (mathematics) and macros such as \texttt for a monospace text font, and \; for spacing/grouping the bits of the binary number.

\begin{equation} \texttt{6C2A}_{16} = \texttt{0110}\;\texttt{1100}\;\texttt{0010}\;\texttt{1010}_{2}\tag{20.1} \end{equation}

If you use these constructions repeatedly, then some macros might be useful. It might also be beneficial for us to add some PreTeXt markup for such numbers used in a paragraph—send us a feature request.

A specialized version of a program listing is an interactive command/response session at a command-line, where differing fonts are used to differentiate the system prompt, the user's commands, and the system's reaction. A console session may be used by itself inside a sidebyside, or it can be wrapped in a listing to get a number and a caption. As elsewhere, you will need to escape ampersands and angle brackets (such as if you have a command using redirection), using &amp;, &lt;, and &gt; in your source.

pi@raspberrypi ~/progs/chap02 $ gcc -Wall -o intAndFloat intAndFloat.c
pi@raspberrypi ~/progs/chap02 $ ./intAndFloat
The integer is 19088743 and the float is 19088.742188
pi@raspberrypi ~/progs/chap02 $ 
Listing20.4Console Session: int and float

Here is the plain version, placed inside a sidebyside for layout control. We simply place a small margin on the left (at 4%).

pi@raspberrypi ~/progs/chap02 $ gcc -Wall -o intAndFloat intAndFloat.c
pi@raspberrypi ~/progs/chap02 $ ./intAndFloat
The integer is 19088743 and the float is 19088.742188
pi@raspberrypi ~/progs/chap02 $ 

If your console input exceeds more than one line, you can author it across several lines and your choice of line breaks will be reflected in the rendering. You can decide to indent lines after the first one for clarity, if desired. You can also decide if your audience needs line-continuation characters or not. (But be careful, a backslash, “\,” will require you to define the latex.console.macro-char xsltproc stringparam to something else, as explained below.)

pi@raspberrypi ~/progs/chap02 $ gcc -Wall
    -o intAndFloat intAndFloat.c
pi@raspberrypi ~/progs/chap02 $ ./intAndFloat
The integer is 19088743 and the float is 19088.742188
pi@raspberrypi ~/progs/chap02 $ 
Listing20.5Console Session: int and float (multi-line input)

Notice in the HTML version of the above example that when you highlight all, or a portion, of the listing for a cut&paste that the prompts are not included.

There is one subtlety with a console session rendered as output. The user input is made bold by a macro, which means that your code cannot contain the special characters “\”, “{”, and “}”, which are used to begin a macro, begin a group, and end a group (respectively). You will get an error message if this condition exists, and there are parameters latex.console.macro-char, latex.console.begin-char, and latex.console.end-char that will allow you to specify alternatives (which need to be characters that do not appear in any of your console sessions, document-wide). The characters & % $ # _ { } ~ ^ \ have special meaning in but should be available for duty as these alternative characters (though not all have been tested). The backslash used in pathnames for Windows is a highly likely case where this needs adjustment.

There is no good way to provide an example of this situation, without making a document with an error in it, out-of-the-box. So experiment by using --stringparam on the xsltproc command-line with alternative characters that will behave with the example above, and with characters that will cause the example above to raise errors. In practice, you may want to specify alternative characters in a thin XSL extension file specific to your project.

We conclude with a longer example, an assembly language program from Bob Plantz, included to test a listing breaking across pages in PDF output.

@ structPass2.s
@ Allocates two structs and assigns a value to each field
@ in each struct, then displays the values.
@ Bob Plantz - 6 July 2016

@ Constants for assembler
        .include "theTag_struct.s"  @ theTag struct defs.
        .equ    y,-28           @ y struct
        .equ    x,-16           @ x struct
        .equ    locals,28       @ space for the structs

@ Constant program data
        .section .rodata
        .align  2
displayX:
        .asciz        "x fields:\n"
displayY:
        .asciz        "y fields:\n"
dispAChar:
        .asciz        "         aChar = "
dispAnInt:
        .asciz        "         anInt = "
dispOtherChar:
        .asciz        "   anotherChar = "

@ The program
        .text
        .align  2
        .global main
        .type   main, %function
main:
        stmfd   sp!, {r4, fp, lr}   @ save caller's info
        add     fp, sp, #8      @ our frame pointer
        sub     sp, sp, #locals @ for the structs

@ fill the x struct
        add     r0, fp, #x      @ address of x struct
        mov     r1, #'1
        mov     r2, #456
        mov     r3, #'2
        bl      loadStruct

@ fill the y struct
        add     r0, fp, #y      @ address of y struct
        mov     r1, #'a
        mov     r2, #123
        mov     r3, #'b
        bl      loadStruct

@ display x struct
        add     r4, fp, #x        @ address of x struct
        ldr     r0, displayXaddr
        bl      writeStr
        ldr     r0, dispACharAddr @ display aChar
        bl      writeStr
        ldrb    r0, [r4, #aChar]
        bl      putChar
        bl      newLine
        ldr     r0, dispAnIntAddr @ display anInt
        bl      writeStr
        ldr     r0, [r4, #anInt]
        bl      putDecInt
        bl      newLine
        ldr     r0, dispOtherCharAddr @ display anotherChar
        bl      writeStr
        ldrb    r0, [r4, #anotherChar]
        bl      putChar
        bl      newLine

@ display y struct
        add     r4, fp, #y        @ address of y struct
        ldr     r0, displayXaddr
        bl      writeStr
        ldr     r0, dispACharAddr @ display aChar
        bl      writeStr
        ldrb    r0, [r4, #aChar]
        bl      putChar
        bl      newLine
        ldr     r0, dispAnIntAddr @ display anInt
        bl      writeStr
        ldr     r0, [r4, #anInt]
        bl      putDecInt
        bl      newLine
        ldr     r0, dispOtherCharAddr @ display anotherChar
        bl      writeStr
        ldrb    r0, [r4, #anotherChar]
        bl      putChar
        bl      newLine

        mov     r0, #0          @ return 0;
        sub     sp, fp, #8      @ restore sp
        ldmfd   sp!, {r4, fp, pc}   @ restore and return

        .align  2
@ addresses of messages
displayXaddr:
        .word   displayX
displayYaddr:
        .word   displayY
dispACharAddr:
        .word   dispAChar
dispAnIntAddr:
        .word   dispAnInt
dispOtherCharAddr:
        .word   dispOtherChar
Listing20.6A longer program listing

In HTML output, a program can be interactive. This is an example program provided by Python Tutor.

Listing20.7An interactive Python program, using Python Tutor