From ff8718f72225a2e34d918c06a3b2c8cca5af3164 Mon Sep 17 00:00:00 2001 From: Synchro Date: Fri, 26 Apr 2013 18:22:45 +0200 Subject: [PATCH] Major overhaul and cleanup of example code Update test_script to use some recently changed features, rename to code_generator Generated code actually works! Update SyntaxHighlighter New PHPMailer graphic --- changelog.md | 13 +- {test_script => examples}/LGPLv3.txt | 0 .../index.php => examples/code_generator.phps | 56 +- examples/contents.html | 35 +- examples/exceptions.phps | 41 + examples/gmail.phps | 62 + examples/images/phpmailer.gif | Bin 4756 -> 0 bytes examples/images/phpmailer.png | Bin 0 -> 8670 bytes examples/index.html | 85 +- examples/mail.phps | 36 + examples/mailing_list.phps | 49 + examples/pop_before_smtp.phps | 63 + examples/scripts/XRegExp.js | 664 ++++++ examples/scripts/shAutoloader.js | 122 ++ examples/scripts/shBrushPhp.js | 72 + examples/scripts/shCore.js | 1 + .../src => examples/scripts}/shLegacy.js | 41 +- examples/sendmail.phps | 38 + examples/smtp.phps | 60 + examples/smtp_no_auth.phps | 56 + examples/styles/shCore.css | 46 + examples/styles/shCoreDefault.css | 77 + examples/styles/shCoreDjango.css | 78 + examples/styles/shCoreEclipse.css | 80 + examples/styles/shCoreEmacs.css | 76 + examples/styles/shCoreFadeToGrey.css | 77 + examples/styles/shCoreMDUltra.css | 76 + examples/styles/shCoreMidnight.css | 76 + examples/styles/shCoreRDark.css | 76 + examples/styles/shThemeAppleScript.css | 21 + examples/styles/shThemeDefault.css | 31 + examples/styles/shThemeDjango.css | 32 + examples/styles/shThemeEclipse.css | 34 + examples/styles/shThemeEmacs.css | 30 + examples/styles/shThemeFadeToGrey.css | 31 + examples/styles/shThemeMDUltra.css | 30 + examples/styles/shThemeMidnight.css | 30 + examples/styles/shThemeRDark.css | 30 + examples/styles/shThemeVisualStudio.css | 31 + {test_script => examples}/styles/wrapping.png | Bin examples/test_db_smtp_basic.php | 58 - examples/test_mail_advanced.php | 30 - examples/test_mail_basic.php | 41 - examples/test_pop_before_smtp_advanced.php | 39 - examples/test_pop_before_smtp_basic.php | 49 - examples/test_sendmail_advanced.php | 33 - examples/test_sendmail_basic.php | 43 - examples/test_smtp_advanced.php | 42 - examples/test_smtp_advanced_no_auth.php | 36 - examples/test_smtp_basic.php | 58 - examples/test_smtp_basic_no_auth.php | 53 - examples/test_smtp_gmail_advanced.php | 40 - examples/test_smtp_gmail_basic.php | 58 - test/contents.html | 19 +- test/test_callback.php | 2 +- test_script/contents.html | 17 - test_script/images/aikido.gif | Bin 26300 -> 0 bytes test_script/images/bkgrnd.gif | Bin 49 -> 0 bytes test_script/images/phpmailer.gif | Bin 4756 -> 0 bytes test_script/scripts/clipboard.swf | Bin 1361 -> 0 bytes test_script/scripts/shBrushBash.js | 59 - test_script/scripts/shBrushCSharp.js | 64 - test_script/scripts/shBrushCpp.js | 99 - test_script/scripts/shBrushCss.js | 93 - test_script/scripts/shBrushDelphi.js | 57 - test_script/scripts/shBrushDiff.js | 43 - test_script/scripts/shBrushGroovy.js | 69 - test_script/scripts/shBrushJScript.js | 51 - test_script/scripts/shBrushJava.js | 55 - test_script/scripts/shBrushPerl.js | 74 - test_script/scripts/shBrushPhp.js | 91 - test_script/scripts/shBrushPlain.js | 35 - test_script/scripts/shBrushPython.js | 56 - test_script/scripts/shBrushRuby.js | 57 - test_script/scripts/shBrushScala.js | 53 - test_script/scripts/shBrushSql.js | 68 - test_script/scripts/shBrushVb.js | 58 - test_script/scripts/shBrushXml.js | 71 - test_script/scripts/shCore.js | 30 - test_script/scripts/shLegacy.js | 30 - test_script/src/shCore.js | 1949 ----------------- test_script/styles/help.png | Bin 786 -> 0 bytes test_script/styles/magnifier.png | Bin 615 -> 0 bytes test_script/styles/page_white_code.png | Bin 603 -> 0 bytes test_script/styles/page_white_copy.png | Bin 309 -> 0 bytes test_script/styles/printer.png | Bin 731 -> 0 bytes test_script/styles/shCore.css | 321 --- test_script/styles/shThemeDefault.css | 191 -- test_script/styles/shThemeDjango.css | 193 -- test_script/styles/shThemeEmacs.css | 192 -- test_script/styles/shThemeFadeToGrey.css | 193 -- test_script/styles/shThemeMidnight.css | 192 -- test_script/styles/shThemeRDark.css | 192 -- test_script/test.html | 47 - 94 files changed, 2336 insertions(+), 5421 deletions(-) rename {test_script => examples}/LGPLv3.txt (100%) rename test_script/index.php => examples/code_generator.phps (91%) create mode 100644 examples/exceptions.phps create mode 100644 examples/gmail.phps delete mode 100644 examples/images/phpmailer.gif create mode 100644 examples/images/phpmailer.png create mode 100644 examples/mail.phps create mode 100644 examples/mailing_list.phps create mode 100644 examples/pop_before_smtp.phps create mode 100755 examples/scripts/XRegExp.js create mode 100644 examples/scripts/shAutoloader.js create mode 100644 examples/scripts/shBrushPhp.js create mode 100644 examples/scripts/shCore.js rename {test_script/src => examples/scripts}/shLegacy.js (72%) create mode 100644 examples/sendmail.phps create mode 100644 examples/smtp.phps create mode 100644 examples/smtp_no_auth.phps create mode 100644 examples/styles/shCore.css create mode 100644 examples/styles/shCoreDefault.css create mode 100644 examples/styles/shCoreDjango.css create mode 100644 examples/styles/shCoreEclipse.css create mode 100644 examples/styles/shCoreEmacs.css create mode 100644 examples/styles/shCoreFadeToGrey.css create mode 100644 examples/styles/shCoreMDUltra.css create mode 100644 examples/styles/shCoreMidnight.css create mode 100644 examples/styles/shCoreRDark.css create mode 100644 examples/styles/shThemeAppleScript.css create mode 100644 examples/styles/shThemeDefault.css create mode 100644 examples/styles/shThemeDjango.css create mode 100644 examples/styles/shThemeEclipse.css create mode 100644 examples/styles/shThemeEmacs.css create mode 100644 examples/styles/shThemeFadeToGrey.css create mode 100644 examples/styles/shThemeMDUltra.css create mode 100644 examples/styles/shThemeMidnight.css create mode 100644 examples/styles/shThemeRDark.css create mode 100644 examples/styles/shThemeVisualStudio.css rename {test_script => examples}/styles/wrapping.png (100%) delete mode 100644 examples/test_db_smtp_basic.php delete mode 100644 examples/test_mail_advanced.php delete mode 100644 examples/test_mail_basic.php delete mode 100644 examples/test_pop_before_smtp_advanced.php delete mode 100644 examples/test_pop_before_smtp_basic.php delete mode 100644 examples/test_sendmail_advanced.php delete mode 100644 examples/test_sendmail_basic.php delete mode 100644 examples/test_smtp_advanced.php delete mode 100644 examples/test_smtp_advanced_no_auth.php delete mode 100644 examples/test_smtp_basic.php delete mode 100644 examples/test_smtp_basic_no_auth.php delete mode 100644 examples/test_smtp_gmail_advanced.php delete mode 100644 examples/test_smtp_gmail_basic.php delete mode 100644 test_script/contents.html delete mode 100644 test_script/images/aikido.gif delete mode 100644 test_script/images/bkgrnd.gif delete mode 100644 test_script/images/phpmailer.gif delete mode 100644 test_script/scripts/clipboard.swf delete mode 100644 test_script/scripts/shBrushBash.js delete mode 100644 test_script/scripts/shBrushCSharp.js delete mode 100644 test_script/scripts/shBrushCpp.js delete mode 100644 test_script/scripts/shBrushCss.js delete mode 100644 test_script/scripts/shBrushDelphi.js delete mode 100644 test_script/scripts/shBrushDiff.js delete mode 100644 test_script/scripts/shBrushGroovy.js delete mode 100644 test_script/scripts/shBrushJScript.js delete mode 100644 test_script/scripts/shBrushJava.js delete mode 100644 test_script/scripts/shBrushPerl.js delete mode 100644 test_script/scripts/shBrushPhp.js delete mode 100644 test_script/scripts/shBrushPlain.js delete mode 100644 test_script/scripts/shBrushPython.js delete mode 100644 test_script/scripts/shBrushRuby.js delete mode 100644 test_script/scripts/shBrushScala.js delete mode 100644 test_script/scripts/shBrushSql.js delete mode 100644 test_script/scripts/shBrushVb.js delete mode 100644 test_script/scripts/shBrushXml.js delete mode 100644 test_script/scripts/shCore.js delete mode 100644 test_script/scripts/shLegacy.js delete mode 100644 test_script/src/shCore.js delete mode 100644 test_script/styles/help.png delete mode 100644 test_script/styles/magnifier.png delete mode 100644 test_script/styles/page_white_code.png delete mode 100644 test_script/styles/page_white_copy.png delete mode 100644 test_script/styles/printer.png delete mode 100644 test_script/styles/shCore.css delete mode 100644 test_script/styles/shThemeDefault.css delete mode 100644 test_script/styles/shThemeDjango.css delete mode 100644 test_script/styles/shThemeEmacs.css delete mode 100644 test_script/styles/shThemeFadeToGrey.css delete mode 100644 test_script/styles/shThemeMidnight.css delete mode 100644 test_script/styles/shThemeRDark.css delete mode 100644 test_script/test.html diff --git a/changelog.md b/changelog.md index 43a76374..7524e14d 100644 --- a/changelog.md +++ b/changelog.md @@ -3,13 +3,17 @@ * Add Ukranian translation from @Krezalis * Support for do_verp * Fix bug in CRAM-MD5 AUTH -* Propagate debug output option to SMTP class (@Reblutus) +* Propagate Debugoutput option to SMTP class (@Reblutus) * Determine MIME type of attachments automatically * Add cross-platform, multibyte-safe pathinfo replacement (with tests) and use it * Add a new 'html' Debugoutput type -* Clean up SMTP debug output, remove unnecessary repeated code +* Clean up SMTP debug output, remove embedded HTML * Some small changes in header formatting to improve IETF msglint test results -* Update test script to use some recently changed features +* Update test_script to use some recently changed features, rename to code_generator +* Generated code actually works! +* Update SyntaxHighlighter +* Major overhaul and cleanup of example code +* New PHPMailer graphic ## Version 5.2.6 (April 11th 2013) * Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer @@ -27,8 +31,7 @@ ## Version 5.2.4 (February 19, 2013) * Fix tag and version bug. -* un-deprecate isSMTP(), isMail(), IsSendmail() and - isQmail(). +* un-deprecate isSMTP(), isMail(), IsSendmail() and isQmail(). * Numerous translation updates ## Version 5.2.3 (February 8, 2013) diff --git a/test_script/LGPLv3.txt b/examples/LGPLv3.txt similarity index 100% rename from test_script/LGPLv3.txt rename to examples/LGPLv3.txt diff --git a/test_script/index.php b/examples/code_generator.phps similarity index 91% rename from test_script/index.php rename to examples/code_generator.phps index 2e8a301f..64124b5a 100644 --- a/test_script/index.php +++ b/examples/code_generator.phps @@ -5,7 +5,7 @@ */ require '../class.phpmailer.php'; -$CFG['smtp_debug'] = 1; +$CFG['smtp_debug'] = 2; //0 == off, 1 for client output, 2 for client and server $CFG['smtp_debugoutput'] = 'html'; $CFG['smtp_server'] = 'localhost'; $CFG['smtp_port'] = '25'; @@ -33,22 +33,22 @@ $authenticate_username = ( isset($_POST['authenticate_username'])) ? $_POST['aut // storing all status output from the script to be shown to the user later $results_messages = array(); -$errorMsg = array(); // $example_code represents the "final code" that we're using, and will // be shown to the user at the end. $example_code = "\nrequire_once '../class.phpmailer.php';"; -$example_code .= "\n\n\$results_messages = new array();"; +$example_code .= "\n\n\$results_messages = array();"; -$mail = new PHPMailer(true); +$mail = new PHPMailer(true); //PHPMailer instance with exceptions enabled $mail->CharSet = 'utf-8'; -$mail->Debugoutput = $CFG['smtp_debugoutput']; //Format error messages so they are HTML-safe +$mail->Debugoutput = $CFG['smtp_debugoutput']; $example_code .= "\n\n\$mail = new PHPMailer(true);"; $example_code .= "\n\$mail->CharSet = 'utf-8';"; class phpmailerAppException extends phpmailerException {} $example_code .= "\n\nclass phpmailerAppException extends phpmailerException {}"; +$example_code .= "\n\ntry {"; try { if ( isset($_POST["submit"]) && $_POST['submit'] == "Submit" ) { @@ -57,32 +57,32 @@ try { throw new phpmailerAppException("Email address " . $to . " is invalid -- aborting!"); } - $example_code .= "\n\$to = \$_POST[\"To_Email\"];"; - $example_code .= "\nif(!PHPMailer::ValidateAddress($to)) {"; + $example_code .= "\n\$to = '{$_POST['To_Email']}';"; + $example_code .= "\nif(!PHPMailer::ValidateAddress(\$to)) {"; $example_code .= "\n throw new phpmailerAppException(\"Email address \" . \$to . \" is invalid -- aborting!\");"; $example_code .= "\n}"; switch ($_POST['test_type']) { case 'smtp': $mail->IsSMTP(); // telling the class to use SMTP - $mail->SMTPDebug = $_POST['smtp_debug']; + $mail->SMTPDebug = (integer)$_POST['smtp_debug']; $mail->Host = $_POST['smtp_server']; // SMTP server - $mail->Port = $_POST['smtp_port']; // set the SMTP port + $mail->Port = (integer)$_POST['smtp_port']; // set the SMTP port if ($_POST['smtp_secure']) { $mail->SMTPSecure = strtolower($_POST['smtp_secure']); } - $mail->SMTPAuth = array_key_exists('smtp_authenticate', $_POST); // enable SMTP authentication + $mail->SMTPAuth = array_key_exists('smtp_authenticate', $_POST); // enable SMTP authentication? if (array_key_exists('smtp_authenticate', $_POST)) { $mail->Username = $_POST['authenticate_username']; // SMTP account username $mail->Password = $_POST['authenticate_password']; // SMTP account password } $example_code .= "\n\$mail->IsSMTP();"; - $example_code .= "\n\$mail->SMTPDebug = \"".$_POST['smtp_debug']."\";"; + $example_code .= "\n\$mail->SMTPDebug = ".$_POST['smtp_debug'].";"; $example_code .= "\n\$mail->Host = \"".$_POST['smtp_server']."\";"; $example_code .= "\n\$mail->Port = \"".$_POST['smtp_port']."\";"; $example_code .= "\n\$mail->SMTPSecure = \"".strtolower($_POST['smtp_secure'])."\";"; - $example_code .= "\n\$mail->SMTPAuth = \"".(array_key_exists('smtp_authenticate', $_POST)?'true':'false')."\";"; + $example_code .= "\n\$mail->SMTPAuth = ".(array_key_exists('smtp_authenticate', $_POST)?'true':'false').";"; if (array_key_exists('smtp_authenticate', $_POST)) { $example_code .= "\n\$mail->Username = \"".$_POST['authenticate_username']."\";"; $example_code .= "\n\$mail->Password = \"".$_POST['authenticate_password']."\";"; @@ -111,8 +111,8 @@ try { $mail->FromName = $_POST['From_Name']; $example_code .= "\n\$mail->AddReplyTo(\"".$_POST['From_Email']."\", \"".$_POST['From_Name']."\");"; - $example_code .= "\n\$mail->From = \"".$_POST['From_Email']."\");"; - $example_code .= "\n\$mail->FromName = \"".$_POST['From_Name']."\");"; + $example_code .= "\n\$mail->From = \"".$_POST['From_Email']."\";"; + $example_code .= "\n\$mail->FromName = \"".$_POST['From_Name']."\";"; } else { $mail->AddReplyTo($_POST['From_Email']); @@ -161,7 +161,7 @@ try { $body = $_POST['Message']; } - $example_code .= "\n\$body = \"".htmlentities(addslashes($body)).'";'; + $example_code .= "\n\$body = <<<'EOT'\n".htmlentities($body)."\nEOT;"; $mail->WordWrap = 80; // set word wrap $mail->MsgHTML($body, dirname(__FILE__), true); //Create message bodies and embed images @@ -169,10 +169,10 @@ try { $example_code .= "\n\$mail->WordWrap = 80;"; $example_code .= "\n\$mail->MsgHTML(\$body, dirname(__FILE__), true); //Create message bodies and embed images"; - $mail->AddAttachment('images/aikido.gif', 'aikido.gif'); // optional name - $mail->AddAttachment('images/phpmailer.gif', 'phpmailer.gif'); // optional name - $example_code .= "\n\$mail->AddAttachment('images/aikido.gif', 'aikido.gif'); // optional name"; - $example_code .= "\n\$mail->AddAttachment('images/phpmailer.gif', 'phpmailer.gif'); // optional name"; + $mail->AddAttachment('images/phpmailer-mini.gif', 'phpmailer-mini.gif'); // optional name + $mail->AddAttachment('images/phpmailer.png', 'phpmailer.png'); // optional name + $example_code .= "\n\$mail->AddAttachment('images/phpmailer-mini.gif', 'phpmailer-mini.gif'); // optional name"; + $example_code .= "\n\$mail->AddAttachment('images/phpmailer.png', 'phpmailer.png'); // optional name"; try { $mail->Send(); @@ -184,7 +184,7 @@ try { $example_code .= "\n\ntry {"; $example_code .= "\n \$mail->Send();"; - $example_code .= "\n \$results_messages[] = \"Message has been sent using \" . strtoupper(\$_POST[\"test_type\"]);"; + $example_code .= "\n \$results_messages[] = \"Message has been sent using ". strtoupper($_POST['test_type'])."\";"; $example_code .= "\n}"; $example_code .= "\ncatch (phpmailerException \$e) {"; $example_code .= "\n throw new phpmailerAppException('Unable to send to: ' . \$to. ': '.\$e->getMessage());"; @@ -194,6 +194,18 @@ try { catch (phpmailerAppException $e) { $results_messages[] = $e->errorMessage(); } +$example_code .= "\n}"; +$example_code .= "\ncatch (phpmailerAppException \$e) {"; +$example_code .= "\n \$results_messages[] = \$e->errorMessage();"; +$example_code .= "\n}"; +$example_code .= "\n\nif (count(\$results_messages) > 0) {"; +$example_code .= "\n echo \"

