Exercises for Friday, October 8, 2004
In class last Friday, I told you that most web pages on web servers
are written in HTML. This statement was once true but is no longer.
Today, most web pages are generated by running scripts on the web
server; these scripts construct HTML (or XHTML) files (referred to as
'dynamic content') on the fly and then send them on to the client.
The scripts are written in any number of languages including the shell
scripting language that we've been working in, Perl - a language that
is somewhere between our shell language and C, Python - a recently
introduced language designed for much the same range of applications
as Perl, PHP - a language designed from the ground up for dynamically
generating web content, and even Scheme - a dialect of Lisp that
was introduced in Chapter 1 and we'll see in later in the course.
In this exercise, you'll write a script that takes as input a table
consisting of database records generated by an SQL query and produces
as output an HTML file featuring an HTML table in which the rows are
the records and the columns are the fields in the database table.
We'll assume that the database table is formatted as we did in our
database exercise: lines are records and the fields are separated
using semicolons at delimiters.
You'll need to know a little more HTML to carry out this exercise.
Save the following HTML code to a file named 'table.html' and then
open it using a browser.
Title
Table Caption
|
COLUMN 1 |
COLUMN 2 |
ROW 1 |
DATUM 1,1 |
DATUM 1,2 |
ROW 2 |
DATUM 2,1 |
DATUM 2,2 |
ROW 3 |
DATUM 3,1 |
DATUM 3,2 |
The 'table' tag takes many more options than shown but the two shown
are pretty common: 'align' can be 'right', 'left' or 'center' and
'border' is an integer greater than or equal to zero. The 'tr' tag
inside a 'table' environment is used to specify a row of data, the
'td' and 'th' are used to display the data for a cell (or box) in the
table with the 'th' form typically reserved for row or column labels
(in most browsers the 'th' form is displayed in a bold face type).
Experiment with 'table.html' by adding rows and columns and altering
the alignment. You can set the alignment in rows or cells using the
same syntax as shown for the 'table' tag; alignment specifications in
a 'table' tag refer to the alignment of the table on the page while
alignment specifications in 'tr', 'th' and 'td' tags determine the
arrangement of text in cells.
1. Create a table with columns 'First', 'Last', 'Age' and 'Gender'.
Populate the table with 3 rows of fake data. The column headers
should be in bold faced type and centered in their cells, the first
and last names should be left justified, ages should be right
justified and gender identifiers ('M' or 'F') should be centered in
the gender column.
2. Write a script that reads from the standard input the result of a
SQL query and produces as output an HTML document that features an
HTML table displaying display the query. For this exercise, the
result of the SQL query is assumed to have one record per line with
fields delimited by semicolons. For this exercise, you need not
label the columns or rows. Here's an example of the sort of input
your script should be able to handle:
% cat employee
Carla;Carbuncle;21;F
Nathan;Normal;33;M
Alice;Altavista;23;F
Ernest;Sequitur;26;M
In writing this script, it would be nice if you could go through
the file line by line just like the 'awk', 'grep' and 'sed'
utilities do. Fortunately, the C-shell scripting language provides
just such an option: '$<' substitutes a line from the standard
input, with no further interpretation. ('$<' is also useful to
read from the keyboard in a shell script; check out 'Advanced
Topics' (topic #3) in ../../../docs/scripts.txt for an example of
an interactive script that implements a simple guessing game.)
% cat number
#!/bin/csh
set line = $<
set n = 1
while ( "$line" != "" )
foreach word ( $line )
printf "$n - $word\n"
end
set line = $<
@ n ++
end
% cat employee | number
cat employee | number
1 - Carla;Carbuncle;21;F
2 - Nathan;Normal;33;M
3 - Alice;Altavista;23;F
4 - Ernest;Sequitur;26;M
That's a start, but how do you read the individual fields in each
record? As a hint, try replacing 'foreach word ( $line )' with
'foreach word ( `echo $line | tr ";" " "` )'. This doesn't quite
work because, as you might recall, we used the semicolon as a
delimiter precisely because if we used the space character as a
field separator we would not be able to distinguish spaces
separating words within an individual field from those separating
distinct fields. Judicious use of 'sed' will fix this however.
Once you understand how to break up the input into records (lines)
and fields (sequences of words separated by semicolons), the only
tricky part left involves writing one loop nested inside a second
loop to construct the table. The outer loop reads in a line from
the standard input and produces the required 'tr' (row) tags, while
the inner loop breaks up the line into words and produces the
requisite 'th' (column) tags and associated text.
3. Rewrite your solution to Exercise 2 but this time assume that the
first two lines of the input file include the names of the fields
and alignment type for displaying the data in each column. The
resulting HTML file should display the field names at the top of
each column and format the data accordingly.
% cat employee
First;Last;Age;Gender
LEFT;LEFT;RIGHT;CENTER
Carla;Carbuncle;21;F
Nathan;Normal;33;M
Alice;Altavista;23;F
Ernest;Sequitur;26;M
4. Rewrite your solution to Exercise 3 to take two optional arguments.
If a second argument appears on the command line it is assumed to
be a string intended for use as the title of the HTML page. If a
third argument appears on the command line, it is assumed to be a
string intended for use as the caption of the HTML table.
5. Rewrite your solution to Exercise 4 to support two command-line
options. Command-line options can be handled in shell scripts just
as you would handle any argument; typically the script scans 'argv'
to extract options from the rest of the command line arguments,
assigning variables and performing additional computations as
appropriate to carry out the options as specified.
Use this alternative directive as the first line of your script:
#!/bin/csh -b
The '-b' option to the C-shell forces a 'break' from option
processing, causing any further shell arguments to be treated as
non-option arguments. The remaining arguments will not be
interpreted as shell options. This is used to pass options to
a shell script without employing convoluted text processing.
% cat options
#!/bin/csh -b
foreach word ( $argv )
if ( "$word" == "-u" ) echo "dash ewe"
if ( "$word" == "-l" ) echo "dash ell"
end
% options -l misc -u misc misc
dash ell
dash ewe
Use the '-d' option to specify an alternative delimiter. Your
script should use the space character as the default delimiter if
no '-d' option is specified. Use the '-a' option to indicate that
the line encoding the alignment directives is present. If the '-a'
option is not present on the command line, you should assume that
the line specifying alignment directives is not present in the
input.
6. Figure out a way to use the script that you wrote for Exercise 5 in
conjunction with the scripts that we wrote in the database exercise
to produce nicely formatted output. (Think about how you might
invoke a browser in a script to display query results.)