Jump to content
Larry Ullman's Book Forums

Max

Members
  • Posts

    112
  • Joined

  • Last visited

Everything posted by Max

  1. That is the exact code, copied and pasted from https://google-developers.appspot.com/chart/interactive/docs/quick_start Should we now, considering the previous posts, move this thread to JavaScript Develop and Design???
  2. The google site says to copy and paste the following to create the pie chart shown on the page so I tried that (copy to a file called testchart.html) and ran it but all I got was a blank screen (yes, I have JS enabled).<p>--------------------------------------------------------------------------------------------------------- <html> <head> <!--Load the AJAX API--> <script type="text/javascript" src="
  3. Thanks for that HartleySan The ideas that I have had are as follows: - Have a .jpg for every conceivable variation of consumption possible and call the correct one with . Yeuk!! - Ages ago, before PCs, there was a computer on tha market called a Commodore PET which had a character set which included boxes in shades of grey, triangles, etc. etc. ASCII and UTF-8 don't seem to provide for this. - Use tables with each column having a dark background to indicate consumption. That's about it, I guess.
  4. I was looking at an Iberdrola electricity invoice and working out how I would code the php to produce one, which was relatively straightforward, except at one point they put a bar chart to show the previous year's consumption....which got me wondering - is there any facility in php to produce something similar? This would be easy enough: x........x x........x...x x....x...x...x x....x...x...x x....x...x...x ________ J...M..M..J A...A..A..U N...R..Y..L BUT WOULD LIKE TO SOMETHING A BIT MORE FLASHY!
  5. One last question to do this topic to death - and I know it should never happen to a good programmer - but am I right in saying that there is no way of stopping parse error messages (that actually stop the script) appearing on the client's screen?
  6. What you are saying HartleySan is that to put <!Doctype html......... will guarantee all browsers (even older ones) will drop into standards mode, but Larry says in his book that some browsers will drop into quirks mode even if there is a small error in the html. I'm getting more confused.
  7. Thanks, Larry - but it was good fun knowing that I could do it! (I don't get out much ).
  8. That's a bit worrying, Larry, as I have used them in the past as the final arbiter of html. What web site (apart from this excellent forum) would you recommend for first class advice and tuition?....And can you please do a textbook on html/css? Yes I know that there are many on the market but I would buy yours.
  9. Have managed to pick up some new php thanks to Margaux. I emphasise that this is just an exercise. Sorry Larry - couldn't find anything regarding fopen in PHP 6 AND MYSQL 5 but I reckon 620 pages is enough for one textbook!!! As always, all comments appreciated. <?php /* This is the other way discussed in this forum to save error messages without sending them to an e-mail address. It is just a fun exercise but I hope it may be useful to someone. The premise is that the programmer can go into the website through, e.g. FileZilla and look at all errors by reading the text files. Each error has its own file which is named with the reverse date/time of the error. There are some refinements that could be made to this script for use in the real world - one is that it might be better to put all of the errors from a certain day into the same .txt file and the other is that if we are going to keep one .txt file for each error, then we should read the previous files and not save the error if it has already been recorded previously. This script doesn't do that. ---------------configforerrors.php----------------------- */ date_default_timezone_set ('Europe/Madrid'); //Set local date (Spain) function my_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars) //See page 494 of book for explanation. { $file = $e_file; // a bit tidier var. $line = $e_line; //a bit tidier; $message = "<p>Error " . $e_number . " in the script " . $file . " on line " . $e_line; //Build the error message - see book $message .= "\n\r" . $e_message; //Stick in a carriage return then the actual message $message2 = print_r ($e_vars, 1); //Variable listing to be appended later (don't know why) $errordate = date('ymdHis'); //Build the reverse date so that files will be listed in date order $newfilename = "errorlog" . $errordate . ".txt"; //Build the filename which will read e.g. "errorlog120708114420.txt" /* We don't want to save the same file name twice so need to know if it exists and then append a number to it e.g. errorlog120708114420-4.txt */ $counter = 0; //Set counter to zero if(file_exists($newfilename)) //If the file we were about to write is already in the directory { while(file_exists($newfilename)) //Set a loop to see if file exists, and if so to increment the extension Nº { $counter = $counter + 1; $newfilename = "errorlog" . $errordate . "-" . $counter . ".txt"; //Build the filename plus extension - if exists then loop through while again } } $file = fopen ($newfilename, "a+"); //This opens the file with the new filename $text = $message . "\n\r" . $message2; //Build the error message by adding the variable listing fwrite($file, $text); //Write to the new file fclose($file); //Close the new file } //End of function set_error_handler ('my_error_handler'); //tell php to use my_error_handler $test = $test1; //Force an error to test the script ?>
  10. Not wishing to over-egg the pudding, but ever since the first day that I started to learn html, I learnt that the www consortium was the paragon, the benchmark, of all things hypertext. I studied html using Maria Castro's book and the W3 schools web site. So....shouldn't W3schools be using html5? Currently it is:.. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML lang=en-US> I can understand why they don't use strict as they need to teach deprecated tags in the lessons (e.g. target = "_blank"), but why not xhtml?...or html5?
  11. Just to stir this up a little more - let's say that I want to use html5 from now on, but agree with everyone that strict is the ultimate benchmark for quality of programming- Then, if I use html5 validation, it will permit me to use deprecated tags as well as do things like not closing a tag (e.g. <br> is OK now????).
  12. O.K. - This is version 2 of the config.sys file as suggested by Antonio Conte. Seems to function O.K. -------------------------------------------------------------------- <?php /* -----------------------------config.php--------------------------------------- Written by: Max Kite This is purely an exercise but feel free to use it if you wish. This program catches errors and saves them either to text or MySql. It is a version of my_error_handler from page 494 of Larry's book but with the function sending error messages to SQL as opposed to e-mail. SQL:...The program needs to see if the error has happened before because we don't want the same error registered a million times on the database. If the error is new, it will be saved on SQL for a programmer to retrieve at will. This program will run in background and will not be seen by users, hence no HTML used. This is the second version using mysqli_num_rows as suggested by Antonio Conte. */ require ('log6.php'); //Get database connection date_default_timezone_set ('Europe/Madrid'); //Set local date (Spain) function my_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars) //See page 494 of book for explanation. { require ('log6.php'); // log6.php is the dbc connection script and needs to be inside the function to connect to My Sql. $file = $e_file; // a bit tidier var. $file = str_replace('\\', '/', $file); //MySql can't save backslashes in utf-8 so need to change all to forward slash. $line = $e_line; //a bit tidier; $message = "<p>Error in the script " . $file . " on line " . $e_line; //Build the error message - see book $message .= "<br /><br />" . $e_message; $message2 = print_r ($e_vars, 1); //Keep the variable listing separate from message (unlike the book) $errornumber = $e_number; $errorexists = 0; //This is the switch which assigns a value depending on whether the error has been previously saved. 0 = not saved 1=saved //We only need to know if ONE record on the DB is the same as the current error to know that we don't want to save it....... $checkerrors1 = "SELECT * FROM errors WHERE File = '$file' AND Line = '$line' AND ErrorLevel = '$errornumber'"; // Build MySQL query - retieve all files from errors table that match three criteria on the error message. $checkerrors2 = mysqli_query($dbc, $checkerrors1); //Make query $r = mysqli_num_rows($checkerrors2); // Find out how many rows were returned if($r == 0) //If no rows were returned (i.e. the error isn't recorded anywhere on the db) then save the error { //Write the query to append the error details to the db....... $saveerror1 = "INSERT INTO errors (ErrorLevel, Error, File, Line, Variables) VALUES ('$errornumber', '$message', '$file', '$line', '$message2')"; $saveerror2 = @mysqli_query ($dbc, $saveerror1); //run query } } //Close function my_error_handler set_error_handler ('my_error_handler'); //tell php to use my_error_handler ?> -------------------------------------------------------------------------
  13. Hi Antonio Yes - it clicked as soon as I left the internet café - I should probably have used sessions instead. However, in my defence, this suite of programs would normally be saved in an inaccessible directory, accessible only form a main passworded program, and only used by the programmer. A very good point, though - I will be VERY wary of using GET in future.
  14. Hi Antonio Will have a look at that and re-work it. Sorry Antoinio - could you please expand on your last comment re: SQL injection....Thanks
  15. O.K. - will have to review that chapter again. I have put together the bare bones of a config.php script that will save error messages to MySql instead of sending an e-mail. This is purely an intellectual exercise and I would appreciate any criticism - constructive or otherwise. Just accept that I'm an amateur! This is the configuration file - feel free to copy:..... -------------------------------------------------------------------------- <?php /* -----------------------------config.php--------------------------------------- Written by: Max Kite This is purely an exercise but feel free to use it if you wish. This program catches errors and saves them either to text or MySql. It is a version of my_error_handler from page 494 of Larry's book but with the function sending error messages to SQL as opposed to e-mail. SQL:...The program needs to see if the error has happened before because we don't want the same error registered a million times on the database. If the error is new, it will be saved on SQL for a programmer to retrieve at will. This program will run in background and will not be seen by users, hence no HTML used. */ require ('log6.php'); //Get database connection date_default_timezone_set ('Europe/Madrid'); //Set local date (Spain) function my_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars) //See page 494 of book for explanation. { require ('log6.php'); // log6.php is the dbc connection script and needs to be inside the function to connect to My Sql. $file = $e_file; // a bit tidier var. $file = str_replace('\\', '/', $file); //MySql can't save backslashes in utf-8 so need to change all to forward slash. $line = $e_line; //a bit tidier; $message = "<p>Error in the script " . $file . " on line " . $e_line; //Build the error message - see book $message .= "<br /><br />" . $e_message; $message2 = print_r ($e_vars, 1); //Keep the variable listing separate from message (unlike the book) $errornumber = $e_number; $errorexists = 0; //This is the switch which assigns a value depending on whether the error has been previously saved. 0 = not saved 1=saved /*Run an enquiry on errors table of db to pass through every record*/ $checkerrors1 = "SELECT * FROM errors"; // Build MySQL query - retieve all files from errors table. $checkerrors2 = mysqli_query($dbc, $checkerrors1); //Make query while ($checkerrors3 = mysqli_fetch_array($checkerrors2)) //Use while loop to fetch all records in the errors table array { //Pass through the db looking for any matching error - firs tidying up variable names $errorFile = $checkerrors3['File']; //Get the name of the errant file $errorLine = $checkerrors3['Line']; //Get line number $errortype = $checkerrors3['ErrorLevel']; //Get error level //Now see if the record selected matches the criteria for our error..... if (($errorFile == $file) && ($errorLine == $line) && ($errortype == $errornumber)) // If the error is already on the db then assign 1 to switch ($errorexists) { $errorexists = 1; } } //End while if ($errorexists == 0) // Now save error if it has not been found and therefore $errorexists = 0 { //Write the query to append the error details to the db....... $saveerror1 = "INSERT INTO errors (ErrorLevel, Error, File, Line, Variables) VALUES ('$errornumber', '$message', '$file', '$line', '$message2')"; $saveerror2 = @mysqli_query ($dbc, $saveerror1); //run query } } //Close function my_error_handler set_error_handler ('my_error_handler'); //tell php to use my_error_handler ?> ------------------------------------------------------------- On top, I have written two scripts to read the db. They are missing html headers etc. but do the job....... ---------------------------------------------------------------- <?php /* Bare bones script to list errors db --------------------seeerrors.php--------------- */ require_once ('log6.php'); // Get db connection script if (isset($_GET['Ref2'])) //If seeerrors2.php or seeerrors.php have returned a GET with a ref number/All, change 'viewed' in db to 1 to preclude the script from showing the errors already seen. { $done = $_GET['Ref2']; //Nicer variable name $done1 = "UPDATE errors SET Viewed = '1' WHERE Ref = $done"; // Put a 1 in viewed column so that it won't be seen again unless specifically requested. $done2 = mysqli_query ($dbc, $done1); //Run the query to change the viewed column to '1' //Now we use $done to see if the user wants to see all errors including "deleted" ones. If user has clicked on "See all", then "All" will be in "$done" if ($done == 'All') { $geterror1 = "SELECT * FROM errors"; //Write query to list all unviewed errors $choice = '<a href = "seeerrors.php">See new</a>'; } else { $geterror1 = "SELECT * FROM errors WHERE viewed = 0"; //Write query to list all errors $choice = '<a href = "seeerrors.php?Ref2=All">See all errors</a>'; } //end if } else { $geterror1 = "SELECT * FROM errors WHERE viewed = 0"; //Write query to list all errors $choice = '<a href = "seeerrors.php?Ref2=All">See all errors</a>'; } //end if echo "ERROR LISTING <br /><br />"; ?> <table width = "500px"><tr><td>DATE</td><td>ERROR LEVEL</td><td>FILE</td></tr> <?php $geterror2 = mysqli_query ($dbc, $geterror1); //Do the query while ($geterror3 = mysqli_fetch_array($geterror2)) //Pass through $geterror3 array to list records { // Do the listing:..... echo '<tr><td><a href = "seeerrors2.php?Ref=' . $geterror3['Ref'] . '">' . $geterror3['Date'] . '</a></td><td align = "center">' . $geterror3['ErrorLevel'] . '</td><td>' . $geterror3['File'] . '</td></tr>'; } echo '</table><br /><br />'; // Close table echo $choice; ?> --------------------------------------------------- Then individual errors can be viewed using seeerrors2.php.......... --------------------------------------------------- <?php echo "ERROR REPORT<br /><br /><br />"; require_once ('log6.php'); //get connction script ?> <table width = "1000px" border = "0"> <?php $errorref = $_GET['Ref']; //Get the error reference No from seeerrors.php $geterror1 = "SELECT * FROM errors WHERE Ref = $errorref"; // Make the query $geterror2 = mysqli_query ($dbc, $geterror1); while ($geterror3 = mysqli_fetch_array($geterror2)) { echo '<tr><td>Ref Nº</td><td>' . $geterror3['Ref'] . '</td></tr>'; echo '<tr><td>Date</td><td>' . $geterror3['Date'] . '</td></tr>'; echo '<tr><td>Error level</td><td>' . $geterror3['ErrorLevel'] . '</td></tr>'; echo '<tr><td valign = "top">Error</td><td>' . $geterror3['Error'] . '</td></tr>'; echo '<tr><td>File</td><td>' . $geterror3['File'] . '</td></tr>'; echo '<tr><td>Variables</td><td>' . $geterror3['Variables'] . '</td></tr>'; } echo '</table><br /><br />'; echo '<p><a href = "seeerrors.php?Ref2=' . $errorref . '">Done</a></p>'; ?> ----------------------------------------------------- Here's the SQL to set up the db:...... SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `errors` ( `Ref` int(100) NOT NULL AUTO_INCREMENT, `Date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `ErrorLevel` int(6) unsigned NOT NULL, `Error` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `File` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `Line` int(6) unsigned NOT NULL, `Variables` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `Viewed` tinyint(3) unsigned NOT NULL, PRIMARY KEY (`Ref`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2774 ; Still working on a script to save to file.
  16. One thing is for sure, it will save Larry a load of print in his next editions!!
  17. Hi Margaux Have been looking through Larry's books and can't seem to find much on writing to files. Uploading images and files, yes, but actually inserting text into a .txt file no. Would appreciate any link you could send me.
  18. Thanks Margaux and Antonio - will make it a little learning project and will post it when done.
  19. Hi Larry In your book you create a my_error_handler which sends error messages to an e-mail address (and it works very well). Just one question - would it be possible in php to write the error message to a file and save it on the server? e.g. error0001.txt error0002.txt error0003.txt etc. etc
  20. Hi HartleySan - Yes - and as Larry points out in his book, always use valid "action" tags in case a user has an old browser that doesn't support html5 and/or JS, not action = "#". Perhaps one day we will all be using html5 and all the rest will be a distant nightmare - but it still seems to me that they are drifting away from clean (i.e. strict) coding - have they just given up? Last question - can anyone explain to me who and why thought up a line of text like <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"> or was he just showing off??????
  21. HartleySan - "It's there purely as the minimum to force all browsers into standards mode." I agree with you there HartleySan. Also - does this mean that W3 will eventually drop strict mode? How many sites are written in strict? Also, if HTML 5 is eventually used by 99% of sites, will it allow all 'transitional' deprecated elements?...and if so, isn't that heading away from the aim of W3 to cleaner html (i.e. strict mode). Having said all of this, the deprecated and error laden code above seems to work in every browser I have tried. Even the marquee which was summarily condemned by all three validators works well. Larry - I understand what you are saying and will not hesitate to use html 5 in future. I guess the problem with other (x)html types is reverse engineering. Like the development of the PC, new motherboards had to be designed with an eye to running older software (DOS) which slowed the development of the 286 and 386 somewhat. I can only imagine the discussions between programming teams at IE or Firefox trying to accomodate all of the different html types in their code. I bet they'd love for someone to say 'Right - the whole world is using html 5 from now on - no exceptions!"
  22. I thought that for a bit of enlightenment, I would do a bit of experimentation. I wrote a simple bit of html, split it into three (html 5, transitional and strict) and passed them individually throught the W3 validator. This is the html (this happens to be transitional): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8"> <title>Testing html</title> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body> <!--This is some code deliberately written to test the different doctypes--> <!--Testing straigtforward code--> <p>This tests paragraph</p> Break with closing slash <br /><br /> Break without closing slash <br><br> Marquee<br /><br /> <marquee height="40px" behavior="scroll" loop="infinite" /> For all your garden machinery sales, service and repairs. <img src = "Bullet.png" /> Free expert advice. <img src = "Bullet.png" /> Modern and vintage machinery specialists. <img src = "Bullet.png" /> Free estimates. <img src = "Bullet.png" /> Free local collection and delivery. <img src = "Bullet.png" /> New and reconditioned mowers with full warranty delivered FREE within Reading and the surrounding areas. <img src = "Bullet.png" /> Allen Asuka Atco Castel Countax Echo Flymo Gardencare Hayter Honda Husqvarna Mountfield Qualcast Sarp Stihl Suffolk Warrior Webb Wolf <img src = "Bullet.png" /> </marquee> <br /><br /> iframe:<br /><br /> <iframe frameborder="2" width="425" height="350" scrolling="yes" marginheight="0" marginwidth="0" src="http://www.larryullman.com">No support for iframes.</iframe><br /> <br /><br /> Tables:<br /><br /> <table align = "left" bgcolor = "yellow" cellpadding = "3" cellspacing = "2" rules = "cols"> <tr bgcolor = "blue" valign = "top" align = "right"><td bgcolor = "green" width = "100px" height = "20px">Should be background green and 100px wide</td><td width="200px">Should be background yellow and 200px wide</td></tr> </table> <br /><br /> <p>Now introduce some errors:....<br /><br /> <p> <b>This text emboldened...<i>--and this bold</b> and now italic only<div>Division opened and para closed</p><br /> <br /> </div> para not closed </html> These are the results:.... HTML 5: 32 errors, 1 warning HTML Transitional: 25 errors, 2 warnings HTML Strict: 65 errors, 2 warnings ------------ Line 5: <meta charset="utf-8"> HTML 5: No error. Transitional: Line 5, Column 19: there is no attribute "charset" The attribute given above is required for an element that you've used, but you have omitted it. For instance, in most HTML and XHTML document types the "type" attribute is required on the "script" element and the "alt" attribute is required for the "img" element. Typical values for type are type="text/css" for <style> and type="text/javascript" for <script>. Line 5, Column 27: end tag for "meta" omitted, but OMITTAG NO was specified Strict: No Character Encoding Found! Falling back to UTF-8. Line 4, Column 26: required attribute "content" not specified ------------- Line 14: HTML 5: None Transitional: None Strict: Line 14, Column 1: character data is not allowed here Break with closing slash You have used character data somewhere it is not permitted to appear. Mistakes that can cause this error include: putting text directly in the body of the document without wrapping it in a container element (such as a <p>aragraph</p>), or forgetting to quote an attribute value (where characters such as "%" and "/" are common, but cannot appear without surrounding quotes), or using XHTML-style self-closing tags (such as <meta ... />) in HTML 4.01 or earlier. To fix, remove the extra slash ('/') character. For more information about the reasons for this, see Empty elements in SGML, HTML, XML, and XHTML. ------------ Line 15: HTML 5: None Transitional: None Strict: document type does not allow element "br" here; missing one of "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "pre", "address", "fieldset", "ins", "del" start-tag <br /><br /> ------------ Line 18: HTML 5: None Transitional: end tag for "br" omitted, but OMITTAG NO was specified <br><br> start tag was here <br><br> Strict: Line 18, Column 13: document type does not allow element "br" here; missing one of "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "pre", "address", "fieldset", "ins", "del" start-tag Marquee<br /><br /> ------------- Marquee: All versions had a good old moan about 'Marquee' which is fair enough, but it does seem to work OK in the browsers that I tried. ------------- Line 24: HTML 5: The frameborder attribute on the iframe element is obsolete. Use CSS instead. The marginwidth attribute on the iframe element is obsolete. Use CSS instead. …dth="0" src="http://www.larryullman.com">No support for iframes.</iframe><br /> Transitional: value of attribute "frameborder" cannot be "2"; must be one of "1", "0" Strict: Line 24 - Too much to mention. A real old groan! ------------- Line 25: HTML 5: None Transitional: None Strict: document type does not allow element "br" here; missing one of "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "pre", "address", "fieldset", "ins", "del" start-tag ------------- Line 26: HTML 5: None Transitional: None Strict: character data is not allowed here - Tables:<br /><br /> ------------- Line 27; HTML 5: The bgcolor attribute on the table element is obsolete. Use CSS instead. Transitional: None Strict: there is no attribute "align" - there is no attribute "bgcolor" etc...etc. ------------- Line 28: HTML 5: The bgcolor attribute (and others!) on the tr element is obsolete. Use CSS instead. Transitional: None Strict: there is no attribute "height" ------------- Line 33: HTML 5: End tag b violates nesting rules. Transitional: end tag for "i" omitted, but OMITTAG NO was specified Strict: end tag for "i" omitted, but OMITTAG NO was specified - document type does not allow element "div" here; missing one of "object", "ins", "del", "map", "button" start-tag ------------- Line 34: HTML 5: End tag div seen, but there were open elements. Transitional: end tag for element "div" which is not open Strict: end tag for element "div" which is not open ------------- Line 36: HTML 5: End tag for html seen, but there were unclosed elements. Transitional: end tag for element "div" which is not open Strict: end tag for element "div" which is not open ------------- Line 37: HTML 5: None Transitional: end tag for "p" omitted, but OMITTAG NO was specified Strict: end tag for "body" omitted, but OMITTAG NO was specified -------------- I haven't a clue what it all means - any comments would be gratefully accepted.
  23. One thing that still bothers me is the older browsers - if they worked perfectly with <!DOCTYPE HTML> then how many millions of man hours have been wasted around the world typing <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">) every time a website was created? This doesn't appear in Maria Castros (otherwise authoritative) HTML book. Sorry if I'm sounding fussy, but why didn't someone five years ago say 'hey - you don't need to type all that stuff - just <!DOCTYPE HTML> will do.'?
  24. Hi HartleySan Had a good look - can't find that option. Easier to use Yahoo.co.uk.
×
×
  • Create New...