| <?php |
| |
| # |
| # SmartyPants - Smart punctuation for web sites |
| # |
| # by John Gruber |
| # <http://daringfireball.net> |
| # |
| # PHP port by Michel Fortin |
| # <http://www.michelf.com/> |
| # |
| # Copyright (c) 2003-2004 John Gruber |
| # Copyright (c) 2004-2005 Michel Fortin |
| # |
| |
| |
| global $SmartyPantsPHPVersion, $SmartyPantsSyntaxVersion, |
| $smartypants_attr, $sp_tags_to_skip; |
| |
| $SmartyPantsPHPVersion = '1.5.1e'; # Fru 9 Dec 2005 |
| $SmartyPantsSyntaxVersion = '1.5.1'; # Fri 12 Mar 2004 |
| |
| |
| # Configurable variables: |
| $smartypants_attr = "1"; # Change this to configure. |
| # 1 => "--" for em-dashes; no en-dash support |
| # 2 => "---" for em-dashes; "--" for en-dashes |
| # 3 => "--" for em-dashes; "---" for en-dashes |
| # See docs for more configuration options. |
| |
| # Globals: |
| $sp_tags_to_skip = '<(/?)(?:pre|code|kbd|script|math)[\s>]'; |
| |
| |
| # -- WordPress plugin interface ----------------------------------------------- |
| /* |
| Plugin Name: SmartyPants |
| Plugin URI: http://www.michelf.com/projects/php-smartypants/ |
| Description: SmartyPants is a web publishing utility that translates plain ASCII punctuation characters into “smart” typographic punctuation HTML entities. This plugin <strong>replace the default WordPress Texturize algorithm</strong> for the content and the title of your posts, the comments body and author name, and everywhere else Texturize normally apply. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. |
| Version: 1.5.1e |
| Author: Michel Fortin |
| Author URI: http://www.michelf.com/ |
| */ |
| if (isset($wp_version)) { |
| # Remove default Texturize filter that would conflict with SmartyPants. |
| remove_filter('category_description', 'wptexturize'); |
| remove_filter('list_cats', 'wptexturize'); |
| remove_filter('comment_author', 'wptexturize'); |
| remove_filter('comment_text', 'wptexturize'); |
| remove_filter('single_post_title', 'wptexturize'); |
| remove_filter('the_title', 'wptexturize'); |
| remove_filter('the_content', 'wptexturize'); |
| remove_filter('the_excerpt', 'wptexturize'); |
| # Add SmartyPants filter with priority 10 (same as Texturize). |
| add_filter('category_description', 'SmartyPants', 10); |
| add_filter('list_cats', 'SmartyPants', 10); |
| add_filter('comment_author', 'SmartyPants', 10); |
| add_filter('comment_text', 'SmartyPants', 10); |
| add_filter('single_post_title', 'SmartyPants', 10); |
| add_filter('the_title', 'SmartyPants', 10); |
| add_filter('the_content', 'SmartyPants', 10); |
| add_filter('the_excerpt', 'SmartyPants', 10); |
| } |
| |
| # -- Smarty Modifier Interface ------------------------------------------------ |
| function smarty_modifier_smartypants($text, $attr = NULL) { |
| return SmartyPants($text, $attr); |
| } |
| |
| |
| |
| function SmartyPants($text, $attr = NULL, $ctx = NULL) { |
| global $smartypants_attr, $sp_tags_to_skip; |
| # Paramaters: |
| $text; # text to be parsed |
| $attr; # value of the smart_quotes="" attribute |
| $ctx; # MT context object (unused) |
| if ($attr == NULL) $attr = $smartypants_attr; |
| |
| # Options to specify which transformations to make: |
| $do_stupefy = FALSE; |
| $convert_quot = 0; # should we translate " entities into normal quotes? |
| |
| # Parse attributes: |
| # 0 : do nothing |
| # 1 : set all |
| # 2 : set all, using old school en- and em- dash shortcuts |
| # 3 : set all, using inverted old school en and em- dash shortcuts |
| # |
| # q : quotes |
| # b : backtick quotes (``double'' only) |
| # B : backtick quotes (``double'' and `single') |
| # d : dashes |
| # D : old school dashes |
| # i : inverted old school dashes |
| # e : ellipses |
| # w : convert " entities to " for Dreamweaver users |
| |
| if ($attr == "0") { |
| # Do nothing. |
| return $text; |
| } |
| else if ($attr == "1") { |
| # Do everything, turn all options on. |
| $do_quotes = 1; |
| $do_backticks = 1; |
| $do_dashes = 1; |
| $do_ellipses = 1; |
| } |
| else if ($attr == "2") { |
| # Do everything, turn all options on, use old school dash shorthand. |
| $do_quotes = 1; |
| $do_backticks = 1; |
| $do_dashes = 2; |
| $do_ellipses = 1; |
| } |
| else if ($attr == "3") { |
| # Do everything, turn all options on, use inverted old school dash shorthand. |
| $do_quotes = 1; |
| $do_backticks = 1; |
| $do_dashes = 3; |
| $do_ellipses = 1; |
| } |
| else if ($attr == "-1") { |
| # Special "stupefy" mode. |
| $do_stupefy = 1; |
| } |
| else { |
| $chars = preg_split('//', $attr); |
| foreach ($chars as $c){ |
| if ($c == "q") { $do_quotes = 1; } |
| else if ($c == "b") { $do_backticks = 1; } |
| else if ($c == "B") { $do_backticks = 2; } |
| else if ($c == "d") { $do_dashes = 1; } |
| else if ($c == "D") { $do_dashes = 2; } |
| else if ($c == "i") { $do_dashes = 3; } |
| else if ($c == "e") { $do_ellipses = 1; } |
| else if ($c == "w") { $convert_quot = 1; } |
| else { |
| # Unknown attribute option, ignore. |
| } |
| } |
| } |
| |
| $tokens = _TokenizeHTML($text); |
| $result = ''; |
| $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags. |
| |
| $prev_token_last_char = ""; # This is a cheat, used to get some context |
| # for one-character tokens that consist of |
| # just a quote char. What we do is remember |
| # the last character of the previous text |
| # token, to use as context to curl single- |
| # character quote tokens correctly. |
| |
| foreach ($tokens as $cur_token) { |
| if ($cur_token[0] == "tag") { |
| # Don't mess with quotes inside tags. |
| $result .= $cur_token[1]; |
| if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) { |
| $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; |
| } |
| } else { |
| $t = $cur_token[1]; |
| $last_char = substr($t, -1); # Remember last char of this token before processing. |
| if (! $in_pre) { |
| $t = ProcessEscapes($t); |
| |
| if ($convert_quot) { |
| $t = preg_replace('/"/', '"', $t); |
| } |
| |
| if ($do_dashes) { |
| if ($do_dashes == 1) $t = EducateDashes($t); |
| if ($do_dashes == 2) $t = EducateDashesOldSchool($t); |
| if ($do_dashes == 3) $t = EducateDashesOldSchoolInverted($t); |
| } |
| |
| if ($do_ellipses) $t = EducateEllipses($t); |
| |
| # Note: backticks need to be processed before quotes. |
| if ($do_backticks) { |
| $t = EducateBackticks($t); |
| if ($do_backticks == 2) $t = EducateSingleBackticks($t); |
| } |
| |
| if ($do_quotes) { |
| if ($t == "'") { |
| # Special case: single-character ' token |
| if (preg_match('/\S/', $prev_token_last_char)) { |
| $t = "’"; |
| } |
| else { |
| $t = "‘"; |
| } |
| } |
| else if ($t == '"') { |
| # Special case: single-character " token |
| if (preg_match('/\S/', $prev_token_last_char)) { |
| $t = "”"; |
| } |
| else { |
| $t = "“"; |
| } |
| } |
| else { |
| # Normal case: |
| $t = EducateQuotes($t); |
| } |
| } |
| |
| if ($do_stupefy) $t = StupefyEntities($t); |
| } |
| $prev_token_last_char = $last_char; |
| $result .= $t; |
| } |
| } |
| |
| return $result; |
| } |
| |
| |
| function SmartQuotes($text, $attr = NULL, $ctx = NULL) { |
| global $smartypants_attr, $sp_tags_to_skip; |
| # Paramaters: |
| $text; # text to be parsed |
| $attr; # value of the smart_quotes="" attribute |
| $ctx; # MT context object (unused) |
| if ($attr == NULL) $attr = $smartypants_attr; |
| |
| $do_backticks; # should we educate ``backticks'' -style quotes? |
| |
| if ($attr == 0) { |
| # do nothing; |
| return $text; |
| } |
| else if ($attr == 2) { |
| # smarten ``backticks'' -style quotes |
| $do_backticks = 1; |
| } |
| else { |
| $do_backticks = 0; |
| } |
| |
| # Special case to handle quotes at the very end of $text when preceded by |
| # an HTML tag. Add a space to give the quote education algorithm a bit of |
| # context, so that it can guess correctly that it's a closing quote: |
| $add_extra_space = 0; |
| if (preg_match("/>['\"]\\z/", $text)) { |
| $add_extra_space = 1; # Remember, so we can trim the extra space later. |
| $text .= " "; |
| } |
| |
| $tokens = _TokenizeHTML($text); |
| $result = ''; |
| $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags |
| |
| $prev_token_last_char = ""; # This is a cheat, used to get some context |
| # for one-character tokens that consist of |
| # just a quote char. What we do is remember |
| # the last character of the previous text |
| # token, to use as context to curl single- |
| # character quote tokens correctly. |
| |
| foreach ($tokens as $cur_token) { |
| if ($cur_token[0] == "tag") { |
| # Don't mess with quotes inside tags |
| $result .= $cur_token[1]; |
| if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) { |
| $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; |
| } |
| } else { |
| $t = $cur_token[1]; |
| $last_char = substr($t, -1); # Remember last char of this token before processing. |
| if (! $in_pre) { |
| $t = ProcessEscapes($t); |
| if ($do_backticks) { |
| $t = EducateBackticks($t); |
| } |
| |
| if ($t == "'") { |
| # Special case: single-character ' token |
| if (preg_match('/\S/', $prev_token_last_char)) { |
| $t = "’"; |
| } |
| else { |
| $t = "‘"; |
| } |
| } |
| else if ($t == '"') { |
| # Special case: single-character " token |
| if (preg_match('/\S/', $prev_token_last_char)) { |
| $t = "”"; |
| } |
| else { |
| $t = "“"; |
| } |
| } |
| else { |
| # Normal case: |
| $t = EducateQuotes($t); |
| } |
| |
| } |
| $prev_token_last_char = $last_char; |
| $result .= $t; |
| } |
| } |
| |
| if ($add_extra_space) { |
| preg_replace('/ \z/', '', $result); # Trim trailing space if we added one earlier. |
| } |
| return $result; |
| } |
| |
| |
| function SmartDashes($text, $attr = NULL, $ctx = NULL) { |
| global $smartypants_attr, $sp_tags_to_skip; |
| # Paramaters: |
| $text; # text to be parsed |
| $attr; # value of the smart_dashes="" attribute |
| $ctx; # MT context object (unused) |
| if ($attr == NULL) $attr = $smartypants_attr; |
| |
| # reference to the subroutine to use for dash education, default to EducateDashes: |
| $dash_sub_ref = 'EducateDashes'; |
| |
| if ($attr == 0) { |
| # do nothing; |
| return $text; |
| } |
| else if ($attr == 2) { |
| # use old smart dash shortcuts, "--" for en, "---" for em |
| $dash_sub_ref = 'EducateDashesOldSchool'; |
| } |
| else if ($attr == 3) { |
| # inverse of 2, "--" for em, "---" for en |
| $dash_sub_ref = 'EducateDashesOldSchoolInverted'; |
| } |
| |
| $tokens; |
| $tokens = _TokenizeHTML($text); |
| |
| $result = ''; |
| $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags |
| foreach ($tokens as $cur_token) { |
| if ($cur_token[0] == "tag") { |
| # Don't mess with quotes inside tags |
| $result .= $cur_token[1]; |
| if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) { |
| $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; |
| } |
| } else { |
| $t = $cur_token[1]; |
| if (! $in_pre) { |
| $t = ProcessEscapes($t); |
| $t = $dash_sub_ref($t); |
| } |
| $result .= $t; |
| } |
| } |
| return $result; |
| } |
| |
| |
| function SmartEllipses($text, $attr = NULL, $ctx = NULL) { |
| # Paramaters: |
| $text; # text to be parsed |
| $attr; # value of the smart_ellipses="" attribute |
| $ctx; # MT context object (unused) |
| if ($attr == NULL) $attr = $smartypants_attr; |
| |
| if ($attr == 0) { |
| # do nothing; |
| return $text; |
| } |
| |
| $tokens; |
| $tokens = _TokenizeHTML($text); |
| |
| $result = ''; |
| $in_pre = 0; # Keep track of when we're inside <pre> or <code> tags |
| foreach ($tokens as $cur_token) { |
| if ($cur_token[0] == "tag") { |
| # Don't mess with quotes inside tags |
| $result .= $cur_token[1]; |
| if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) { |
| $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1; |
| } |
| } else { |
| $t = $cur_token[1]; |
| if (! $in_pre) { |
| $t = ProcessEscapes($t); |
| $t = EducateEllipses($t); |
| } |
| $result .= $t; |
| } |
| } |
| return $result; |
| } |
| |
| |
| function EducateQuotes($_) { |
| # |
| # Parameter: String. |
| # |
| # Returns: The string, with "educated" curly quote HTML entities. |
| # |
| # Example input: "Isn't this fun?" |
| # Example output: “Isn’t this fun?” |
| # |
| # Make our own "punctuation" character class, because the POSIX-style |
| # [:PUNCT:] is only available in Perl 5.6 or later: |
| $punct_class = "[!\"#\\$\\%'()*+,-.\\/:;<=>?\\@\\[\\\\\]\\^_`{|}~]"; |
| |
| # Special case if the very first character is a quote |
| # followed by punctuation at a non-word-break. Close the quotes by brute force: |
| $_ = preg_replace( |
| array("/^'(?=$punct_class\\B)/", "/^\"(?=$punct_class\\B)/"), |
| array('’', '”'), $_); |
| |
| |
| # Special case for double sets of quotes, e.g.: |
| # <p>He said, "'Quoted' words in a larger quote."</p> |
| $_ = preg_replace( |
| array("/\"'(?=\w)/", "/'\"(?=\w)/"), |
| array('“‘', '‘“'), $_); |
| |
| # Special case for decade abbreviations (the '80s): |
| $_ = preg_replace("/'(?=\\d{2}s)/", '’', $_); |
| |
| $close_class = '[^\ \t\r\n\[\{\(\-]'; |
| $dec_dashes = '&\#8211;|&\#8212;'; |
| |
| # Get most opening single quotes: |
| $_ = preg_replace("{ |
| ( |
| \\s | # a whitespace char, or |
| | # a non-breaking space entity, or |
| -- | # dashes, or |
| &[mn]dash; | # named dash entities |
| $dec_dashes | # or decimal entities |
| &\\#x201[34]; # or hex |
| ) |
| ' # the quote |
| (?=\\w) # followed by a word character |
| }x", '\1‘', $_); |
| # Single closing quotes: |
| $_ = preg_replace("{ |
| ($close_class)? |
| ' |
| (?(1)| # If $1 captured, then do nothing; |
| (?=\\s | s\\b) # otherwise, positive lookahead for a whitespace |
| ) # char or an 's' at a word ending position. This |
| # is a special case to handle something like: |
| # \"<i>Custer</i>'s Last Stand.\" |
| }xi", '\1’', $_); |
| |
| # Any remaining single quotes should be opening ones: |
| $_ = str_replace("'", '‘', $_); |
| |
| |
| # Get most opening double quotes: |
| $_ = preg_replace("{ |
| ( |
| \\s | # a whitespace char, or |
| | # a non-breaking space entity, or |
| -- | # dashes, or |
| &[mn]dash; | # named dash entities |
| $dec_dashes | # or decimal entities |
| &\\#x201[34]; # or hex |
| ) |
| \" # the quote |
| (?=\\w) # followed by a word character |
| }x", '\1“', $_); |
| |
| # Double closing quotes: |
| $_ = preg_replace("{ |
| ($close_class)? |
| \" |
| (?(1)|(?=\\s)) # If $1 captured, then do nothing; |
| # if not, then make sure the next char is whitespace. |
| }x", '\1”', $_); |
| |
| # Any remaining quotes should be opening ones. |
| $_ = str_replace('"', '“', $_); |
| |
| return $_; |
| } |
| |
| |
| function EducateBackticks($_) { |
| # |
| # Parameter: String. |
| # Returns: The string, with ``backticks'' -style double quotes |
| # translated into HTML curly quote entities. |
| # |
| # Example input: ``Isn't this fun?'' |
| # Example output: “Isn't this fun?” |
| # |
| |
| $_ = str_replace(array("``", "''",), |
| array('“', '”'), $_); |
| return $_; |
| } |
| |
| |
| function EducateSingleBackticks($_) { |
| # |
| # Parameter: String. |
| # Returns: The string, with `backticks' -style single quotes |
| # translated into HTML curly quote entities. |
| # |
| # Example input: `Isn't this fun?' |
| # Example output: ‘Isn’t this fun?’ |
| # |
| |
| $_ = str_replace(array("`", "'",), |
| array('‘', '’'), $_); |
| return $_; |
| } |
| |
| |
| function EducateDashes($_) { |
| # |
| # Parameter: String. |
| # |
| # Returns: The string, with each instance of "--" translated to |
| # an em-dash HTML entity. |
| # |
| |
| $_ = str_replace('--', '—', $_); |
| return $_; |
| } |
| |
| |
| function EducateDashesOldSchool($_) { |
| # |
| # Parameter: String. |
| # |
| # Returns: The string, with each instance of "--" translated to |
| # an en-dash HTML entity, and each "---" translated to |
| # an em-dash HTML entity. |
| # |
| |
| # em en |
| $_ = str_replace(array("---", "--",), |
| array('—', '–'), $_); |
| return $_; |
| } |
| |
| |
| function EducateDashesOldSchoolInverted($_) { |
| # |
| # Parameter: String. |
| # |
| # Returns: The string, with each instance of "--" translated to |
| # an em-dash HTML entity, and each "---" translated to |
| # an en-dash HTML entity. Two reasons why: First, unlike the |
| # en- and em-dash syntax supported by |
| # EducateDashesOldSchool(), it's compatible with existing |
| # entries written before SmartyPants 1.1, back when "--" was |
| # only used for em-dashes. Second, em-dashes are more |
| # common than en-dashes, and so it sort of makes sense that |
| # the shortcut should be shorter to type. (Thanks to Aaron |
| # Swartz for the idea.) |
| # |
| |
| # en em |
| $_ = str_replace(array("---", "--",), |
| array('–', '—'), $_); |
| return $_; |
| } |
| |
| |
| function EducateEllipses($_) { |
| # |
| # Parameter: String. |
| # Returns: The string, with each instance of "..." translated to |
| # an ellipsis HTML entity. Also converts the case where |
| # there are spaces between the dots. |
| # |
| # Example input: Huh...? |
| # Example output: Huh…? |
| # |
| |
| $_ = str_replace(array("...", ". . .",), '…', $_); |
| return $_; |
| } |
| |
| |
| function StupefyEntities($_) { |
| # |
| # Parameter: String. |
| # Returns: The string, with each SmartyPants HTML entity translated to |
| # its ASCII counterpart. |
| # |
| # Example input: “Hello — world.” |
| # Example output: "Hello -- world." |
| # |
| |
| # en-dash em-dash |
| $_ = str_replace(array('–', '—'), |
| array('-', '--'), $_); |
| |
| # single quote open close |
| $_ = str_replace(array('‘', '’'), "'", $_); |
| |
| # double quote open close |
| $_ = str_replace(array('“', '”'), '"', $_); |
| |
| $_ = str_replace('…', '...', $_); # ellipsis |
| |
| return $_; |
| } |
| |
| |
| function ProcessEscapes($_) { |
| # |
| # Parameter: String. |
| # Returns: The string, with after processing the following backslash |
| # escape sequences. This is useful if you want to force a "dumb" |
| # quote or other character to appear. |
| # |
| # Escape Value |
| # ------ ----- |
| # \\ \ |
| # \" " |
| # \' ' |
| # \. . |
| # \- - |
| # \` ` |
| # |
| $_ = str_replace( |
| array('\\\\', '\"', "\'", '\.', '\-', '\`'), |
| array('\', '"', ''', '.', '-', '`'), $_); |
| |
| return $_; |
| } |
| |
| |
| # _TokenizeHTML is shared between PHP SmartyPants and PHP Markdown. |
| # We only define it if it is not already defined. |
| if (!function_exists('_TokenizeHTML')) : |
| function _TokenizeHTML($str) { |
| # |
| # Parameter: String containing HTML markup. |
| # Returns: An array of the tokens comprising the input |
| # string. Each token is either a tag (possibly with nested, |
| # tags contained therein, such as <a href="<MTFoo>">, or a |
| # run of text between tags. Each element of the array is a |
| # two-element array; the first is either 'tag' or 'text'; |
| # the second is the actual value. |
| # |
| # |
| # Regular expression derived from the _tokenize() subroutine in |
| # Brad Choate's MTRegex plugin. |
| # <http://www.bradchoate.com/past/mtregex.php> |
| # |
| $index = 0; |
| $tokens = array(); |
| |
| $match = '(?s:<!(?:--.*?--\s*)+>)|'. # comment |
| '(?s:<\?.*?\?>)|'. # processing instruction |
| # regular tags |
| '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)'; |
| |
| $parts = preg_split("{($match)}", $str, -1, PREG_SPLIT_DELIM_CAPTURE); |
| |
| foreach ($parts as $part) { |
| if (++$index % 2 && $part != '') |
| $tokens[] = array('text', $part); |
| else |
| $tokens[] = array('tag', $part); |
| } |
| return $tokens; |
| } |
| endif; |
| |
| |
| /* |
| |
| PHP SmartyPants |
| =============== |
| |
| Description |
| ----------- |
| |
| This is a PHP translation of the original SmartyPants quote educator written in |
| Perl by John Gruber. |
| |
| SmartyPants is a web publishing utility that translates plain ASCII |
| punctuation characters into "smart" typographic punctuation HTML |
| entities. SmartyPants can perform the following transformations: |
| |
| * Straight quotes (`"` and `'`) into "curly" quote HTML entities |
| * Backticks-style quotes (` ``like this'' `) into "curly" quote HTML |
| entities |
| * Dashes (`--` and `---`) into en- and em-dash entities |
| * Three consecutive dots (`...`) into an ellipsis entity |
| |
| SmartyPants does not modify characters within `<pre>`, `<code>`, `<kbd>`, |
| `<script>`, or `<math>` tag blocks. Typically, these tags are used to |
| display text where smart quotes and other "smart punctuation" would not |
| be appropriate, such as source code or example markup. |
| |
| |
| ### Backslash Escapes ### |
| |
| If you need to use literal straight quotes (or plain hyphens and |
| periods), SmartyPants accepts the following backslash escape sequences |
| to force non-smart punctuation. It does so by transforming the escape |
| sequence into a decimal-encoded HTML entity: |
| |
| Escape Value Character |
| ------ ----- --------- |
| \\ \ \ |
| \" " " |
| \' ' ' |
| \. . . |
| \- - - |
| \` ` ` |
| |
| This is useful, for example, when you want to use straight quotes as |
| foot and inch marks: 6'2" tall; a 17" iMac. |
| |
| |
| Bugs |
| ---- |
| |
| To file bug reports or feature requests (other than topics listed in the |
| Caveats section above) please send email to: |
| |
| <michel.fortin@michelf.com> |
| |
| If the bug involves quotes being curled the wrong way, please send example |
| text to illustrate. |
| |
| |
| ### Algorithmic Shortcomings ### |
| |
| One situation in which quotes will get curled the wrong way is when |
| apostrophes are used at the start of leading contractions. For example: |
| |
| 'Twas the night before Christmas. |
| |
| In the case above, SmartyPants will turn the apostrophe into an opening |
| single-quote, when in fact it should be a closing one. I don't think |
| this problem can be solved in the general case -- every word processor |
| I've tried gets this wrong as well. In such cases, it's best to use the |
| proper HTML entity for closing single-quotes (`’`) by hand. |
| |
| |
| Version History |
| --------------- |
| |
| 1.5.1e (9 Dec 2005) |
| |
| * Corrected a bug that prevented special characters from being |
| escaped. |
| |
| |
| 1.5.1d (25 May 2005) |
| |
| * Corrected a small bug in `_TokenizeHTML` where a Doctype declaration |
| was not seen as HTML (smart quotes where applied inside). |
| |
| |
| 1.5.1c (13 Dec 2004) |
| |
| * Changed a regular expression in `_TokenizeHTML` that could lead to |
| a segmentation fault with PHP 4.3.8 on Linux. |
| |
| |
| 1.5.1b (6 Sep 2004) |
| |
| * Corrected a problem with quotes immediately following a dash |
| with no space between: `Text--"quoted text"--text.` |
| |
| * PHP SmartyPants can now be used as a modifier by the Smarty |
| template engine. Rename the file to "modifier.smartypants.php" |
| and put it in your smarty plugins folder. |
| |
| * Replaced a lot of space characters by tabs, saving about 4 KB. |
| |
| |
| 1.5.1a (30 Jun 2004) |
| |
| * PHP Markdown and PHP Smartypants now share the same `_TokenizeHTML` |
| function when loaded simultanously. |
| |
| * Changed the internals of `_TokenizeHTML` to lower the PHP version |
| requirement to PHP 4.0.5. |
| |
| |
| 1.5.1 (6 Jun 2004) |
| |
| * Initial release of PHP SmartyPants, based on version 1.5.1 of the |
| original SmartyPants written in Perl. |
| |
| |
| Author |
| ------ |
| |
| John Gruber |
| <http://daringfireball.net/> |
| |
| Ported to PHP by Michel Fortin |
| <http://www.michelf.com/> |
| |
| |
| Additional Credits |
| ------------------ |
| |
| Portions of this plug-in are based on Brad Choate's nifty MTRegex plug-in. |
| Brad Choate also contributed a few bits of source code to this plug-in. |
| Brad Choate is a fine hacker indeed. (<http://bradchoate.com/>) |
| |
| Jeremy Hedley (<http://antipixel.com/>) and Charles Wiltgen |
| (<http://playbacktime.com/>) deserve mention for exemplary beta testing. |
| |
| |
| Copyright and License |
| --------------------- |
| |
| Copyright (c) 2003 John Gruber |
| <http://daringfireball.net/> |
| All rights reserved. |
| |
| Copyright (c) 2004-2005 Michel Fortin |
| <http://www.michelf.com> |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| |
| * Neither the name "SmartyPants" nor the names of its contributors may |
| be used to endorse or promote products derived from this software |
| without specific prior written permission. |
| |
| This software is provided by the copyright holders and contributors "as is" |
| and any express or implied warranties, including, but not limited to, the |
| implied warranties of merchantability and fitness for a particular purpose |
| are disclaimed. In no event shall the copyright owner or contributors be |
| liable for any direct, indirect, incidental, special, exemplary, or |
| consequential damages (including, but not limited to, procurement of |
| substitute goods or services; loss of use, data, or profits; or business |
| interruption) however caused and on any theory of liability, whether in |
| contract, strict liability, or tort (including negligence or otherwise) |
| arising in any way out of the use of this software, even if advised of the |
| possibility of such damage. |
| |
| */ |
| ?> |