Run results

\\n\";"; +$example_code .= "\n echo \"\\n\";"; +$example_code .= "\n}"; ?> @@ -453,8 +465,8 @@ catch (phpmailerAppException $e) { diff --git a/examples/contents.html b/examples/contents.html index fc4c3088..e5c55100 100644 --- a/examples/contents.html +++ b/examples/contents.html @@ -1,20 +1,17 @@ - -
-

-
- This is a test of PHPMailer.
-
-This particular example uses HTML, with a <div> tag and inline
-styles.
-
-Also note the use of the PHPMailer logo above with no specific code to handle -including it.
-Included are two attachments:
-phpmailer.gif is an attachment and used inline as a graphic (above)
-phpmailer_mini.gif is an attachment
-
-PHPMailer:
-Author: Andy Prevost (codeworxtech@users.sourceforge.net)
-Author: Marcus Bointon (coolbru@users.sourceforge.net)
-
+ + + + + PHPMailer Test + + +
+

This is a test of PHPMailer.

+
+ PHPMailer rocks +
+

This example uses HTML.

+

The PHPMailer image at the top has been embedded automatically.

+
+ diff --git a/examples/exceptions.phps b/examples/exceptions.phps new file mode 100644 index 00000000..2df8b3cb --- /dev/null +++ b/examples/exceptions.phps @@ -0,0 +1,41 @@ + + + + + PHPMailer - Exceptions test + + +SetFrom('from@example.com', 'First Last'); + //Set an alternative reply-to address + $mail->AddReplyTo('replyto@example.com','First Last'); + //Set who the message is to be sent to + $mail->AddAddress('whoto@example.com', 'John Doe'); + //Set the subject line + $mail->Subject = 'PHPMailer Exceptions test'; + //Read an HTML message body from an external file, convert referenced images to embedded, + //and convert the HTML into a basic plain-text alternative body + $mail->MsgHTML(file_get_contents('contents.html'), dirname(__FILE__)); + //Replace the plain text body with one created manually + $mail->AltBody = 'This is a plain-text message body'; + //Attach an image file + $mail->AddAttachment('images/phpmailer-mini.gif'); + //Send the message + //Note that we don't need check the response from this because it will throw an exception if it has trouble + $mail->Send(); + echo "Message sent!"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + diff --git a/examples/gmail.phps b/examples/gmail.phps new file mode 100644 index 00000000..c4df1eba --- /dev/null +++ b/examples/gmail.phps @@ -0,0 +1,62 @@ + + + + + PHPMailer - GMail SMTP test + + +IsSMTP(); +//Enable SMTP debugging +// 0 = off (for production use) +// 1 = client messages +// 2 = client and server messages +$mail->SMTPDebug = 2; +//Ask for HTML-friendly debug output +$mail->Debugoutput = 'html'; +//Set the hostname of the mail server +$mail->Host = 'smtp.gmail.com'; +//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission +$mail->Port = 587; +//Set the encryption system to use - ssl (deprecated) or tls +$mail->SMTPSecure = 'tls'; +//Whether to use SMTP authentication +$mail->SMTPAuth = true; +//Username to use for SMTP authentication - use full email address for gmail +$mail->Username = "username@gmail.com"; +//Password to use for SMTP authentication +$mail->Password = "yourpassword"; +//Set who the message is to be sent from +$mail->SetFrom('from@example.com', 'First Last'); +//Set an alternative reply-to address +$mail->AddReplyTo('replyto@example.com','First Last'); +//Set who the message is to be sent to +$mail->AddAddress('whoto@example.com', 'John Doe'); +//Set the subject line +$mail->Subject = 'PHPMailer GMail SMTP test'; +//Read an HTML message body from an external file, convert referenced images to embedded, convert HTML into a basic plain-text alternative body +$mail->MsgHTML(file_get_contents('contents.html'), dirname(__FILE__)); +//Replace the plain text body with one created manually +$mail->AltBody = 'This is a plain-text message body'; +//Attach an image file +$mail->AddAttachment('images/phpmailer-mini.gif'); + +//Send the message, check for errors +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} +?> + + diff --git a/examples/images/phpmailer.gif b/examples/images/phpmailer.gif deleted file mode 100644 index 5e269714e32991eab9fb1aecd32d321cd17c790c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4756 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 UCUCLi;vX1V>W|b)?^=icFF3L%;{X5v literal 0 HcmV?d00001 diff --git a/examples/index.html b/examples/index.html index 08c808e5..aeb6cad1 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,50 +1,35 @@ -This release of PHPMailer (v5.0.0) sets a new milestone in the development -cycle of PHPMailer. First, class.phpmailer.php has a small footprint (65.7 Kb), -while class.smtp.php is even smaller than before (at only 25.0 Kb).
-
-We have maintained all functionality and added Exception handling unique to -PHP 5/6.
-
-There is only one function that has been removed: that is getFile(). The reason -for this is that getFile() became a wrapper for the PHP function 'file_get_contents()' -and nothing more. Rather than burden the class with a function already available -in PHP, we decided to remove it.
-
-Our new Exception handling provides your own scripts far more power than ever.
-
-We have also enhanced the "packaging" of PHPMailer with an entirely new set of -examples. Included are both basic and advanced examples showing how you can take -advantage of PHP Exception handling to improve your own scripts.
-
-A few things to note about PHPMailer: -
    -
  • the use of $mail->AltBody is completely optional. If not used, PHPMailer - will use the HTML text with htmlentities().
    - We also highly recommend using HTML2Text authored by Jon Abernathy. The class description - and download can be viewed at: http://www.chuggnutt.com/html2text but is also bundled with - PHPMailer in ./extras/ . -
  • -
  • there is no specific code to define image or attachment types ... that is handled - automatically by PHPMailer when it parses the images
  • -
-A note to users that want to use SMTP with PHPMailer. The most common problems are: -
    -
  • wrong port ... most ISP (Internet Service Providers) will not allow relaying through - their servers. If that's the case with your ISP, try using port 26. -
  • -
  • wrong authentication information (username and/or password) ... don't forget that - many servers require the account name to be in the format of the full email address. -
  • -
  • ... if these tips do not get your SMTP settings working, we have a debug mode - for helping you determine the problem. Insert this after $mail->IsSMTP();
    - $mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
    - note that a setting of 2 will display all errors and messages generated by the SMTP - server
    -
  • -
-Our examples all use an HTML file in the /examples folder. To see what the email SHOULD -look like in your HTML compatible email viewer: click here
-
-From the PHPMailer team:
-Author: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net (and Project Administrator)
-Author: Marcus Bointon (coolbru) coolbru@users.sourceforge.net
+ + + + + PHPMailer Examples + + +

PHPMailer code examples

+

This folder contains a collection of examples of using PHPMailer.

+
+

Security note

+

Before running these examples you'll need to rename them with '.php' extensions. They are supplied as '.phps' files which will usually be displayed with syntax highlighting by PHP instead of running them. This prevents potential security issues with running potential spam-gateway code if you happen to deploy these code examples on a live site - please don't do that! Simliarly, don't leave your passwords in these files as they will be visible to teh world!

+
+

code_generator.phps

+

This script is a simple code generator - fill in the form and hit submit, and it will use when you entered to email you a message, and will also generate PHP code using your settings that you can copy and paste to use in your own apps. If you need to get going quickly, this is probably the best place to start.

+

mail.phps

+

This script is a basic example which creates an email message from an external HTML file, creates a plain text body, sets various addresses, adds an attachment and sends the message. It uses PHP's built-in mail() function which is the simplest to use, but relies on the presence of a local mail server, something which is not usually available on Windows. If you find yourself in that sitution, either install a local mail server, or use a remote one and send using SMTP instead.

+

exceptions.phps

+

The same as the mail example, but shows how to use PHPMailer's exceptions for error handling.

+

smtp.phps

+

A simple example sending using SMTP with authentication.

+

smtp_no_auth.phps

+

A simple example sending using SMTP without authentication.

+

sendmail.phps

+

A simple example using sendmail. Sendmail is a program (usually found on Linux/BSD, OS X and other UNIX-alikes) that can be used to submit messages to a local mail server without a lengthy SMTP conversation. It's probably the fastest sending mechanism, but lacks some error reporting features. There are sendmail emulators for most popular mail servers including postfix, qmail, exim etc.

+

gmail.phps

+

Submitting email via Google's gmail service is a popular use of PHPMailer. It's much the same as normal SMTP sending, just with some specific settings, namely that sending needs to use TLS encryption, authentication is enabled, and it connects to the SMTP submission port 587 on the smtp.gmail.com host. This example does all that.

+

pop_before_smtp.phps

+

Before effective SMTP authentication mechanisms were available, it was common for ISPs to use POP-before-SMTP authentication. As it implies, you authenticate using the POP3 protocol (an older protocol now mostly replaced by the far superior IMAP), and then the SMTP server will allow send access from your IP address for a short while, usually 5-15 minutes. PHPMailer includes a POP3 protocol client, so it can carry out this sequence - it's just like a normal SMTP conversation (without authentication), but connects via POP first.

+

mailing_list.phps

+

This is a somewhat naïve example of how you could construct a mechanism for sending similar emails to a list of different addresses. It sets up a PHPMailer instance using SMTP, then connects to a MySQL database to retrieve a list of recipients. The code loops over this list, sending email to each person using their info and marks them as sent in the database. It makes use of SMTP-keepalive which saves reconnecting and re-authenticating between each message.

+
+

Most of these examples use the 'example.com' domain. This domain is reserved by IANA for illustrative purposes, as documented in RFC 2606. Don't use made-up domains like 'mydomain.com' or 'somedomain.com' in examples as someone, somewhere, probably owns them!

+ + diff --git a/examples/mail.phps b/examples/mail.phps new file mode 100644 index 00000000..71b5b401 --- /dev/null +++ b/examples/mail.phps @@ -0,0 +1,36 @@ + + + + + PHPMailer - mail() test + + +SetFrom('from@example.com', 'First Last'); +//Set an alternative reply-to address +$mail->AddReplyTo('replyto@example.com','First Last'); +//Set who the message is to be sent to +$mail->AddAddress('whoto@example.com', 'John Doe'); +//Set the subject line +$mail->Subject = 'PHPMailer mail() test'; +//Read an HTML message body from an external file, convert referenced images to embedded, convert HTML into a basic plain-text alternative body +$mail->MsgHTML(file_get_contents('contents.html'), dirname(__FILE__)); +//Replace the plain text body with one created manually +$mail->AltBody = 'This is a plain-text message body'; +//Attach an image file +$mail->AddAttachment('images/phpmailer-mini.gif'); + +//Send the message, check for errors +if(!$mail->Send()) { + echo "Mailer Error: " . $mail->ErrorInfo; +} else { + echo "Message sent!"; +} +?> + + diff --git a/examples/mailing_list.phps b/examples/mailing_list.phps new file mode 100644 index 00000000..8fbd838c --- /dev/null +++ b/examples/mailing_list.phps @@ -0,0 +1,49 @@ +IsSMTP(); +$mail->Host = 'smtp.example.com'; +$mail->SMTPAuth = true; +$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead +$mail->Host = 'mail.example.com'; +$mail->Port = 25; +$mail->Username = 'yourname@example.com'; +$mail->Password = 'yourpassword'; +$mail->SetFrom('list@example.com', 'List manager'); +$mail->AddReplyTo('list@example.com', 'List manager'); + +$mail->Subject = "PHPMailer Simple database mailing list test"; + +//Connect to the database and select the recipients from your mailing list that have not yet been sent to +//You'll need to alter this to match your database +$mysql = mysql_connect('localhost', 'username', 'password'); +mysql_select_db('mydb', $mysql); +$result = mysql_query("SELECT full_name, email, photo FROM mailinglist WHERE sent = false", $mysql); + +while ($row = mysql_fetch_array($result)) { + $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; + $mail->MsgHTML($body); + $mail->AddAddress($row['email'], $row['full_name']); + $mail->AddStringAttachment($row['photo'], 'YourPhoto.jpg'); //Assumes the image data is stored in the DB + + if(!$mail->Send()) { + echo "Mailer Error (" . str_replace("@", "@", $row["email"]) . ') ' . $mail->ErrorInfo . '
'; + break; //Abandon sending + } else { + echo "Message sent to :" . $row['full_name'] . ' (' . str_replace("@", "@", $row['email']) . ')
'; + //Mark it as sent in the DB + mysql_query("UPDATE mailinglist SET sent = true WHERE email = '".mysql_real_escape_string($row['email'], $mysql)."'"); + } + // Clear all addresses and attachments for next loop + $mail->ClearAddresses(); + $mail->ClearAttachments(); +} diff --git a/examples/pop_before_smtp.phps b/examples/pop_before_smtp.phps new file mode 100644 index 00000000..b72008e8 --- /dev/null +++ b/examples/pop_before_smtp.phps @@ -0,0 +1,63 @@ + + + + + PHPMailer - POP-before-SMTP test + + +Authorise('pop3.yourdomain.com', 110, 30, 'username', 'password', 1); +//Now you should be clear to submit messages over SMTP for a while +//Only applies if your host supports POP-before-SMTP + +//Create a new PHPMailer instance +//Passing true to the constructor enables the use of exceptions for error handling +$mail = new PHPMailer(true); +try { + $mail->IsSMTP(); + //Enable SMTP debugging + // 0 = off (for production use) + // 1 = client messages + // 2 = client and server messages + $mail->SMTPDebug = 2; + //Ask for HTML-friendly debug output + $mail->Debugoutput = 'html'; + //Set the hostname of the mail server + $mail->Host = "mail.example.com"; + //Set the SMTP port number - likely to be 25, 465 or 587 + $mail->Port = 25; + //Whether to use SMTP authentication + $mail->SMTPAuth = false; + //Set who the message is to be sent from + $mail->SetFrom('from@example.com', 'First Last'); + //Set an alternative reply-to address + $mail->AddReplyTo('replyto@example.com','First Last'); + //Set who the message is to be sent to + $mail->AddAddress('whoto@example.com', 'John Doe'); + //Set the subject line + $mail->Subject = 'PHPMailer POP-before-SMTP test'; + //Read an HTML message body from an external file, convert referenced images to embedded, + //and convert the HTML into a basic plain-text alternative body + $mail->MsgHTML(file_get_contents('contents.html'), dirname(__FILE__)); + //Replace the plain text body with one created manually + $mail->AltBody = 'This is a plain-text message body'; + //Attach an image file + $mail->AddAttachment('images/phpmailer-mini.gif'); + //Send the message + //Note that we don't need check the response from this because it will throw an exception if it has trouble + $mail->Send(); + echo "Message sent!"; +} catch (phpmailerException $e) { + echo $e->errorMessage(); //Pretty error messages from PHPMailer +} catch (Exception $e) { + echo $e->getMessage(); //Boring error messages from anything else! +} +?> + + diff --git a/examples/scripts/XRegExp.js b/examples/scripts/XRegExp.js new file mode 100755 index 00000000..ebdb9c94 --- /dev/null +++ b/examples/scripts/XRegExp.js @@ -0,0 +1,664 @@ +// XRegExp 1.5.1 +// (c) 2007-2012 Steven Levithan +// MIT License +// +// Provides an augmented, extensible, cross-browser implementation of regular expressions, +// including support for additional syntax, flags, and methods + +var XRegExp; + +if (XRegExp) { + // Avoid running twice, since that would break references to native globals + throw Error("can't load XRegExp twice in the same frame"); +} + +// Run within an anonymous function to protect variables and avoid new globals +(function (undefined) { + + //--------------------------------- + // Constructor + //--------------------------------- + + // Accepts a pattern and flags; returns a new, extended `RegExp` object. Differs from a native + // regular expression in that additional syntax and flags are supported and cross-browser + // syntax inconsistencies are ameliorated. `XRegExp(/regex/)` clones an existing regex and + // converts to type XRegExp + XRegExp = function (pattern, flags) { + var output = [], + currScope = XRegExp.OUTSIDE_CLASS, + pos = 0, + context, tokenResult, match, chr, regex; + + if (XRegExp.isRegExp(pattern)) { + if (flags !== undefined) + throw TypeError("can't supply flags when constructing one RegExp from another"); + return clone(pattern); + } + // Tokens become part of the regex construction process, so protect against infinite + // recursion when an XRegExp is constructed within a token handler or trigger + if (isInsideConstructor) + throw Error("can't call the XRegExp constructor within token definition functions"); + + flags = flags || ""; + context = { // `this` object for custom tokens + hasNamedCapture: false, + captureNames: [], + hasFlag: function (flag) {return flags.indexOf(flag) > -1;}, + setFlag: function (flag) {flags += flag;} + }; + + while (pos < pattern.length) { + // Check for custom tokens at the current position + tokenResult = runTokens(pattern, pos, currScope, context); + + if (tokenResult) { + output.push(tokenResult.output); + pos += (tokenResult.match[0].length || 1); + } else { + // Check for native multicharacter metasequences (excluding character classes) at + // the current position + if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) { + output.push(match[0]); + pos += match[0].length; + } else { + chr = pattern.charAt(pos); + if (chr === "[") + currScope = XRegExp.INSIDE_CLASS; + else if (chr === "]") + currScope = XRegExp.OUTSIDE_CLASS; + // Advance position one character + output.push(chr); + pos++; + } + } + } + + regex = RegExp(output.join(""), nativ.replace.call(flags, flagClip, "")); + regex._xregexp = { + source: pattern, + captureNames: context.hasNamedCapture ? context.captureNames : null + }; + return regex; + }; + + + //--------------------------------- + // Public properties + //--------------------------------- + + XRegExp.version = "1.5.1"; + + // Token scope bitflags + XRegExp.INSIDE_CLASS = 1; + XRegExp.OUTSIDE_CLASS = 2; + + + //--------------------------------- + // Private variables + //--------------------------------- + + var replacementToken = /\$(?:(\d\d?|[$&`'])|{([$\w]+)})/g, + flagClip = /[^gimy]+|([\s\S])(?=[\s\S]*\1)/g, // Nonnative and duplicate flags + quantifier = /^(?:[?*+]|{\d+(?:,\d*)?})\??/, + isInsideConstructor = false, + tokens = [], + // Copy native globals for reference ("native" is an ES3 reserved keyword) + nativ = { + exec: RegExp.prototype.exec, + test: RegExp.prototype.test, + match: String.prototype.match, + replace: String.prototype.replace, + split: String.prototype.split + }, + compliantExecNpcg = nativ.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups + compliantLastIndexIncrement = function () { + var x = /^/g; + nativ.test.call(x, ""); + return !x.lastIndex; + }(), + hasNativeY = RegExp.prototype.sticky !== undefined, + nativeTokens = {}; + + // `nativeTokens` match native multicharacter metasequences only (including deprecated octals, + // excluding character classes) + nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/; + nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/; + + + //--------------------------------- + // Public methods + //--------------------------------- + + // Lets you extend or change XRegExp syntax and create custom flags. This is used internally by + // the XRegExp library and can be used to create XRegExp plugins. This function is intended for + // users with advanced knowledge of JavaScript's regular expression syntax and behavior. It can + // be disabled by `XRegExp.freezeTokens` + XRegExp.addToken = function (regex, handler, scope, trigger) { + tokens.push({ + pattern: clone(regex, "g" + (hasNativeY ? "y" : "")), + handler: handler, + scope: scope || XRegExp.OUTSIDE_CLASS, + trigger: trigger || null + }); + }; + + // Accepts a pattern and flags; returns an extended `RegExp` object. If the pattern and flag + // combination has previously been cached, the cached copy is returned; otherwise the newly + // created regex is cached + XRegExp.cache = function (pattern, flags) { + var key = pattern + "/" + (flags || ""); + return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags)); + }; + + // Accepts a `RegExp` instance; returns a copy with the `/g` flag set. The copy has a fresh + // `lastIndex` (set to zero). If you want to copy a regex without forcing the `global` + // property, use `XRegExp(regex)`. Do not use `RegExp(regex)` because it will not preserve + // special properties required for named capture + XRegExp.copyAsGlobal = function (regex) { + return clone(regex, "g"); + }; + + // Accepts a string; returns the string with regex metacharacters escaped. The returned string + // can safely be used at any point within a regex to match the provided literal string. Escaped + // characters are [ ] { } ( ) * + ? - . , \ ^ $ | # and whitespace + XRegExp.escape = function (str) { + return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }; + + // Accepts a string to search, regex to search with, position to start the search within the + // string (default: 0), and an optional Boolean indicating whether matches must start at-or- + // after the position or at the specified position only. This function ignores the `lastIndex` + // of the provided regex in its own handling, but updates the property for compatibility + XRegExp.execAt = function (str, regex, pos, anchored) { + var r2 = clone(regex, "g" + ((anchored && hasNativeY) ? "y" : "")), + match; + r2.lastIndex = pos = pos || 0; + match = r2.exec(str); // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (anchored && match && match.index !== pos) + match = null; + if (regex.global) + regex.lastIndex = match ? r2.lastIndex : 0; + return match; + }; + + // Breaks the unrestorable link to XRegExp's private list of tokens, thereby preventing + // syntax and flag changes. Should be run after XRegExp and any plugins are loaded + XRegExp.freezeTokens = function () { + XRegExp.addToken = function () { + throw Error("can't run addToken after freezeTokens"); + }; + }; + + // Accepts any value; returns a Boolean indicating whether the argument is a `RegExp` object. + // Note that this is also `true` for regex literals and regexes created by the `XRegExp` + // constructor. This works correctly for variables created in another frame, when `instanceof` + // and `constructor` checks would fail to work as intended + XRegExp.isRegExp = function (o) { + return Object.prototype.toString.call(o) === "[object RegExp]"; + }; + + // Executes `callback` once per match within `str`. Provides a simpler and cleaner way to + // iterate over regex matches compared to the traditional approaches of subverting + // `String.prototype.replace` or repeatedly calling `exec` within a `while` loop + XRegExp.iterate = function (str, regex, callback, context) { + var r2 = clone(regex, "g"), + i = -1, match; + while (match = r2.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (regex.global) + regex.lastIndex = r2.lastIndex; // Doing this to follow expectations if `lastIndex` is checked within `callback` + callback.call(context, match, ++i, str, regex); + if (r2.lastIndex === match.index) + r2.lastIndex++; + } + if (regex.global) + regex.lastIndex = 0; + }; + + // Accepts a string and an array of regexes; returns the result of using each successive regex + // to search within the matches of the previous regex. The array of regexes can also contain + // objects with `regex` and `backref` properties, in which case the named or numbered back- + // references specified are passed forward to the next regex or returned. E.g.: + // var xregexpImgFileNames = XRegExp.matchChain(html, [ + // {regex: /]+)>/i, backref: 1}, // tag attributes + // {regex: XRegExp('(?ix) \\s src=" (? [^"]+ )'), backref: "src"}, // src attribute values + // {regex: XRegExp("^http://xregexp\\.com(/[^#?]+)", "i"), backref: 1}, // xregexp.com paths + // /[^\/]+$/ // filenames (strip directory paths) + // ]); + XRegExp.matchChain = function (str, chain) { + return function recurseChain (values, level) { + var item = chain[level].regex ? chain[level] : {regex: chain[level]}, + regex = clone(item.regex, "g"), + matches = [], i; + for (i = 0; i < values.length; i++) { + XRegExp.iterate(values[i], regex, function (match) { + matches.push(item.backref ? (match[item.backref] || "") : match[0]); + }); + } + return ((level === chain.length - 1) || !matches.length) ? + matches : recurseChain(matches, level + 1); + }([str], 0); + }; + + + //--------------------------------- + // New RegExp prototype methods + //--------------------------------- + + // Accepts a context object and arguments array; returns the result of calling `exec` with the + // first value in the arguments array. the context is ignored but is accepted for congruity + // with `Function.prototype.apply` + RegExp.prototype.apply = function (context, args) { + return this.exec(args[0]); + }; + + // Accepts a context object and string; returns the result of calling `exec` with the provided + // string. the context is ignored but is accepted for congruity with `Function.prototype.call` + RegExp.prototype.call = function (context, str) { + return this.exec(str); + }; + + + //--------------------------------- + // Overriden native methods + //--------------------------------- + + // Adds named capture support (with backreferences returned as `result.name`), and fixes two + // cross-browser issues per ES3: + // - Captured values for nonparticipating capturing groups should be returned as `undefined`, + // rather than the empty string. + // - `lastIndex` should not be incremented after zero-length matches. + RegExp.prototype.exec = function (str) { + var match, name, r2, origLastIndex; + if (!this.global) + origLastIndex = this.lastIndex; + match = nativ.exec.apply(this, arguments); + if (match) { + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { + r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), "g", "")); + // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed + // matching due to characters outside the match + nativ.replace.call((str + "").slice(match.index), r2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) + match[i] = undefined; + } + }); + } + // Attach named capture properties + if (this._xregexp && this._xregexp.captureNames) { + for (var i = 1; i < match.length; i++) { + name = this._xregexp.captureNames[i - 1]; + if (name) + match[name] = match[i]; + } + } + // Fix browsers that increment `lastIndex` after zero-length matches + if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + } + if (!this.global) + this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + return match; + }; + + // Fix browser bugs in native method + RegExp.prototype.test = function (str) { + // Use the native `exec` to skip some processing overhead, even though the altered + // `exec` would take care of the `lastIndex` fixes + var match, origLastIndex; + if (!this.global) + origLastIndex = this.lastIndex; + match = nativ.exec.call(this, str); + // Fix browsers that increment `lastIndex` after zero-length matches + if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + if (!this.global) + this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + return !!match; + }; + + // Adds named capture support and fixes browser bugs in native method + String.prototype.match = function (regex) { + if (!XRegExp.isRegExp(regex)) + regex = RegExp(regex); // Native `RegExp` + if (regex.global) { + var result = nativ.match.apply(this, arguments); + regex.lastIndex = 0; // Fix IE bug + return result; + } + return regex.exec(this); // Run the altered `exec` + }; + + // Adds support for `${n}` tokens for named and numbered backreferences in replacement text, + // and provides named backreferences to replacement functions as `arguments[0].name`. Also + // fixes cross-browser differences in replacement text syntax when performing a replacement + // using a nonregex search value, and the value of replacement regexes' `lastIndex` property + // during replacement iterations. Note that this doesn't support SpiderMonkey's proprietary + // third (`flags`) parameter + String.prototype.replace = function (search, replacement) { + var isRegex = XRegExp.isRegExp(search), + captureNames, result, str, origLastIndex; + + // There are too many combinations of search/replacement types/values and browser bugs that + // preclude passing to native `replace`, so don't try + //if (...) + // return nativ.replace.apply(this, arguments); + + if (isRegex) { + if (search._xregexp) + captureNames = search._xregexp.captureNames; // Array or `null` + if (!search.global) + origLastIndex = search.lastIndex; + } else { + search = search + ""; // Type conversion + } + + if (Object.prototype.toString.call(replacement) === "[object Function]") { + result = nativ.replace.call(this + "", search, function () { + if (captureNames) { + // Change the `arguments[0]` string primitive to a String object which can store properties + arguments[0] = new String(arguments[0]); + // Store named backreferences on `arguments[0]` + for (var i = 0; i < captureNames.length; i++) { + if (captureNames[i]) + arguments[0][captureNames[i]] = arguments[i + 1]; + } + } + // Update `lastIndex` before calling `replacement` (fix browsers) + if (isRegex && search.global) + search.lastIndex = arguments[arguments.length - 2] + arguments[0].length; + return replacement.apply(null, arguments); + }); + } else { + str = this + ""; // Type conversion, so `args[args.length - 1]` will be a string (given nonstring `this`) + result = nativ.replace.call(str, search, function () { + var args = arguments; // Keep this function's `arguments` available through closure + return nativ.replace.call(replacement + "", replacementToken, function ($0, $1, $2) { + // Numbered backreference (without delimiters) or special variable + if ($1) { + switch ($1) { + case "$": return "$"; + case "&": return args[0]; + case "`": return args[args.length - 1].slice(0, args[args.length - 2]); + case "'": return args[args.length - 1].slice(args[args.length - 2] + args[0].length); + // Numbered backreference + default: + // What does "$10" mean? + // - Backreference 10, if 10 or more capturing groups exist + // - Backreference 1 followed by "0", if 1-9 capturing groups exist + // - Otherwise, it's the string "$10" + // Also note: + // - Backreferences cannot be more than two digits (enforced by `replacementToken`) + // - "$01" is equivalent to "$1" if a capturing group exists, otherwise it's the string "$01" + // - There is no "$0" token ("$&" is the entire match) + var literalNumbers = ""; + $1 = +$1; // Type conversion; drop leading zero + if (!$1) // `$1` was "0" or "00" + return $0; + while ($1 > args.length - 3) { + literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers; + $1 = Math.floor($1 / 10); // Drop the last digit + } + return ($1 ? args[$1] || "" : "$") + literalNumbers; + } + // Named backreference or delimited numbered backreference + } else { + // What does "${n}" mean? + // - Backreference to numbered capture n. Two differences from "$n": + // - n can be more than two digits + // - Backreference 0 is allowed, and is the entire match + // - Backreference to named capture n, if it exists and is not a number overridden by numbered capture + // - Otherwise, it's the string "${n}" + var n = +$2; // Type conversion; drop leading zeros + if (n <= args.length - 3) + return args[n]; + n = captureNames ? indexOf(captureNames, $2) : -1; + return n > -1 ? args[n + 1] : $0; + } + }); + }); + } + + if (isRegex) { + if (search.global) + search.lastIndex = 0; // Fix IE, Safari bug (last tested IE 9.0.5, Safari 5.1.2 on Windows) + else + search.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + } + + return result; + }; + + // A consistent cross-browser, ES3 compliant `split` + String.prototype.split = function (s /* separator */, limit) { + // If separator `s` is not a regex, use the native `split` + if (!XRegExp.isRegExp(s)) + return nativ.split.apply(this, arguments); + + var str = this + "", // Type conversion + output = [], + lastLastIndex = 0, + match, lastLength; + + // Behavior for `limit`: if it's... + // - `undefined`: No limit + // - `NaN` or zero: Return an empty array + // - A positive number: Use `Math.floor(limit)` + // - A negative number: No limit + // - Other: Type-convert, then use the above rules + if (limit === undefined || +limit < 0) { + limit = Infinity; + } else { + limit = Math.floor(+limit); + if (!limit) + return []; + } + + // This is required if not `s.global`, and it avoids needing to set `s.lastIndex` to zero + // and restore it to its original value when we're done using the regex + s = XRegExp.copyAsGlobal(s); + + while (match = s.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (s.lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + + if (match.length > 1 && match.index < str.length) + Array.prototype.push.apply(output, match.slice(1)); + + lastLength = match[0].length; + lastLastIndex = s.lastIndex; + + if (output.length >= limit) + break; + } + + if (s.lastIndex === match.index) + s.lastIndex++; + } + + if (lastLastIndex === str.length) { + if (!nativ.test.call(s, "") || lastLength) + output.push(""); + } else { + output.push(str.slice(lastLastIndex)); + } + + return output.length > limit ? output.slice(0, limit) : output; + }; + + + //--------------------------------- + // Private helper functions + //--------------------------------- + + // Supporting function for `XRegExp`, `XRegExp.copyAsGlobal`, etc. Returns a copy of a `RegExp` + // instance with a fresh `lastIndex` (set to zero), preserving properties required for named + // capture. Also allows adding new flags in the process of copying the regex + function clone (regex, additionalFlags) { + if (!XRegExp.isRegExp(regex)) + throw TypeError("type RegExp expected"); + var x = regex._xregexp; + regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || "")); + if (x) { + regex._xregexp = { + source: x.source, + captureNames: x.captureNames ? x.captureNames.slice(0) : null + }; + } + return regex; + } + + function getNativeFlags (regex) { + return (regex.global ? "g" : "") + + (regex.ignoreCase ? "i" : "") + + (regex.multiline ? "m" : "") + + (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 + (regex.sticky ? "y" : ""); + } + + function runTokens (pattern, index, scope, context) { + var i = tokens.length, + result, match, t; + // Protect against constructing XRegExps within token handler and trigger functions + isInsideConstructor = true; + // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws + try { + while (i--) { // Run in reverse order + t = tokens[i]; + if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) { + t.pattern.lastIndex = index; + match = t.pattern.exec(pattern); // Running the altered `exec` here allows use of named backreferences, etc. + if (match && match.index === index) { + result = { + output: t.handler.call(context, match, scope), + match: match + }; + break; + } + } + } + } catch (err) { + throw err; + } finally { + isInsideConstructor = false; + } + return result; + } + + function indexOf (array, item, from) { + if (Array.prototype.indexOf) // Use the native array method if available + return array.indexOf(item, from); + for (var i = from || 0; i < array.length; i++) { + if (array[i] === item) + return i; + } + return -1; + } + + + //--------------------------------- + // Built-in tokens + //--------------------------------- + + // Augment XRegExp's regular expression syntax and flags. Note that when adding tokens, the + // third (`scope`) argument defaults to `XRegExp.OUTSIDE_CLASS` + + // Comment pattern: (?# ) + XRegExp.addToken( + /\(\?#[^)]*\)/, + function (match) { + // Keep tokens separated unless the following token is a quantifier + return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)"; + } + ); + + // Capturing group (match the opening parenthesis only). + // Required for support of named capturing groups + XRegExp.addToken( + /\((?!\?)/, + function () { + this.captureNames.push(null); + return "("; + } + ); + + // Named capturing group (match the opening delimiter only): (? + XRegExp.addToken( + /\(\?<([$\w]+)>/, + function (match) { + this.captureNames.push(match[1]); + this.hasNamedCapture = true; + return "("; + } + ); + + // Named backreference: \k + XRegExp.addToken( + /\\k<([\w$]+)>/, + function (match) { + var index = indexOf(this.captureNames, match[1]); + // Keep backreferences separate from subsequent literal numbers. Preserve back- + // references to named groups that are undefined at this point as literal strings + return index > -1 ? + "\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? "" : "(?:)") : + match[0]; + } + ); + + // Empty character class: [] or [^] + XRegExp.addToken( + /\[\^?]/, + function (match) { + // For cross-browser compatibility with ES3, convert [] to \b\B and [^] to [\s\S]. + // (?!) should work like \b\B, but is unreliable in Firefox + return match[0] === "[]" ? "\\b\\B" : "[\\s\\S]"; + } + ); + + // Mode modifier at the start of the pattern only, with any combination of flags imsx: (?imsx) + // Does not support x(?i), (?-i), (?i-m), (?i: ), (?i)(?m), etc. + XRegExp.addToken( + /^\(\?([imsx]+)\)/, + function (match) { + this.setFlag(match[1]); + return ""; + } + ); + + // Whitespace and comments, in free-spacing (aka extended) mode only + XRegExp.addToken( + /(?:\s+|#.*)+/, + function (match) { + // Keep tokens separated unless the following token is a quantifier + return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)"; + }, + XRegExp.OUTSIDE_CLASS, + function () {return this.hasFlag("x");} + ); + + // Dot, in dotall (aka singleline) mode only + XRegExp.addToken( + /\./, + function () {return "[\\s\\S]";}, + XRegExp.OUTSIDE_CLASS, + function () {return this.hasFlag("s");} + ); + + + //--------------------------------- + // Backward compatibility + //--------------------------------- + + // Uncomment the following block for compatibility with XRegExp 1.0-1.2: + /* + XRegExp.matchWithinChain = XRegExp.matchChain; + RegExp.prototype.addFlags = function (s) {return clone(this, s);}; + RegExp.prototype.execAll = function (s) {var r = []; XRegExp.iterate(s, this, function (m) {r.push(m);}); return r;}; + RegExp.prototype.forEachExec = function (s, f, c) {return XRegExp.iterate(s, this, f, c);}; + RegExp.prototype.validate = function (s) {var r = RegExp("^(?:" + this.source + ")$(?!\\s)", getNativeFlags(this)); if (this.global) this.lastIndex = 0; return s.search(r) === 0;}; + */ + +})(); + diff --git a/examples/scripts/shAutoloader.js b/examples/scripts/shAutoloader.js new file mode 100644 index 00000000..9f5942ee --- /dev/null +++ b/examples/scripts/shAutoloader.js @@ -0,0 +1,122 @@ +(function() { + +var sh = SyntaxHighlighter; + +/** + * Provides functionality to dynamically load only the brushes that a needed to render the current page. + * + * There are two syntaxes that autoload understands. For example: + * + * SyntaxHighlighter.autoloader( + * [ 'applescript', 'Scripts/shBrushAppleScript.js' ], + * [ 'actionscript3', 'as3', 'Scripts/shBrushAS3.js' ] + * ); + * + * or a more easily comprehendable one: + * + * SyntaxHighlighter.autoloader( + * 'applescript Scripts/shBrushAppleScript.js', + * 'actionscript3 as3 Scripts/shBrushAS3.js' + * ); + */ +sh.autoloader = function() +{ + var list = arguments, + elements = sh.findElements(), + brushes = {}, + scripts = {}, + all = SyntaxHighlighter.all, + allCalled = false, + allParams = null, + i + ; + + SyntaxHighlighter.all = function(params) + { + allParams = params; + allCalled = true; + }; + + function addBrush(aliases, url) + { + for (var i = 0; i < aliases.length; i++) + brushes[aliases[i]] = url; + }; + + function getAliases(item) + { + return item.pop + ? item + : item.split(/\s+/) + ; + } + + // create table of aliases and script urls + for (i = 0; i < list.length; i++) + { + var aliases = getAliases(list[i]), + url = aliases.pop() + ; + + addBrush(aliases, url); + } + + // dynamically add tags. */ - scriptScriptTags : { left: /(<|<)\s*script.*?(>|>)/gi, right: /(<|<)\/\s*script\s*(>|>)/gi } - }, - - toolbar : { - /** - * Creates new toolbar for a highlighter. - * @param {Highlighter} highlighter Target highlighter. - */ - create : function(highlighter) - { - var div = document.createElement('DIV'), - items = sh.toolbar.items - ; - - div.className = 'toolbar'; - - for (var name in items) - { - var constructor = items[name], - command = new constructor(highlighter), - element = command.create() - ; - - highlighter.toolbarCommands[name] = command; - - if (element == null) - continue; - - if (typeof(element) == 'string') - element = sh.toolbar.createButton(element, highlighter.id, name); - - element.className += 'item ' + name; - div.appendChild(element); - } - - return div; - }, - - /** - * Create a standard anchor button for the toolbar. - * @param {String} label Label text to display. - * @param {String} highlighterId Highlighter ID that this button would belong to. - * @param {String} commandName Command name that would be executed. - * @return {Element} Returns an 'A' element. - */ - createButton : function(label, highlighterId, commandName) - { - var a = document.createElement('a'), - style = a.style, - config = sh.config, - width = config.toolbarItemWidth, - height = config.toolbarItemHeight - ; - - a.href = '#' + commandName; - a.title = label; - a.highlighterId = highlighterId; - a.commandName = commandName; - a.innerHTML = label; - - if (isNaN(width) == false) - style.width = width + 'px'; - - if (isNaN(height) == false) - style.height = height + 'px'; - - a.onclick = function(e) - { - try - { - sh.toolbar.executeCommand( - this, - e || window.event, - this.highlighterId, - this.commandName - ); - } - catch(e) - { - sh.utils.alert(e.message); - } - - return false; - }; - - return a; - }, - - /** - * Executes a toolbar command. - * @param {Element} sender Sender element. - * @param {MouseEvent} event Original mouse event object. - * @param {String} highlighterId Highlighter DIV element ID. - * @param {String} commandName Name of the command to execute. - * @return {Object} Passes out return value from command execution. - */ - executeCommand : function(sender, event, highlighterId, commandName, args) - { - var highlighter = sh.vars.highlighters[highlighterId], - command - ; - - if (highlighter == null || (command = highlighter.toolbarCommands[commandName]) == null) - return null; - - return command.execute(sender, event, args); - }, - - /** Collection of toolbar items. */ - items : { - expandSource : function(highlighter) - { - this.create = function() - { - if (highlighter.getParam('collapse') != true) - return; - - return sh.config.strings.expandSource; - }; - - this.execute = function(sender, event, args) - { - var div = highlighter.div; - - sender.parentNode.removeChild(sender); - div.className = div.className.replace('collapsed', ''); - }; - }, - - /** - * Command to open a new window and display the original unformatted source code inside. - */ - viewSource : function(highlighter) - { - this.create = function() - { - return sh.config.strings.viewSource; - }; - - this.execute = function(sender, event, args) - { - var code = sh.utils.fixForBlogger(highlighter.originalCode).replace(/' + code + ''); - wnd.document.close(); - }; - }, - - /** - * Command to copy the original source code in to the clipboard. - * Uses Flash method if clipboardSwf is configured. - */ - copyToClipboard : function(highlighter) - { - var flashDiv, flashSwf, - highlighterId = highlighter.id - ; - - this.create = function() - { - var config = sh.config; - - // disable functionality if running locally - if (config.clipboardSwf == null) - return null; - - function params(list) - { - var result = ''; - - for (var name in list) - result += ""; - - return result; - }; - - function attributes(list) - { - var result = ''; - - for (var name in list) - result += " " + name + "='" + list[name] + "'"; - - return result; - }; - - var args1 = { - width : config.toolbarItemWidth, - height : config.toolbarItemHeight, - id : highlighterId + '_clipboard', - type : 'application/x-shockwave-flash', - title : sh.config.strings.copyToClipboard - }, - - // these arguments are used in IE's collection - args2 = { - allowScriptAccess : 'always', - wmode : 'transparent', - flashVars : 'highlighterId=' + highlighterId, - menu : 'false' - }, - swf = config.clipboardSwf, - html - ; - - if (/msie/i.test(navigator.userAgent)) - { - html = '' - + params(args2) - + params({ movie : swf }) - + '' - ; - } - else - { - html = '' - ; - } - - flashDiv = document.createElement('div'); - flashDiv.innerHTML = html; - - return flashDiv; - }; - - this.execute = function(sender, event, args) - { - var command = args.command; - - switch (command) - { - case 'get': - var code = sh.utils.unindent( - sh.utils.fixForBlogger(highlighter.originalCode) - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/&/g, '&') - ); - - if(window.clipboardData) - // will fall through to the confirmation because there isn't a break - window.clipboardData.setData('text', code); - else - return sh.utils.unindent(code); - - case 'ok': - sh.utils.alert(sh.config.strings.copyToClipboardConfirmation); - break; - - case 'error': - sh.utils.alert(args.message); - break; - } - }; - }, - - /** Command to print the colored source code. */ - printSource : function(highlighter) - { - this.create = function() - { - return sh.config.strings.print; - }; - - this.execute = function(sender, event, args) - { - var iframe = document.createElement('IFRAME'), - doc = null - ; - - // make sure there is never more than one hidden iframe created by SH - if (sh.vars.printFrame != null) - document.body.removeChild(sh.vars.printFrame); - - sh.vars.printFrame = iframe; - - // this hides the iframe - iframe.style.cssText = 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;'; - - document.body.appendChild(iframe); - doc = iframe.contentWindow.document; - - copyStyles(doc, window.document); - doc.write('
' + highlighter.div.innerHTML + '
'); - doc.close(); - - iframe.contentWindow.focus(); - iframe.contentWindow.print(); - - function copyStyles(destDoc, sourceDoc) - { - var links = sourceDoc.getElementsByTagName('link'); - - for(var i = 0; i < links.length; i++) - if(links[i].rel.toLowerCase() == 'stylesheet' && /shCore\.css$/.test(links[i].href)) - destDoc.write(''); - }; - }; - }, - - /** Command to display the about dialog window. */ - about : function(highlighter) - { - this.create = function() - { - return sh.config.strings.help; - }; - - this.execute = function(sender, event) - { - var wnd = sh.utils.popup('', '_blank', 500, 250, 'scrollbars=0'), - doc = wnd.document - ; - - doc.write(sh.config.strings.aboutDialog); - doc.close(); - wnd.focus(); - }; - } - } - }, - - utils : { - guid : function(prefix) - { - return prefix + Math.round(Math.random() * 1000000).toString(); - }, - - /** - * Merges two objects. Values from obj2 override values in obj1. - * Function is NOT recursive and works only for one dimensional objects. - * @param {Object} obj1 First object. - * @param {Object} obj2 Second object. - * @return {Object} Returns combination of both objects. - */ - merge: function(obj1, obj2) - { - var result = {}, name; - - for (name in obj1) - result[name] = obj1[name]; - - for (name in obj2) - result[name] = obj2[name]; - - return result; - }, - - /** - * Attempts to convert string to boolean. - * @param {String} value Input string. - * @return {Boolean} Returns true if input was "true", false if input was "false" and value otherwise. - */ - toBoolean: function(value) - { - switch (value) - { - case "true": - return true; - - case "false": - return false; - } - - return value; - }, - - /** - * Opens up a centered popup window. - * @param {String} url URL to open in the window. - * @param {String} name Popup name. - * @param {int} width Popup width. - * @param {int} height Popup height. - * @param {String} options window.open() options. - * @return {Window} Returns window instance. - */ - popup: function(url, name, width, height, options) - { - var x = (screen.width - width) / 2, - y = (screen.height - height) / 2 - ; - - options += ', left=' + x + - ', top=' + y + - ', width=' + width + - ', height=' + height - ; - options = options.replace(/^,/, ''); - - var win = window.open(url, name, options); - win.focus(); - return win; - }, - - /** - * Adds event handler to the target object. - * @param {Object} obj Target object. - * @param {String} type Name of the event. - * @param {Function} func Handling function. - */ - addEvent: function(obj, type, func) - { - if (obj.attachEvent) - { - obj['e' + type + func] = func; - obj[type + func] = function() - { - obj['e' + type + func](window.event); - } - obj.attachEvent('on' + type, obj[type + func]); - } - else - { - obj.addEventListener(type, func, false); - } - }, - - /** - * Displays an alert. - * @param {String} str String to display. - */ - alert: function(str) - { - alert(sh.config.strings.alert + str) - }, - - /** - * Finds a brush by its alias. - * - * @param {String} alias Brush alias. - * @param {Boolean} alert Suppresses the alert if false. - * @return {Brush} Returns bursh constructor if found, null otherwise. - */ - findBrush: function(alias, alert) - { - var brushes = sh.vars.discoveredBrushes, - result = null - ; - - if (brushes == null) - { - brushes = {}; - - // Find all brushes - for (var brush in sh.brushes) - { - var aliases = sh.brushes[brush].aliases; - - if (aliases == null) - continue; - - for (var i = 0; i < aliases.length; i++) - brushes[aliases[i]] = brush; - } - - sh.vars.discoveredBrushes = brushes; - } - - result = sh.brushes[brushes[alias]]; - - if (result == null && alert != false) - sh.utils.alert(sh.config.strings.noBrush + alias); - - return result; - }, - - /** - * Executes a callback on each line and replaces each line with result from the callback. - * @param {Object} str Input string. - * @param {Object} callback Callback function taking one string argument and returning a string. - */ - eachLine: function(str, callback) - { - var lines = str.split('\n'); - - for (var i = 0; i < lines.length; i++) - lines[i] = callback(lines[i]); - - return lines.join('\n'); - }, - - /** - * Creates rules looking div. - */ - createRuler: function() - { - var div = document.createElement('div'), - ruler = document.createElement('div'), - showEvery = 10, - i = 1 - ; - - while (i <= 150) - { - if (i % showEvery === 0) - { - div.innerHTML += i; - i += (i + '').length; - } - else - { - div.innerHTML += '·'; - i++; - } - } - - ruler.className = 'ruler line'; - ruler.appendChild(div); - - return ruler; - }, - - /** - * This is a special trim which only removes first and last empty lines - * and doesn't affect valid leading space on the first line. - * - * @param {String} str Input string - * @return {String} Returns string without empty first and last lines. - */ - trimFirstAndLastLines: function(str) - { - return str.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g, ''); - }, - - /** - * Parses key/value pairs into hash object. - * - * Understands the following formats: - * - name: word; - * - name: [word, word]; - * - name: "string"; - * - name: 'string'; - * - * For example: - * name1: value; name2: [value, value]; name3: 'value' - * - * @param {String} str Input string. - * @return {Object} Returns deserialized object. - */ - parseParams: function(str) - { - var match, - result = {}, - arrayRegex = new XRegExp("^\\[(?(.*?))\\]$"), - regex = new XRegExp( - "(?[\\w-]+)" + - "\\s*:\\s*" + - "(?" + - "[\\w-%#]+|" + // word - "\\[.*?\\]|" + // [] array - '".*?"|' + // "" string - "'.*?'" + // '' string - ")\\s*;?", - "g" - ) - ; - - while ((match = regex.exec(str)) != null) - { - var value = match.value - .replace(/^['"]|['"]$/g, '') // strip quotes from end of strings - ; - - // try to parse array value - if (value != null && arrayRegex.test(value)) - { - var m = arrayRegex.exec(value); - value = m.values.length > 0 ? m.values.split(/\s*,\s*/) : []; - } - - result[match.name] = value; - } - - return result; - }, - - /** - * Wraps each line of the string into tag with given style applied to it. - * - * @param {String} str Input string. - * @param {String} css Style name to apply to the string. - * @return {String} Returns input string with each line surrounded by tag. - */ - decorate: function(str, css) - { - if (str == null || str.length == 0 || str == '\n') - return str; - - str = str.replace(/... to them so that - // leading spaces aren't included. - if (css != null) - str = sh.utils.eachLine(str, function(line) - { - if (line.length == 0) - return ''; - - var spaces = ''; - - line = line.replace(/^( | )+/, function(s) - { - spaces = s; - return ''; - }); - - if (line.length == 0) - return spaces; - - return spaces + '' + line + ''; - }); - - return str; - }, - - /** - * Pads number with zeros until it's length is the same as given length. - * - * @param {Number} number Number to pad. - * @param {Number} length Max string length with. - * @return {String} Returns a string padded with proper amount of '0'. - */ - padNumber : function(number, length) - { - var result = number.toString(); - - while (result.length < length) - result = '0' + result; - - return result; - }, - - /** - * Measures width of a single space character. - * @return {Number} Returns width of a single space character. - */ - measureSpace : function() - { - var container = document.createElement('div'), - span, - result = 0, - body = document.body, - id = sh.utils.guid('measureSpace'), - - // variable names will be compressed, so it's better than a plain string - divOpen = '
' - + divOpen + 'lines">' - + divOpen + 'line">' - + divOpen + 'content' - + '"> ' + closeSpan + closeSpan - + closeDiv - + closeDiv - + closeDiv - + closeDiv - ; - - body.appendChild(container); - span = document.getElementById(id); - - if (/opera/i.test(navigator.userAgent)) - { - var style = window.getComputedStyle(span, null); - result = parseInt(style.getPropertyValue("width")); - } - else - { - result = span.offsetWidth; - } - - body.removeChild(container); - - return result; - }, - - /** - * Replaces tabs with spaces. - * - * @param {String} code Source code. - * @param {Number} tabSize Size of the tab. - * @return {String} Returns code with all tabs replaces by spaces. - */ - processTabs : function(code, tabSize) - { - var tab = ''; - - for (var i = 0; i < tabSize; i++) - tab += ' '; - - return code.replace(/\t/g, tab); - }, - - /** - * Replaces tabs with smart spaces. - * - * @param {String} code Code to fix the tabs in. - * @param {Number} tabSize Number of spaces in a column. - * @return {String} Returns code with all tabs replaces with roper amount of spaces. - */ - processSmartTabs : function(code, tabSize) - { - var lines = code.split('\n'), - tab = '\t', - spaces = '' - ; - - // Create a string with 1000 spaces to copy spaces from... - // It's assumed that there would be no indentation longer than that. - for (var i = 0; i < 50; i++) - spaces += ' '; // 20 spaces * 50 - - // This function inserts specified amount of spaces in the string - // where a tab is while removing that given tab. - function insertSpaces(line, pos, count) - { - return line.substr(0, pos) - + spaces.substr(0, count) - + line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab - ; - }; - - // Go through all the lines and do the 'smart tabs' magic. - code = sh.utils.eachLine(code, function(line) - { - if (line.indexOf(tab) == -1) - return line; - - var pos = 0; - - while ((pos = line.indexOf(tab)) != -1) - { - // This is pretty much all there is to the 'smart tabs' logic. - // Based on the position within the line and size of a tab, - // calculate the amount of spaces we need to insert. - var spaces = tabSize - pos % tabSize; - line = insertSpaces(line, pos, spaces); - } - - return line; - }); - - return code; - }, - - fixForBlogger : function(str) - { - return (sh.config.bloggerMode == true) ? str.replace(/|<br\s*\/?>/gi, '\n') : str; - }, - - /** - * Removes all white space at the begining and end of a string. - * - * @param {String} str String to trim. - * @return {String} Returns string without leading and following white space characters. - */ - trim: function(str) - { - return str.replace(/\s*$/g, '').replace(/^\s*/, ''); - }, - - /** - * Unindents a block of text by the lowest common indent amount. - * @param {String} str Text to unindent. - * @return {String} Returns unindented text block. - */ - unindent: function(str) - { - var lines = sh.utils.fixForBlogger(str).split('\n'), - indents = new Array(), - regex = /^\s*/, - min = 1000 - ; - - // go through every line and check for common number of indents - for (var i = 0; i < lines.length && min > 0; i++) - { - var line = lines[i]; - - if (sh.utils.trim(line).length == 0) - continue; - - var matches = regex.exec(line); - - // In the event that just one line doesn't have leading white space - // we can't unindent anything, so bail completely. - if (matches == null) - return str; - - min = Math.min(matches[0].length, min); - } - - // trim minimum common number of white space from the begining of every line - if (min > 0) - for (var i = 0; i < lines.length; i++) - lines[i] = lines[i].substr(min); - - return lines.join('\n'); - }, - - /** - * Callback method for Array.sort() which sorts matches by - * index position and then by length. - * - * @param {Match} m1 Left object. - * @param {Match} m2 Right object. - * @return {Number} Returns -1, 0 or -1 as a comparison result. - */ - matchesSortCallback: function(m1, m2) - { - // sort matches by index first - if(m1.index < m2.index) - return -1; - else if(m1.index > m2.index) - return 1; - else - { - // if index is the same, sort by length - if(m1.length < m2.length) - return -1; - else if(m1.length > m2.length) - return 1; - } - - return 0; - }, - - /** - * Executes given regular expression on provided code and returns all - * matches that are found. - * - * @param {String} code Code to execute regular expression on. - * @param {Object} regex Regular expression item info from regexList collection. - * @return {Array} Returns a list of Match objects. - */ - getMatches: function(code, regexInfo) - { - function defaultAdd(match, regexInfo) - { - return [new sh.Match(match[0], match.index, regexInfo.css)]; - }; - - var index = 0, - match = null, - result = [], - func = regexInfo.func ? regexInfo.func : defaultAdd - ; - - while((match = regexInfo.regex.exec(code)) != null) - result = result.concat(func(match, regexInfo)); - - return result; - }, - - processUrls: function(code) - { - return code.replace(sh.regexLib.url, function(m) - { - return '' + m + ''; - }); - } - }, // end of utils - - /** - * Shorthand to highlight all elements on the page that are marked as - * SyntaxHighlighter source code. - * - * @param {Object} globalParams Optional parameters which override element's - * parameters. Only used if element is specified. - * - * @param {Object} element Optional element to highlight. If none is - * provided, all elements in the current document - * are highlighted. - */ - highlight : function(globalParams, element) - { - function toArray(source) - { - var result = []; - - for (var i = 0; i < source.length; i++) - result.push(source[i]); - - return result; - }; - - var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)), - propertyName = 'innerHTML', - highlighter = null - ; - - if (elements.length === 0) - return; - - for (var i = 0; i < elements.length; i++) - { - var target = elements[i], - params = sh.utils.parseParams(target.className), - brushName - ; - - // local params take precedence over globals - params = sh.utils.merge(globalParams, params); - brushName = params['brush']; - - if (brushName == null) - continue; - - // Instantiate a brush - if (params['html-script'] == 'true') - { - highlighter = new sh.HtmlScript(brushName); - } - else - { - var brush = sh.utils.findBrush(brushName); - - if (brush) - highlighter = new brush(); - else - continue; - } - - highlighter.highlight(target[propertyName], params); - - var result = highlighter.div; - - if (sh.config.debug) - { - result = document.createElement('textarea'); - result.value = highlighter.div.innerHTML; - result.style.width = '70em'; - result.style.height = '30em'; - } - - target.parentNode.replaceChild(result, target); - } - }, - - /** - * Main entry point for the SyntaxHighlighter. - * @param {Object} params Optional params to apply to all highlighted elements. - */ - all : function(params) - { - sh.utils.addEvent( - window, - 'load', - function() { sh.highlight(params); } - ); - } -}; // end of sh - -/** Match object */ -sh.Match = function(value, index, css) -{ - this.value = value; - this.index = index; - this.length = value.length; - this.css = css; -}; - -sh.Match.prototype.toString = function() -{ - return this.value; -}; - -/** - * Simulates HTML code with a scripting language embedded. - * - * @param {String} scriptBrushName Brush name of the scripting language. - */ -sh.HtmlScript = function(scriptBrushName) -{ - var scriptBrush = sh.utils.findBrush(scriptBrushName), - xmlBrush = new sh.brushes.Xml(), - bracketsRegex = null - ; - - if (scriptBrush == null) - return; - - scriptBrush = new scriptBrush(); - this.xmlBrush = xmlBrush; - - if (scriptBrush.htmlScript == null) - { - sh.utils.alert(sh.config.strings.brushNotHtmlScript + scriptBrushName); - return; - } - - xmlBrush.regexList.push( - { regex: scriptBrush.htmlScript.code, func: process } - ); - - function offsetMatches(matches, offset) - { - for (var j = 0; j < matches.length; j++) - matches[j].index += offset; - } - - function process(match, info) - { - var code = match.code, - matches = [], - regexList = scriptBrush.regexList, - offset = match.index + match.left.length, - htmlScript = scriptBrush.htmlScript, - result - ; - - for (var i = 0; i < regexList.length; i++) - { - result = sh.utils.getMatches(code, regexList[i]); - offsetMatches(result, offset); - matches = matches.concat(result); - } - - if (htmlScript.left != null && match.left != null) - { - result = sh.utils.getMatches(match.left, htmlScript.left); - offsetMatches(result, match.index); - matches = matches.concat(result); - } - - if (htmlScript.right != null && match.right != null) - { - result = sh.utils.getMatches(match.right, htmlScript.right); - offsetMatches(result, match.index + match[0].lastIndexOf(match.right)); - matches = matches.concat(result); - } - - return matches; - } -}; - -sh.HtmlScript.prototype.highlight = function(code, params) -{ - this.xmlBrush.highlight(code, params); - this.div = this.xmlBrush.div; -} - -/** - * Main Highlither class. - * @constructor - */ -sh.Highlighter = function() -{ -}; - -sh.Highlighter.prototype = { - /** - * Returns value of the parameter passed to the highlighter. - * @param {String} name Name of the parameter. - * @param {Object} defaultValue Default value. - * @return {Object} Returns found value or default value otherwise. - */ - getParam : function(name, defaultValue) - { - var result = this.params[name]; - return sh.utils.toBoolean(result == null ? defaultValue : result); - }, - - /** - * Shortcut to document.createElement(). - * @param {String} name Name of the element to create (DIV, A, etc). - * @return {HTMLElement} Returns new HTML element. - */ - create: function(name) - { - return document.createElement(name); - }, - - /** - * Checks if one match is inside another. - * @param {Match} match Match object to check. - * @return {Boolean} Returns true if given match was inside another, false otherwise. - */ - isMatchNested: function(match) - { - for (var i = 0; i < this.matches.length; i++) - { - var item = this.matches[i]; - - if (item === null) - continue; - - if ((match.index > item.index) && (match.index < item.index + item.length)) - return true; - } - - return false; - }, - - /** - * Applies all regular expression to the code and stores all found - * matches in the `this.matches` array. - * @param {Array} regexList List of regular expressions. - * @param {String} code Source code. - * @return {Array} Returns list of matches. - */ - findMatches: function(regexList, code) - { - var result = []; - - if (regexList != null) - for (var i = 0; i < regexList.length; i++) - result = result.concat(sh.utils.getMatches(code, regexList[i])); - - // sort the matches - result = result.sort(sh.utils.matchesSortCallback); - - return result; - }, - - /** - * Checks to see if any of the matches are inside of other matches. - * This process would get rid of highligted strings inside comments, - * keywords inside strings and so on. - */ - removeNestedMatches: function() - { - for (var i = 0; i < this.matches.length; i++) - if (this.isMatchNested(this.matches[i])) - this.matches[i] = null; - }, - - /** - * Splits block of text into individual DIV lines. - * @param {String} code Code to highlight. - * @return {String} Returns highlighted code in HTML form. - */ - createDisplayLines : function(code) - { - var lines = code.split(/\n/g), - firstLine = parseInt(this.getParam('first-line')), - padLength = (firstLine + lines.length).toString().length, - highlightedLines = this.getParam('highlight', []) - ; - - code = ''; - - for (var i = 0; i < lines.length; i++) - { - var line = lines[i], - indent = /^( |\s)+/.exec(line), - lineClass = 'line alt' + (i % 2 == 0 ? 1 : 2), - lineNumber = sh.utils.padNumber(firstLine + i, padLength), - highlighted = highlightedLines.indexOf((firstLine + i).toString()) != -1, - spaces = null - ; - - if (indent != null) - { - spaces = indent[0].toString(); - line = line.substr(spaces.length); - spaces = spaces.replace(/ /g, ' '); - indent = sh.vars.spaceWidth * spaces.length; - } - else - { - indent = 0; - } - - line = sh.utils.trim(line); - - if (line.length == 0) - line = ' '; - - if (highlighted) - lineClass += ' highlighted'; - - code += - '
' - + '' + lineNumber + '.' - + '' - + (spaces != null ? '' + spaces.replace(/\s/g, ' ') + '' : '') - + '' + line + '' - + '' - + '
' - ; - } - - return code; - }, - - /** - * Finds all matches in the source code. - * @param {String} code Source code to process matches in. - * @param {Array} matches Discovered regex matches. - * @return {String} Returns formatted HTML with processed mathes. - */ - processMatches: function(code, matches) - { - var pos = 0, - result = '', - decorate = sh.utils.decorate // make an alias to save some bytes - ; - - // Finally, go through the final list of matches and pull the all - // together adding everything in between that isn't a match. - for (var i = 0; i < matches.length; i++) - { - var match = matches[i]; - - if (match === null || match.length === 0) - continue; - - result += decorate(code.substr(pos, match.index - pos), 'plain') - + decorate(match.value, match.css) - ; - - pos = match.index + match.length; - } - - // don't forget to add whatever's remaining in the string - result += decorate(code.substr(pos), 'plain'); - - return result; - }, - - /** - * Highlights the code and returns complete HTML. - * @param {String} code Code to highlight. - * @param {Object} params Parameters object. - */ - highlight: function(code, params) - { - var conf = sh.config, - vars = sh.vars, - div, - tabSize - ; - - this.params = {}; - this.div = null; - this.lines = null; - this.code = null; - this.bar = null; - this.toolbarCommands = {}; - this.id = sh.utils.guid('highlighter_'); - - // register this instance in the highlighters list - vars.highlighters[this.id] = this; - - if (code === null) - code = ''; - - // Measure width of a single space. - if (vars.spaceWidth === null) - vars.spaceWidth = sh.utils.measureSpace(); - - // local params take precedence over defaults - this.params = sh.utils.merge(sh.defaults, params || {}); - - // process light mode - if (this.getParam('light') == true) - this.params.toolbar = this.params.gutter = false; - - this.div = div = this.create('DIV'); - this.lines = this.create('DIV'); - this.lines.className = 'lines'; - - div.className = 'syntaxhighlighter'; - div.id = this.id; - - if (this.getParam('collapse')) - div.className += ' collapsed'; - - if (this.getParam('gutter') == false) - div.className += ' nogutter'; - - div.className += ' ' + this.getParam('class-name'); - div.style.fontSize = this.getParam('font-size', ''); // IE7 can't take null - - this.originalCode = code; - this.code = sh.utils.trimFirstAndLastLines(code) - .replace(/\r/g, ' ') // IE lets these buggers through - ; - - tabSize = this.getParam('tab-size'); - - // replace tabs with spaces - this.code = this.getParam('smart-tabs') == true - ? sh.utils.processSmartTabs(this.code, tabSize) - : sh.utils.processTabs(this.code, tabSize) - ; - - this.code = sh.utils.unindent(this.code); - - // add controls toolbar - if (this.getParam('toolbar')) - { - this.bar = this.create('DIV'); - this.bar.className = 'bar'; - this.bar.appendChild(sh.toolbar.create(this)); - div.appendChild(this.bar); - } - - // add columns ruler - if (this.getParam('ruler')) - div.appendChild(sh.utils.createRuler()); - - div.appendChild(this.lines); - - this.matches = this.findMatches(this.regexList, this.code); - this.removeNestedMatches(); - - code = this.processMatches(this.code, this.matches); - - // finally, split all lines so that they wrap well - code = this.createDisplayLines(sh.utils.trim(code)); - - // finally, process the links - if (this.getParam('auto-links')) - code = sh.utils.processUrls(code); - - this.lines.innerHTML = code; - }, - - /** - * Converts space separated list of keywords into a regular expression string. - * @param {String} str Space separated keywords. - * @return {String} Returns regular expression string. - */ - getKeywords: function(str) - { - str = str - .replace(/^\s+|\s+$/g, '') - .replace(/\s+/g, '\\b|\\b') - ; - - return '\\b' + str + '\\b'; - }, - - /** - * Makes a brush compatible with the `html-script` functionality. - * @param {Object} regexGroup Object containing `left` and `right` regular expressions. - */ - forHtmlScript: function(regexGroup) - { - this.htmlScript = { - left : { regex: regexGroup.left, css: 'script' }, - right : { regex: regexGroup.right, css: 'script' }, - code : new XRegExp( - "(?" + regexGroup.left.source + ")" + - "(?.*?)" + - "(?" + regexGroup.right.source + ")", - "sgi" - ) - }; - } -}; // end of Highlighter - -return sh; -}(); // end of anonymous function - -if (!Array.indexOf) - /** - * Finds an index of element in the array. - * @ignore - * @param {Object} searchElement - * @param {Number} fromIndex - * @return {Number} Returns index of element if found; -1 otherwise. - */ - Array.prototype.indexOf = function (searchElement, fromIndex) - { - fromIndex = Math.max(fromIndex || 0, 0); - - for (var i = fromIndex; i < this.length; i++) - if(this[i] == searchElement) - return i; - - return -1; - }; - -/** - * XRegExp 0.6.1 - * (c) 2007-2008 Steven Levithan - * - * MIT License - * - * provides an augmented, cross-browser implementation of regular expressions - * including support for additional modifiers and syntax. several convenience - * methods and a recursive-construct parser are also included. - */ - -// prevent running twice, which would break references to native globals -if (!window.XRegExp) { -// anonymous function to avoid global variables -(function () { -// copy various native globals for reference. can't use the name ``native`` -// because it's a reserved JavaScript keyword. -var real = { - exec: RegExp.prototype.exec, - match: String.prototype.match, - replace: String.prototype.replace, - split: String.prototype.split - }, - /* regex syntax parsing with support for all the necessary cross- - browser and context issues (escapings, character classes, etc.) */ - lib = { - part: /(?:[^\\([#\s.]+|\\(?!k<[\w$]+>|[pP]{[^}]+})[\S\s]?|\((?=\?(?!#|<[\w$]+>)))+|(\()(?:\?(?:(#)[^)]*\)|<([$\w]+)>))?|\\(?:k<([\w$]+)>|[pP]{([^}]+)})|(\[\^?)|([\S\s])/g, - replaceVar: /(?:[^$]+|\$(?![1-9$&`']|{[$\w]+}))+|\$(?:([1-9]\d*|[$&`'])|{([$\w]+)})/g, - extended: /^(?:\s+|#.*)+/, - quantifier: /^(?:[?*+]|{\d+(?:,\d*)?})/, - classLeft: /&&\[\^?/g, - classRight: /]/g - }, - indexOf = function (array, item, from) { - for (var i = from || 0; i < array.length; i++) - if (array[i] === item) return i; - return -1; - }, - brokenExecUndef = /()??/.exec("")[1] !== undefined, - plugins = {}; - -/** - * Accepts a pattern and flags, returns a new, extended RegExp object. - * differs from a native regex in that additional flags and syntax are - * supported and browser inconsistencies are ameliorated. - * @ignore - */ -XRegExp = function (pattern, flags) { - if (pattern instanceof RegExp) { - if (flags !== undefined) - throw TypeError("can't supply flags when constructing one RegExp from another"); - return pattern.addFlags(); // new copy - } - - var flags = flags || "", - singleline = flags.indexOf("s") > -1, - extended = flags.indexOf("x") > -1, - hasNamedCapture = false, - captureNames = [], - output = [], - part = lib.part, - match, cc, len, index, regex; - - part.lastIndex = 0; // in case the last XRegExp compilation threw an error (unbalanced character class) - - while (match = real.exec.call(part, pattern)) { - // comment pattern. this check must come before the capturing group check, - // because both match[1] and match[2] will be non-empty. - if (match[2]) { - // keep tokens separated unless the following token is a quantifier - if (!lib.quantifier.test(pattern.slice(part.lastIndex))) - output.push("(?:)"); - // capturing group - } else if (match[1]) { - captureNames.push(match[3] || null); - if (match[3]) - hasNamedCapture = true; - output.push("("); - // named backreference - } else if (match[4]) { - index = indexOf(captureNames, match[4]); - // keep backreferences separate from subsequent literal numbers - // preserve backreferences to named groups that are undefined at this point as literal strings - output.push(index > -1 ? - "\\" + (index + 1) + (isNaN(pattern.charAt(part.lastIndex)) ? "" : "(?:)") : - match[0] - ); - // unicode element (requires plugin) - } else if (match[5]) { - output.push(plugins.unicode ? - plugins.unicode.get(match[5], match[0].charAt(1) === "P") : - match[0] - ); - // character class opening delimiter ("[" or "[^") - // (non-native unicode elements are not supported within character classes) - } else if (match[6]) { - if (pattern.charAt(part.lastIndex) === "]") { - // for cross-browser compatibility with ECMA-262 v3 behavior, - // convert [] to (?!) and [^] to [\S\s]. - output.push(match[6] === "[" ? "(?!)" : "[\\S\\s]"); - part.lastIndex++; - } else { - // parse the character class with support for inner escapes and - // ES4's infinitely nesting intersection syntax ([&&[^&&[]]]). - cc = XRegExp.matchRecursive("&&" + pattern.slice(match.index), lib.classLeft, lib.classRight, "", {escapeChar: "\\"})[0]; - output.push(match[6] + cc + "]"); - part.lastIndex += cc.length + 1; - } - // dot ("."), pound sign ("#"), or whitespace character - } else if (match[7]) { - if (singleline && match[7] === ".") { - output.push("[\\S\\s]"); - } else if (extended && lib.extended.test(match[7])) { - len = real.exec.call(lib.extended, pattern.slice(part.lastIndex - 1))[0].length; - // keep tokens separated unless the following token is a quantifier - if (!lib.quantifier.test(pattern.slice(part.lastIndex - 1 + len))) - output.push("(?:)"); - part.lastIndex += len - 1; - } else { - output.push(match[7]); - } - } else { - output.push(match[0]); - } - } - - regex = RegExp(output.join(""), real.replace.call(flags, /[sx]+/g, "")); - regex._x = { - source: pattern, - captureNames: hasNamedCapture ? captureNames : null - }; - return regex; -}; - -/** - * Barebones plugin support for now (intentionally undocumented) - * @ignore - * @param {Object} name - * @param {Object} o - */ -XRegExp.addPlugin = function (name, o) { - plugins[name] = o; -}; - -/** - * Adds named capture support, with values returned as ``result.name``. - * - * Also fixes two cross-browser issues, following the ECMA-262 v3 spec: - * - captured values for non-participating capturing groups should be returned - * as ``undefined``, rather than the empty string. - * - the regex's ``lastIndex`` should not be incremented after zero-length - * matches. - * @ignore - */ -RegExp.prototype.exec = function (str) { - var match = real.exec.call(this, str), - name, i, r2; - if (match) { - // fix browsers whose exec methods don't consistently return - // undefined for non-participating capturing groups - if (brokenExecUndef && match.length > 1) { - // r2 doesn't need /g or /y, but they shouldn't hurt - r2 = new RegExp("^" + this.source + "$(?!\\s)", this.getNativeFlags()); - real.replace.call(match[0], r2, function () { - for (i = 1; i < arguments.length - 2; i++) { - if (arguments[i] === undefined) match[i] = undefined; - } - }); - } - // attach named capture properties - if (this._x && this._x.captureNames) { - for (i = 1; i < match.length; i++) { - name = this._x.captureNames[i - 1]; - if (name) match[name] = match[i]; - } - } - // fix browsers that increment lastIndex after zero-length matches - if (this.global && this.lastIndex > (match.index + match[0].length)) - this.lastIndex--; - } - return match; -}; -})(); // end anonymous function -} // end if(!window.XRegExp) - -/** - * intentionally undocumented - * @ignore - */ -RegExp.prototype.getNativeFlags = function () { - return (this.global ? "g" : "") + - (this.ignoreCase ? "i" : "") + - (this.multiline ? "m" : "") + - (this.extended ? "x" : "") + - (this.sticky ? "y" : ""); -}; - -/** - * Accepts flags; returns a new XRegExp object generated by recompiling - * the regex with the additional flags (may include non-native flags). - * The original regex object is not altered. - * @ignore - */ -RegExp.prototype.addFlags = function (flags) { - var regex = new XRegExp(this.source, (flags || "") + this.getNativeFlags()); - if (this._x) { - regex._x = { - source: this._x.source, - captureNames: this._x.captureNames ? this._x.captureNames.slice(0) : null - }; - } - return regex; -}; - -/** - * Accepts a context object and string; returns the result of calling - * ``exec`` with the provided string. the context is ignored but is - * accepted for congruity with ``Function.prototype.call``. - * @ignore - */ -RegExp.prototype.call = function (context, str) { - return this.exec(str); -}; - -/** - * Accepts a context object and arguments array; returns the result of - * calling ``exec`` with the first value in the arguments array. the context - * is ignored but is accepted for congruity with ``Function.prototype.apply``. - * @ignore - */ -RegExp.prototype.apply = function (context, args) { - return this.exec(args[0]); -}; - -/** - * Accepts a pattern and flags; returns an XRegExp object. if the pattern - * and flag combination has previously been cached, the cached copy is - * returned, otherwise the new object is cached. - * @ignore - */ -XRegExp.cache = function (pattern, flags) { - var key = "/" + pattern + "/" + (flags || ""); - return XRegExp.cache[key] || (XRegExp.cache[key] = new XRegExp(pattern, flags)); -}; - -/** - * Accepts a string; returns the string with regex metacharacters escaped. - * the returned string can safely be used within a regex to match a literal - * string. escaped characters are [, ], {, }, (, ), -, *, +, ?, ., \, ^, $, - * |, #, [comma], and whitespace. - * @ignore - */ -XRegExp.escape = function (str) { - return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&"); -}; - -/** - * Accepts a string to search, left and right delimiters as regex pattern - * strings, optional regex flags (may include non-native s, x, and y flags), - * and an options object which allows setting an escape character and changing - * the return format from an array of matches to a two-dimensional array of - * string parts with extended position data. returns an array of matches - * (optionally with extended data), allowing nested instances of left and right - * delimiters. use the g flag to return all matches, otherwise only the first - * is returned. if delimiters are unbalanced within the subject data, an error - * is thrown. - * - * This function admittedly pushes the boundaries of what can be accomplished - * sensibly without a "real" parser. however, by doing so it provides flexible - * and powerful recursive parsing capabilities with minimal code weight. - * - * Warning: the ``escapeChar`` option is considered experimental and might be - * changed or removed in future versions of XRegExp. - * - * unsupported features: - * - backreferences within delimiter patterns when using ``escapeChar``. - * - although providing delimiters as regex objects adds the minor feature of - * independent delimiter flags, it introduces other limitations and is only - * intended to be done by the ``XRegExp`` constructor (which can't call - * itself while building a regex). - * - * @ignore - */ -XRegExp.matchRecursive = function (str, left, right, flags, options) { - var options = options || {}, - escapeChar = options.escapeChar, - vN = options.valueNames, - flags = flags || "", - global = flags.indexOf("g") > -1, - ignoreCase = flags.indexOf("i") > -1, - multiline = flags.indexOf("m") > -1, - sticky = flags.indexOf("y") > -1, - /* sticky mode has its own handling in this function, which means you - can use flag "y" even in browsers which don't support it natively */ - flags = flags.replace(/y/g, ""), - left = left instanceof RegExp ? (left.global ? left : left.addFlags("g")) : new XRegExp(left, "g" + flags), - right = right instanceof RegExp ? (right.global ? right : right.addFlags("g")) : new XRegExp(right, "g" + flags), - output = [], - openTokens = 0, - delimStart = 0, - delimEnd = 0, - lastOuterEnd = 0, - outerStart, innerStart, leftMatch, rightMatch, escaped, esc; - - if (escapeChar) { - if (escapeChar.length > 1) throw SyntaxError("can't supply more than one escape character"); - if (multiline) throw TypeError("can't supply escape character when using the multiline flag"); - escaped = XRegExp.escape(escapeChar); - /* Escape pattern modifiers: - /g - not needed here - /i - included - /m - **unsupported**, throws error - /s - handled by XRegExp when delimiters are provided as strings - /x - handled by XRegExp when delimiters are provided as strings - /y - not needed here; supported by other handling in this function - */ - esc = new RegExp( - "^(?:" + escaped + "[\\S\\s]|(?:(?!" + left.source + "|" + right.source + ")[^" + escaped + "])+)+", - ignoreCase ? "i" : "" - ); - } - - while (true) { - /* advance the starting search position to the end of the last delimiter match. - a couple special cases are also covered: - - if using an escape character, advance to the next delimiter's starting position, - skipping any escaped characters - - first time through, reset lastIndex in case delimiters were provided as regexes - */ - left.lastIndex = right.lastIndex = delimEnd + - (escapeChar ? (esc.exec(str.slice(delimEnd)) || [""])[0].length : 0); - - leftMatch = left.exec(str); - rightMatch = right.exec(str); - - // only keep the result which matched earlier in the string - if (leftMatch && rightMatch) { - if (leftMatch.index <= rightMatch.index) - rightMatch = null; - else leftMatch = null; - } - - /* paths*: - leftMatch | rightMatch | openTokens | result - 1 | 0 | 1 | ... - 1 | 0 | 0 | ... - 0 | 1 | 1 | ... - 0 | 1 | 0 | throw - 0 | 0 | 1 | throw - 0 | 0 | 0 | break - * - does not include the sticky mode special case - - the loop ends after the first completed match if not in global mode - */ - - if (leftMatch || rightMatch) { - delimStart = (leftMatch || rightMatch).index; - delimEnd = (leftMatch ? left : right).lastIndex; - } else if (!openTokens) { - break; - } - - if (sticky && !openTokens && delimStart > lastOuterEnd) - break; - - if (leftMatch) { - if (!openTokens++) { - outerStart = delimStart; - innerStart = delimEnd; - } - } else if (rightMatch && openTokens) { - if (!--openTokens) { - if (vN) { - if (vN[0] && outerStart > lastOuterEnd) - output.push([vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart]); - if (vN[1]) output.push([vN[1], str.slice(outerStart, innerStart), outerStart, innerStart]); - if (vN[2]) output.push([vN[2], str.slice(innerStart, delimStart), innerStart, delimStart]); - if (vN[3]) output.push([vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd]); - } else { - output.push(str.slice(innerStart, delimStart)); - } - lastOuterEnd = delimEnd; - if (!global) - break; - } - } else { - // reset lastIndex in case delimiters were provided as regexes - left.lastIndex = right.lastIndex = 0; - throw Error("subject data contains unbalanced delimiters"); - } - - // if the delimiter matched an empty string, advance delimEnd to avoid an infinite loop - if (delimStart === delimEnd) - delimEnd++; - } - - if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd) - output.push([vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length]); - - // reset lastIndex in case delimiters were provided as regexes - left.lastIndex = right.lastIndex = 0; - - return output; -}; diff --git a/test_script/styles/help.png b/test_script/styles/help.png deleted file mode 100644 index 5c870176d4dea68aab9e51166cc3d7a582f326d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 786 zcmV+t1MU2YP)$XgYMs^AIOw1Qr{*Wn)N-{9ma}x2(<~`9Go1=*>YR!KZvrBS zCd!u}@M0og%Ev@_;Z?Kk>Wwv=%h_57zmt2<_1msz_niYE=YRNPpd%02TK9oK1z z>ooPno}v^sikz_|1XHFx_L%~;ljh7i(jiay5F0x*+(9aXXFCl?AdQj5XlQ65%sEv+ ztfe?|YcjPN*@yYtE~ImQh{l|#A6Z8iu>pf43Rj52CzU_dMQm|S2xR62YjQOn+z8WH zaK=!}ggOZi{4pB7SQ=xC0n|vXP_Bkx_a)FeNd}w8U97BNbSWxa^QW-li9BZ#M1!_xE*?wzt^GcoeoL*JGLSe_+l-JT2#2tz!z&^ z_s5anq&^nBklIMwRvcoP3%qs%%Ea?1c{_*V*Xj&~uLu-2Dp1fUN4<0zMo$EH>*U83 zm_9;Vt%-bE{_J_!If!1y=c+`QVZ>0_BPy z+%^pgnv`f8H)Z%0&Tp8&u*MCIC4igNW5MeWM_DHpDNi)Zxz|9XboOnitwFq$ETN=X zj-tkCJnz**Y4k#6_Ty^B=hWo~L!47r`HoP=x&3T1)JLr2t2+#fHgNuvOO$0ks zMIj=HnnBRUR?tKXG11rxCU4&7dG4NbuvR2_mEvc)n?Cow;~Wve|KR^>9@p5l)|QB+ z$jmun3q#x>;ss-PW_mnr2MHVzLAl1RW&0?VkixF*4t!St0YVb2wnKdU(kmOHiL;aW zK8Xte%(k>MVGG$E4no6dcNnb>BhVHHGD&1pv4YZ68kE2V03t5#PCEFm7=ad$6)+3B zTCmn*?A?=u(o~ET7~-7g0)ZB=6|lumi4}B}MLgy~Ysy6)Q5%Al7|05&1z3Jpu>cF8 z3?VXs*3<}%h3`5Wld)N2zJnk%Agw<~3k)sPTLFd=F5;d8-bj-09SkQuynfflNcZLN z!^_37fdZvzrq=9~mp*($%mcDRKC&qvaaZuX+C=AT6O*~tHl>0mcP<_q>-z%$xO(@! zYluq5a8VQI$S@4?r*v;gPo!QQ%pX3A#>xx4t=w-L6COWx?aj&`f+!YePsFtj=hOQR zP3=E2j@9L7s8;T^&s?u(Hdpu?CubjMrGn{t_37>9$|AD)QE08weJlKn8|OyjL~7oP zC8mPT`jzuH*Dh^I0048RGafUIT)4H~*m8m>egI0iH=(LB%b@@O002ovPDHLkV1lw0 B3^~*-1fljz_B$LUvK}k?BNXe#Y!m=zM!!V#}8bncK5m;8VP zw86G*RI63?Cd%b9bX|ueNlZ|wR6rj|r_)VIP@r2imh3?SN+^{|kY%~8B{maJ@F*OK z&VH9LwOeGt#DRjj0~v~8`>iO7!Ybi;zE$va`A^T#yW`y44;k^#O~K5*jD=qcUhPSc zvyy~q;5H_1WT1l~cqje9yfa+l!hu6xjdOJ8s;8E^+=QQ$tw p?%p!Hy#YapB=@+^9(46X{{RQg%9y;OKjr`c002ovPDHLkV1g7l326WT diff --git a/test_script/styles/page_white_copy.png b/test_script/styles/page_white_copy.png deleted file mode 100644 index a9f31a278e17993d8d4e13beac2f9d5f7b42d08f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmV-50m}Y~P)^msfbTI z9jQ^EwMRD5xNEm*sJPjH^k)@gXT@kl5ii6#6jNXX`Yb0kVgq(zut?ZfbRr+DS= z>q{33dTpWN$tl6c7nxE)4Qur1GCxuUnp5Y z5HK(>u&W4&EXz<>UtfnPivJ`O3Zb4K8yl-}7K;Uh5XR!-B2uXo6E#Dr&Ck!D<$0b5 zXEK?PNF*3;w;Rc15`MqGDN4rSaGd2kJ3GNmOiaM%^D*ppJL2&;mX?;95{t!PwOY^e z?d|R0=pOKTy$qMj1$rk8qtS@b(NQ*LUtb@(y1JlNtJzsS-`3U!Ze(Pn>hXBkfzr6} z{3Vv(2AlG1;RQN6I#_mYZVs)jt>6p>!_3go(6&ye1Mdo>SRyz&A^1T#%t=UROW6Bf zz^9CeqErU&3`3<-Da~6HQ^UW&yCT)$Cu diff --git a/test_script/styles/shCore.css b/test_script/styles/shCore.css deleted file mode 100644 index b720e73b..00000000 --- a/test_script/styles/shCore.css +++ /dev/null @@ -1,321 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -.syntaxhighlighter, -.syntaxhighlighter div, -.syntaxhighlighter code, -.syntaxhighlighter span -{ - margin: 0 !important; - padding: 0 !important; - border: 0 !important; - outline: 0 !important; - background: none !important; - text-align: left !important; - float: none !important; - vertical-align: baseline !important; - position: static !important; - left: auto !important; - top: auto !important; - right: auto !important; - bottom: auto !important; - height: auto !important; - width: auto !important; - line-height: 1.1em !important; - font-family: "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; - font-weight: normal !important; - font-style: normal !important; - font-size: 1em !important; -} - -.syntaxhighlighter -{ - width: 100% !important; - margin: 1em 0 1em 0 !important; - padding: 1px !important; /* adds a little border on top and bottom */ - position: relative !important; -} - -.syntaxhighlighter .bold { - font-weight: bold !important; -} - -.syntaxhighlighter .italic { - font-style: italic !important; -} - -.syntaxhighlighter .line .number -{ - float: left !important; - width: 3em !important; - padding-right: .3em !important; - text-align: right !important; - display: block !important; -} - -/* Disable numbers when no gutter option is set */ -.syntaxhighlighter.nogutter .line .number -{ - display: none !important; -} - -.syntaxhighlighter .line .content -{ - margin-left: 3.3em !important; - padding-left: .5em !important; - display: block !important; -} - -.syntaxhighlighter .line .content .block -{ - display: block !important; - padding-left: 1.5em !important; - text-indent: -1.5em !important; -} - -.syntaxhighlighter .line .content .spaces -{ - display: none !important; -} - -/* Disable border and margin on the lines when no gutter option is set */ -.syntaxhighlighter.nogutter .line .content -{ - margin-left: 0 !important; - border-left: none !important; -} - -.syntaxhighlighter .bar -{ -} - -.syntaxhighlighter.collapsed .bar -{ - -} - -.syntaxhighlighter.nogutter .ruler -{ - margin-left: 0 !important; - padding-left: 0 !important; -} - -.syntaxhighlighter .ruler -{ - padding: 0 0 .5em .5em !important; - margin-left: 3.3em !important; - overflow: hidden !important; -} - -/* Adjust some properties when collapsed */ - -.syntaxhighlighter.collapsed .lines, -.syntaxhighlighter.collapsed .ruler -{ - display: none !important; -} - -/* Styles for the toolbar */ - -.syntaxhighlighter .toolbar -{ - position: absolute !important; - right: 0px !important; - top: 0px !important; - font-size: 1px !important; - padding: 8px 8px 8px 0 !important; /* in px because images don't scale with ems */ -} - -.syntaxhighlighter.collapsed .toolbar -{ - font-size: 80% !important; - padding: .2em 0 .5em .5em !important; - position: static !important; -} - -.syntaxhighlighter .toolbar a.item, -.syntaxhighlighter .toolbar .item -{ - display: block !important; - float: left !important; - margin-left: 8px !important; - background-repeat: no-repeat !important; - overflow: hidden !important; - text-indent: -5000px !important; -} - -.syntaxhighlighter.collapsed .toolbar .item -{ - display: none !important; -} - -.syntaxhighlighter.collapsed .toolbar .item.expandSource -{ - background-image: url(magnifier.png) !important; - display: inline !important; - text-indent: 0 !important; - width: auto !important; - float: none !important; - height: 16px !important; - padding-left: 20px !important; -} - -.syntaxhighlighter .toolbar .item.viewSource -{ - background-image: url(page_white_code.png) !important; -} - -.syntaxhighlighter .toolbar .item.printSource -{ - background-image: url(printer.png) !important; -} - -.syntaxhighlighter .toolbar .item.copyToClipboard -{ - text-indent: 0 !important; - background: none !important; - overflow: visible !important; -} - -.syntaxhighlighter .toolbar .item.about -{ - background-image: url(help.png) !important; -} - -/** - * Print view. - * Colors are based on the default theme without background. - */ - -.syntaxhighlighter.printing, -.syntaxhighlighter.printing .line.alt1 .content, -.syntaxhighlighter.printing .line.alt2 .content, -.syntaxhighlighter.printing .line.highlighted .number, -.syntaxhighlighter.printing .line.highlighted.alt1 .content, -.syntaxhighlighter.printing .line.highlighted.alt2 .content, -.syntaxhighlighter.printing .line .content .block -{ - background: none !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter.printing .line .number -{ - color: #bbb !important; -} - -/* Add border to the lines */ -.syntaxhighlighter.printing .line .content -{ - color: #000 !important; -} - -/* Toolbar when visible */ -.syntaxhighlighter.printing .toolbar, -.syntaxhighlighter.printing .ruler -{ - display: none !important; -} - -.syntaxhighlighter.printing a -{ - text-decoration: none !important; -} - -.syntaxhighlighter.printing .plain, -.syntaxhighlighter.printing .plain a -{ - color: #000 !important; -} - -.syntaxhighlighter.printing .comments, -.syntaxhighlighter.printing .comments a -{ - color: #008200 !important; -} - -.syntaxhighlighter.printing .string, -.syntaxhighlighter.printing .string a -{ - color: blue !important; -} - -.syntaxhighlighter.printing .keyword -{ - color: #069 !important; - font-weight: bold !important; -} - -.syntaxhighlighter.printing .preprocessor -{ - color: gray !important; -} - -.syntaxhighlighter.printing .variable -{ - color: #a70 !important; -} - -.syntaxhighlighter.printing .value -{ - color: #090 !important; -} - -.syntaxhighlighter.printing .functions -{ - color: #ff1493 !important; -} - -.syntaxhighlighter.printing .constants -{ - color: #0066CC !important; -} - -.syntaxhighlighter.printing .script -{ - font-weight: bold !important; -} - -.syntaxhighlighter.printing .color1, -.syntaxhighlighter.printing .color1 a -{ - color: #808080 !important; -} - -.syntaxhighlighter.printing .color2, -.syntaxhighlighter.printing .color2 a -{ - color: #ff1493 !important; -} - -.syntaxhighlighter.printing .color3, -.syntaxhighlighter.printing .color3 a -{ - color: red !important; -} diff --git a/test_script/styles/shThemeDefault.css b/test_script/styles/shThemeDefault.css deleted file mode 100644 index e466c97d..00000000 --- a/test_script/styles/shThemeDefault.css +++ /dev/null @@ -1,191 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/************************************ - * Default Syntax Highlighter theme. - * - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #E7E5DC !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #6CE26C !important; - color: black !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #6CE26C !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #5C5C5C !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #6CE26C !important; - color: #000 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ - background-color: #fff !important; -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #F8F8F8 !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -.syntaxhighlighter .ruler -{ - color: silver !important; - background-color: #F8F8F8 !important; - border-left: 3px solid #6CE26C !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #F8F8F8 !important; - border: #E7E5DC solid 1px !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #a0a0a0 !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: red !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #000 !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #008200 !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: blue !important; -} - -.syntaxhighlighter .keyword -{ - color: #069 !important; - font-weight: bold !important; -} - -.syntaxhighlighter .preprocessor -{ - color: gray !important; -} - -.syntaxhighlighter .variable -{ - color: #a70 !important; -} - -.syntaxhighlighter .value -{ - color: #090 !important; -} - -.syntaxhighlighter .functions -{ - color: #ff1493 !important; -} - -.syntaxhighlighter .constants -{ - color: #0066CC !important; -} - -.syntaxhighlighter .script -{ - background-color: yellow !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #808080 !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #ff1493 !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: red !important; -} diff --git a/test_script/styles/shThemeDjango.css b/test_script/styles/shThemeDjango.css deleted file mode 100644 index 65a7f067..00000000 --- a/test_script/styles/shThemeDjango.css +++ /dev/null @@ -1,193 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/** - * Django SyntaxHighlighter theme - */ - -/************************************ - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #0B2F20 !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #497958 !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #41A83E !important; - color: #B9BDB6 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #0a2b1d !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #336442 !important; - color: #fff !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #336442 !important; -} - -.syntaxhighlighter .ruler -{ - color: #C4B14A !important; - background-color: #245032 !important; - border-left: 3px solid #41A83E !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #245032 !important; - border: #0B2F20 solid 1px !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #C4B14A !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: #FFE862 !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #F8F8F8 !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #336442 !important; - font-style: italic !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: #9DF39F !important; -} - -.syntaxhighlighter .keyword -{ - color: #96DD3B !important; - font-weight: bold !important; -} - -.syntaxhighlighter .preprocessor -{ - color: #91BB9E !important; -} - -.syntaxhighlighter .variable -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .value -{ - color: #F7E741 !important; -} - -.syntaxhighlighter .functions -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .constants -{ - color: #E0E8FF !important; -} - -.syntaxhighlighter .script -{ - background-color: #497958 !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #EB939A !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #91BB9E !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: #EDEF7D !important; -} diff --git a/test_script/styles/shThemeEmacs.css b/test_script/styles/shThemeEmacs.css deleted file mode 100644 index e4eed165..00000000 --- a/test_script/styles/shThemeEmacs.css +++ /dev/null @@ -1,192 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/** - * Emacs SyntaxHighlighter theme based on theme by Joshua Emmons - * http://www.skia.net/ - */ - -/************************************ - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #000000 !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #D3D3D3 !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #990000 !important; - color: #B9BDB6 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #0f0f0f !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #435A5F !important; - color: #fff !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #435A5F !important; -} - -.syntaxhighlighter .ruler -{ - color: silver !important; - background-color: #000000 !important; - border-left: 3px solid #990000 !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #000000 !important; - border: #000000 solid 1px !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #646763 !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: #9CCFF4 !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #D3D3D3 !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #FF7D27 !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: #FF9E7B !important; -} - -.syntaxhighlighter .keyword -{ - color: #00FFFF !important; -} - -.syntaxhighlighter .preprocessor -{ - color: #AEC4DE !important; -} - -.syntaxhighlighter .variable -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .value -{ - color: #090 !important; -} - -.syntaxhighlighter .functions -{ - color: #81CEF9 !important; -} - -.syntaxhighlighter .constants -{ - color: #FF9E7B !important; -} - -.syntaxhighlighter .script -{ - background-color: #990000 !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #EBDB8D !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #FF7D27 !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: #AEC4DE !important; -} diff --git a/test_script/styles/shThemeFadeToGrey.css b/test_script/styles/shThemeFadeToGrey.css deleted file mode 100644 index b19c3be3..00000000 --- a/test_script/styles/shThemeFadeToGrey.css +++ /dev/null @@ -1,193 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/** - * Fade to Grey SyntaxHighlighter theme based on theme by Brasten Sager - * http://www.ibrasten.com/ - */ - -/************************************ - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #121212 !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #C3C3C3 !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #3185B9 !important; - color: #B9BDB6 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #000000 !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #3A3A00 !important; - color: #fff !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #3A3A00 !important; -} - -.syntaxhighlighter .ruler -{ - color: silver !important; - border-left: 3px solid #3185B9 !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #000000 !important; - border: #000000 solid 1px !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #808080 !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: #96DAFF !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #FFFFFF !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #696854 !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: #E3E658 !important; -} - -.syntaxhighlighter .keyword -{ - color: #D01D33 !important; -} - -.syntaxhighlighter .preprocessor -{ - color: #435A5F !important; -} - -.syntaxhighlighter .variable -{ - color: #898989 !important; -} - -.syntaxhighlighter .value -{ - color: #090 !important; -} - -.syntaxhighlighter .functions -{ - color: #AAAAAA !important; - font-weight: bold !important; -} - -.syntaxhighlighter .constants -{ - color: #96DAFF !important; -} - -.syntaxhighlighter .script -{ - background-color: #C3C3C3 !important; - color: #000 !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #FFC074 !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #4A8CDB !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: #96DAFF !important; -} diff --git a/test_script/styles/shThemeMidnight.css b/test_script/styles/shThemeMidnight.css deleted file mode 100644 index 0f39d0c8..00000000 --- a/test_script/styles/shThemeMidnight.css +++ /dev/null @@ -1,192 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/** - * Midnight SyntaxHighlighter theme based on theme by J.D. Myers - * http://webdesign.lsnjd.com/ - */ - -/************************************ - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #0F192A !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #38566F !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #435A5F !important; - color: #B9BDB6 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ - background-color: #0F192A !important; -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #0F192A !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #253E5A !important; - color: #fff !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #253E5A !important; -} - -.syntaxhighlighter .ruler -{ - color: #38566F !important; - background-color: #0F192A !important; - border-left: 3px solid #435A5F !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #0F192A !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #38566F !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: #8AA6C1 !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #D1EDFF !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #428BDD !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: #1DC116 !important; -} - -.syntaxhighlighter .keyword -{ - color: #B43D3D !important; -} - -.syntaxhighlighter .preprocessor -{ - color: #8AA6C1 !important; -} - -.syntaxhighlighter .variable -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .value -{ - color: #F7E741 !important; -} - -.syntaxhighlighter .functions -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .constants -{ - color: #E0E8FF !important; -} - -.syntaxhighlighter .script -{ - background-color: #404040 !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #F8BB00 !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #FFFFFF !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: #FFAA3E !important; -} diff --git a/test_script/styles/shThemeRDark.css b/test_script/styles/shThemeRDark.css deleted file mode 100644 index 308db598..00000000 --- a/test_script/styles/shThemeRDark.css +++ /dev/null @@ -1,192 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/ - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate - * - * @version - * 2.0.296 (March 01 2009) - * - * @copyright - * Copyright (C) 2004-2009 Alex Gorbatchev. - * - * @license - * This file is part of SyntaxHighlighter. - * - * SyntaxHighlighter is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SyntaxHighlighter is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SyntaxHighlighter. If not, see . - */ -/** - * RDark SyntaxHighlighter theme based on theme by Radu Dineiu - * http://www.vim.org/scripts/script.php?script_id=1732 - */ - -/************************************ - * Interface elements. - ************************************/ - -.syntaxhighlighter -{ - background-color: #1B2426 !important; -} - -/* Gutter line numbers */ -.syntaxhighlighter .line .number -{ - color: #B9BDB6 !important; -} - -/* Add border to the lines */ -.syntaxhighlighter .line .content -{ - border-left: 3px solid #435A5F !important; - color: #B9BDB6 !important; -} - -.syntaxhighlighter.printing .line .content -{ - border: 0 !important; -} - -/* First line */ -.syntaxhighlighter .line.alt1 .content -{ - background-color: #1B2426 !important; -} - -/* Second line */ -.syntaxhighlighter .line.alt2 .content -{ - background-color: #1B2426 !important; -} - -.syntaxhighlighter .line .content .block -{ - background: url(wrapping.png) 0 1.1em no-repeat !important; -} - -/* Highlighed line number */ -.syntaxhighlighter .line.highlighted .number -{ - background-color: #435A5F !important; - color: #fff !important; -} - -/* Highlighed line */ -.syntaxhighlighter .line.highlighted.alt1 .content, -.syntaxhighlighter .line.highlighted.alt2 .content -{ - background-color: #435A5F !important; -} - -.syntaxhighlighter .ruler -{ - color: silver !important; - background-color: #1B2426 !important; - border-left: 3px solid #435A5F !important; -} - -.syntaxhighlighter.nogutter .ruler -{ - border: 0 !important; -} - -.syntaxhighlighter .toolbar -{ - background-color: #1B2426 !important; -} - -.syntaxhighlighter .toolbar a -{ - color: #646763 !important; -} - -.syntaxhighlighter .toolbar a:hover -{ - color: #E0E8FF !important; -} - -/************************************ - * Actual syntax highlighter colors. - ************************************/ -.syntaxhighlighter .plain, -.syntaxhighlighter .plain a -{ - color: #B9BDB6 !important; -} - -.syntaxhighlighter .comments, -.syntaxhighlighter .comments a -{ - color: #878A85 !important; -} - -.syntaxhighlighter .string, -.syntaxhighlighter .string a -{ - color: #5CE638 !important; -} - -.syntaxhighlighter .keyword -{ - color: #5BA1CF !important; -} - -.syntaxhighlighter .preprocessor -{ - color: #435A5F !important; -} - -.syntaxhighlighter .variable -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .value -{ - color: #090 !important; -} - -.syntaxhighlighter .functions -{ - color: #FFAA3E !important; -} - -.syntaxhighlighter .constants -{ - color: #E0E8FF !important; -} - -.syntaxhighlighter .script -{ - background-color: #435A5F !important; -} - -.syntaxhighlighter .color1, -.syntaxhighlighter .color1 a -{ - color: #E0E8FF !important; -} - -.syntaxhighlighter .color2, -.syntaxhighlighter .color2 a -{ - color: #FFFFFF !important; -} - -.syntaxhighlighter .color3, -.syntaxhighlighter .color3 a -{ - color: #FFAA3E !important; -} diff --git a/test_script/test.html b/test_script/test.html deleted file mode 100644 index 26f559ff..00000000 --- a/test_script/test.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Syntax Highlighter Build Test Page - - - - - - - - - - -

Syntax Highlighter Test

-

This is a test file to insure that everything is working well.

- -
-function test() : String
-{
-  return 10;
-}
-
- -