stdmarkup.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <?php if (!defined('PmWiki')) exit();
  2. /* Copyright 2004-2006 Patrick R. Michaud (pmichaud@pobox.com)
  3. This file is part of PmWiki; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published
  5. by the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version. See pmwiki.php for full details.
  7. This script defines PmWiki's standard markup. It is automatically
  8. included from stdconfig.php unless $EnableStdMarkup==0.
  9. Each call to Markup() below adds a new rule to PmWiki's translation
  10. engine (unless a rule with the same name has already been defined).
  11. The form of the call is Markup($id,$where,$pat,$rep);
  12. $id is a unique name for the rule, $where is the position of the rule
  13. relative to another rule, $pat is the pattern to look for, and
  14. $rep is the string to replace it with.
  15. */
  16. ## first we preserve text in [=...=] and [@...@]
  17. function PreserveText($sigil, $text, $lead) {
  18. if ($sigil=='=') return $lead.Keep($text);
  19. if (strpos($text, "\n")===false)
  20. return "$lead<code class='escaped'>".Keep($text)."</code>";
  21. $text = preg_replace("/\n[^\\S\n]+$/", "\n", $text);
  22. if ($lead == "" || $lead == "\n")
  23. return "$lead<pre class='escaped'>".Keep($text)."</pre>";
  24. return "$lead<:pre,1>".Keep($text);
  25. }
  26. Markup('[=','_begin',"/(\n[^\\S\n]*)?\\[([=@])(.*?)\\2\\]/se",
  27. "PreserveText('$2', PSS('$3'), '$1')");
  28. Markup('restore','<_end',"/$KeepToken(\\d.*?)$KeepToken/e",
  29. '$GLOBALS[\'KPV\'][\'$1\']');
  30. Markup('<:', '>restore',
  31. '/<:[^>]*>/', '');
  32. Markup('<vspace>', '<restore',
  33. '/<vspace>/',
  34. "<div class='vspace'></div>");
  35. Markup('<vspace><p>', '<<vspace>',
  36. "/<vspace><p\\b(([^>]*)(\\s)class=(['\"])([^>]*?)\\4)?/",
  37. "<p$2 class='vspace$3$5'");
  38. ## remove carriage returns before preserving text
  39. Markup('\\r','<[=','/\\r/','');
  40. # $[phrase] substitutions
  41. Markup('$[phrase]', '>[=',
  42. '/\\$\\[(?>([^\\]]+))\\]/e', "NoCache(XL(PSS('$1')))");
  43. # {$var} substitutions
  44. Markup('{$var}', '>$[phrase]',
  45. '/\\{(!?[-\\w.\\/]*)(\\$\\w+)\\}/e',
  46. "htmlspecialchars(PageVar(\$pagename, '$2', '$1'), ENT_NOQUOTES)");
  47. Markup('if', 'fulltext',
  48. "/\\(:(if[^\n]*?):\\)(.*?)(?=\\(:if[^\n]*?:\\)|$)/sei",
  49. "CondText(\$pagename,PSS('$1'),PSS('$2'))");
  50. ## (:include:)
  51. Markup('include', '>if',
  52. '/\\(:include\\s+(\\S.*?):\\)/ei',
  53. "PRR(IncludeText(\$pagename, '$1'))");
  54. ## (:redirect:)
  55. Markup('redirect', '<include',
  56. '/\\(:redirect\\s+(\\S.*?):\\)/ei',
  57. "RedirectMarkup(\$pagename, PSS('$1'))");
  58. $SaveAttrPatterns['/\\(:(if|include|redirect)(\\s.*?)?:\\)/i'] = ' ';
  59. ## GroupHeader/GroupFooter handling
  60. Markup('nogroupheader', '>include',
  61. '/\\(:nogroupheader:\\)/ei',
  62. "PZZ(\$GLOBALS['GroupHeaderFmt']='')");
  63. Markup('nogroupfooter', '>include',
  64. '/\\(:nogroupfooter:\\)/ei',
  65. "PZZ(\$GLOBALS['GroupFooterFmt']='')");
  66. Markup('groupheader', '>nogroupheader',
  67. '/\\(:groupheader:\\)/ei',
  68. "PRR(FmtPageName(\$GLOBALS['GroupHeaderFmt'],\$pagename))");
  69. Markup('groupfooter','>nogroupfooter',
  70. '/\\(:groupfooter:\\)/ei',
  71. "PRR(FmtPageName(\$GLOBALS['GroupFooterFmt'],\$pagename))");
  72. ## (:nl:)
  73. Markup('nl0','<split',"/([^\n])(?>(?:\\(:nl:\\))+)([^\n])/i","$1\n$2");
  74. Markup('nl1','>nl0',"/\\(:nl:\\)/i",'');
  75. ## \\$ (end of line joins)
  76. Markup('\\$','>nl1',"/\\\\(?>(\\\\*))\n/e",
  77. "str_repeat('<br />',strlen('$1'))");
  78. ## Remove one <:vspace> after !headings
  79. Markup('!vspace', '>\\$', "/^(!(?>[^\n]+)\n)<:vspace>/m", '$1');
  80. ## (:noheader:),(:nofooter:),(:notitle:)...
  81. Markup('noheader', 'directives',
  82. '/\\(:noheader:\\)/ei',
  83. "SetTmplDisplay('PageHeaderFmt',0)");
  84. Markup('nofooter', 'directives',
  85. '/\\(:nofooter:\\)/ei',
  86. "SetTmplDisplay('PageFooterFmt',0)");
  87. Markup('notitle', 'directives',
  88. '/\\(:notitle:\\)/ei',
  89. "SetTmplDisplay('PageTitleFmt',0)");
  90. Markup('noleft', 'directives',
  91. '/\\(:noleft:\\)/ei',
  92. "SetTmplDisplay('PageLeftFmt',0)");
  93. Markup('noright', 'directives',
  94. '/\\(:noright:\\)/ei',
  95. "SetTmplDisplay('PageRightFmt',0)");
  96. Markup('noaction', 'directives',
  97. '/\\(:noaction:\\)/ei',
  98. "SetTmplDisplay('PageActionFmt',0)");
  99. ## (:spacewikiwords:)
  100. Markup('spacewikiwords', 'directives',
  101. '/\\(:(no)?spacewikiwords:\\)/ei',
  102. "PZZ(\$GLOBALS['SpaceWikiWords']=('$1'!='no'))");
  103. ## (:linkwikiwords:)
  104. Markup('linkwikiwords', 'directives',
  105. '/\\(:(no)?linkwikiwords:\\)/ei',
  106. "PZZ(\$GLOBALS['LinkWikiWords']=('$1'!='no'))");
  107. ## (:linebreaks:)
  108. Markup('linebreaks', 'directives',
  109. '/\\(:(no)?linebreaks:\\)/ei',
  110. "PZZ(\$GLOBALS['HTMLPNewline'] = ('$1'!='no') ? '<br />' : '')");
  111. ## (:messages:)
  112. Markup('messages', 'directives',
  113. '/^\\(:messages:\\)/ei',
  114. "'<:block>'.Keep(
  115. FmtPageName(implode('',(array)\$GLOBALS['MessagesFmt']), \$pagename))");
  116. ## (:comment:)
  117. Markup('comment', 'directives', '/\\(:comment .*?:\\)/i', '');
  118. ## character entities
  119. Markup('&','directives','/&amp;(?>([A-Za-z0-9]+|#\\d+|#[xX][A-Fa-f0-9]+));/',
  120. '&$1;');
  121. ## (:title:)
  122. Markup('title','>&',
  123. '/\\(:title\\s(.*?):\\)/ei',
  124. "PZZ(PCache(\$pagename,
  125. \$zz=array('title' => SetProperty(\$pagename, 'title', PSS('$1')))))");
  126. ## (:keywords:), (:description:)
  127. Markup('keywords', '>&',
  128. "/\\(:keywords?\\s+(.+?):\\)/ei",
  129. "PZZ(SetProperty(\$pagename, 'keywords', PSS('$1'), ', '))");
  130. Markup('description', '>&',
  131. "/\\(:description\\s+(.+?):\\)/ei",
  132. "PZZ(SetProperty(\$pagename, 'description', PSS('$1'), '\n'))");
  133. $HTMLHeaderFmt['meta'] = 'function:PrintMetaTags';
  134. function PrintMetaTags($pagename, $args) {
  135. global $PCache;
  136. foreach(array('keywords', 'description') as $n) {
  137. foreach((array)@$PCache[$pagename]["=p_$n"] as $v) {
  138. $v = str_replace("'", '&#039;', $v);
  139. print "<meta name='$n' content='$v' />\n";
  140. }
  141. }
  142. }
  143. #### inline markups ####
  144. ## ''emphasis''
  145. Markup("''",'inline',"/''(.*?)''/",'<em>$1</em>');
  146. ## '''strong'''
  147. Markup("'''","<''","/'''(.*?)'''/",'<strong>$1</strong>');
  148. ## '''''strong emphasis'''''
  149. Markup("'''''","<'''","/'''''(.*?)'''''/",'<strong><em>$1</em></strong>');
  150. ## @@code@@
  151. Markup('@@','inline','/@@(.*?)@@/','<code>$1</code>');
  152. ## '+big+', '-small-'
  153. Markup("'+","<'''''","/'\\+(.*?)\\+'/",'<big>$1</big>');
  154. Markup("'-","<'''''","/'\\-(.*?)\\-'/",'<small>$1</small>');
  155. ## '^superscript^', '_subscript_'
  156. Markup("'^","<'''''","/'\\^(.*?)\\^'/",'<sup>$1</sup>');
  157. Markup("'_","<'''''","/'_(.*?)_'/",'<sub>$1</sub>');
  158. ## [+big+], [-small-]
  159. Markup('[+','inline','/\\[(([-+])+)(.*?)\\1\\]/e',
  160. "'<span style=\'font-size:'.(round(pow(6/5,$2strlen('$1'))*100,0)).'%\'>'.
  161. PSS('$3</span>')");
  162. ## {+ins+}, {-del-}
  163. Markup('{+','inline','/\\{\\+(.*?)\\+\\}/','<ins>$1</ins>');
  164. Markup('{-','inline','/\\{-(.*?)-\\}/','<del>$1</del>');
  165. ## [[<<]] (break)
  166. Markup('[[<<]]','inline','/\\[\\[&lt;&lt;\\]\\]/',"<br clear='all' />");
  167. ###### Links ######
  168. ## [[free links]]
  169. Markup('[[','links',"/(?>\\[\\[\\s*(.*?)\\]\\])($SuffixPattern)/e",
  170. "Keep(MakeLink(\$pagename,PSS('$1'),NULL,'$2'),'L')");
  171. ## [[!Category]]
  172. SDV($CategoryGroup,'Category');
  173. SDV($LinkCategoryFmt,"<a class='categorylink' href='\$LinkUrl'>\$LinkText</a>");
  174. Markup('[[!','<[[','/\\[\\[!(.*?)\\]\\]/e',
  175. "Keep(MakeLink(\$pagename,PSS('$CategoryGroup/$1'),NULL,'',\$GLOBALS['LinkCategoryFmt']),'L')");
  176. # This is a temporary workaround for blank category pages.
  177. # It may be removed in a future release (Pm, 2006-01-24)
  178. if (preg_match("/^$CategoryGroup\\./", $pagename)) {
  179. SDV($DefaultPageTextFmt, '');
  180. SDV($PageNotFoundHeaderFmt, 'HTTP/1.1 200 Ok');
  181. }
  182. ## [[target | text]]
  183. Markup('[[|','<[[',
  184. "/(?>\\[\\[([^|\\]]*)\\|\\s*)(.*?)\\s*\\]\\]($SuffixPattern)/e",
  185. "Keep(MakeLink(\$pagename,PSS('$1'),PSS('$2'),'$3'),'L')");
  186. ## [[text -> target ]]
  187. Markup('[[->','>[[|',
  188. "/(?>\\[\\[([^\\]]+?)\\s*-+&gt;\\s*)(.*?)\\]\\]($SuffixPattern)/e",
  189. "Keep(MakeLink(\$pagename,PSS('$2'),PSS('$1'),'$3'),'L')");
  190. ## [[#anchor]]
  191. Markup('[[#','<[[','/(?>\\[\\[#([A-Za-z][-.:\\w]*))\\]\\]/e',
  192. "Keep(TrackAnchors('$1') ? '' : \"<a name='$1' id='$1'></a>\", 'L')");
  193. function TrackAnchors($x) { global $SeenAnchor; return @$SeenAnchor[$x]++; }
  194. ## [[target |#]] reference links
  195. Markup('[[|#', '<[[|',
  196. "/(?>\\[\\[([^|\\]]+))\\|\\s*#\\s*\\]\\]/e",
  197. "Keep(MakeLink(\$pagename,PSS('$1'),'['.++\$MarkupFrame[0]['ref'].']'),'L')");
  198. ## [[target |+]] title links
  199. Markup('[[|+', '<[[|',
  200. "/(?>\\[\\[([^|\\]]+))\\|\\s*\\+\\s*]]/e",
  201. "Keep(MakeLink(\$pagename, PSS('$1'),
  202. PageVar(MakePageName(\$pagename,PSS('$1')), '\$Title')
  203. ),'L')");
  204. ## bare urllinks
  205. Markup('urllink','>[[',
  206. "/\\b(?>(\\L))[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]/e",
  207. "Keep(MakeLink(\$pagename,'$0','$0'),'L')");
  208. ## mailto: links
  209. Markup('mailto','<urllink',
  210. "/\\bmailto:([^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars])/e",
  211. "Keep(MakeLink(\$pagename,'$0','$1'),'L')");
  212. ## inline images
  213. Markup('img','<urllink',
  214. "/\\b(?>(\\L))([^\\s$UrlExcludeChars]+$ImgExtPattern)(\"([^\"]*)\")?/e",
  215. "Keep(\$GLOBALS['LinkFunctions']['$1'](\$pagename,'$1','$2','$4','$1$2',
  216. \$GLOBALS['ImgTagFmt']),'L')");
  217. ## bare wikilinks
  218. Markup('wikilink', '>urllink',
  219. "/\\b($GroupPattern([\\/.]))?($WikiWordPattern)/e",
  220. "Keep('<span class=\\'wikiword\\'>'.WikiLink(\$pagename,'$0').'</span>',
  221. 'L')");
  222. ## escaped `WikiWords
  223. Markup('`wikiword', '<wikilink',
  224. "/`(($GroupPattern([\\/.]))?($WikiWordPattern))/e",
  225. "Keep('$1')");
  226. #### Block markups ####
  227. ## Completely blank lines don't do anything.
  228. Markup('blank', '<block', '/^\\s+$/', '');
  229. ## process any <:...> markup (after all other block markups)
  230. Markup('^<:','>block','/^(?=\\s*\\S)(<:([^>]+)>)?/e',"Block('$2')");
  231. ## unblocked lines w/block markup become anonymous <:block>
  232. Markup('^!<:', '<^<:',
  233. "/^(?!<:)(?=.*(<\\/?($BlockPattern)\\b)|$KeepToken\\d+B$KeepToken)/",
  234. '<:block>');
  235. ## Lines that begin with displayed images receive their own block. A
  236. ## pipe following the image indicates a "caption" (generates a linebreak).
  237. Markup('^img', 'block',
  238. "/^((?>(\\s+|%%|%[A-Za-z][-,=:#\\w\\s'\".]*%)*)$KeepToken(\\d+L)$KeepToken)(\\s*\\|\\s?)?(.*)$/e",
  239. "PSS((strpos(\$GLOBALS['KPV']['$3'],'<img')===false) ? '$0' :
  240. '<:block,1><div>$1' . ('$4' ? '<br />' : '') .'$5</div>')");
  241. ## Whitespace at the beginning of lines can be used to maintain the
  242. ## indent level of a previous list item, or a preformatted text block.
  243. Markup('^ws', '<^img', '/^(\\s+)/e', "WSIndent('$1')");
  244. function WSIndent($i) {
  245. global $MarkupFrame;
  246. $icol = strlen($i);
  247. for($depth = count(@$MarkupFrame[0]['cs']); $depth > 0; $depth--)
  248. if (@$MarkupFrame[0]['is'][$depth] == $icol) {
  249. $MarkupFrame[0]['idep'] = $depth;
  250. $MarkupFrame[0]['icol'] = $icol;
  251. return '';
  252. }
  253. return "<:pre,1>$i";
  254. }
  255. ## If the ^ws rule is disabled, then leading whitespace is a
  256. ## preformatted text block.
  257. Markup('^ ','block','/^(\\s)/','<:pre,1>$1');
  258. ## bullet lists
  259. Markup('^*','block','/^(\\*+)\\s?(\\s*)/','<:ul,$1,$0>$2');
  260. ## numbered lists
  261. Markup('^#','block','/^(#+)\\s?(\\s*)/','<:ol,$1,$0>$2');
  262. ## indented (->) /hanging indent (-<) text
  263. Markup('^->','block','/^(?>(-+))&gt;\\s?(\\s*)/','<:indent,$1,$1 $2>$2');
  264. Markup('^-<','block','/^(?>(-+))&lt;\\s?(\\s*)/','<:outdent,$1,$1 $2>$2');
  265. ## definition lists
  266. Markup('^::','block','/^(:+)(\s*)([^:]+):/','<:dl,$1,$1$2><dt>$2$3</dt><dd>');
  267. ## Q: and A:
  268. Markup('^Q:', 'block', '/^Q:(.*)$/', "<:block,1><p class='question'>$1</p>");
  269. Markup('^A:', 'block', '/^A:/', Keep(''));
  270. ## tables
  271. ## ||cell||, ||!header cell||, ||!caption!||
  272. Markup('^||||', 'block',
  273. '/^\\|\\|.*\\|\\|.*$/e',
  274. "FormatTableRow(PSS('$0'))");
  275. ## ||table attributes
  276. Markup('^||','>^||||','/^\\|\\|(.*)$/e',
  277. "PZZ(\$GLOBALS['BlockMarkups']['table'][0] = '<table '.PQA(PSS('$1')).'>')
  278. .'<:block,1>'");
  279. ## headings
  280. Markup('^!', 'block',
  281. '/^(!{1,6})\\s?(.*)$/e',
  282. "'<:block,1><h'.strlen('$1').PSS('>$2</h').strlen('$1').'>'");
  283. ## horiz rule
  284. Markup('^----','>^->','/^----+/','<:block,1><hr />');
  285. #### (:table:) markup (AdvancedTables)
  286. function Cells($name,$attr) {
  287. global $MarkupFrame;
  288. $attr = PQA($attr);
  289. $tattr = @$MarkupFrame[0]['tattr'];
  290. $name = strtolower($name);
  291. $key = preg_replace('/end$/', '', $name);
  292. if (strncmp($key, 'cell', 4) == 0) $key = 'cell';
  293. $out = '<:block>'.MarkupClose($key);
  294. if (substr($name, -3) == 'end') return $out;
  295. $cf = & $MarkupFrame[0]['closeall'];
  296. if ($name == 'table') $MarkupFrame[0]['tattr'] = $attr;
  297. else if (strncmp($name, 'cell', 4) == 0) {
  298. if (strpos($attr, "valign=")===false) $attr .= " valign='top'";
  299. if (!@$cf['table']) {
  300. $tattr = @$MarkupFrame[0]['tattr'];
  301. $out .= "<table $tattr><tr><td $attr>";
  302. $cf['table'] = '</td></tr></table><!---->';
  303. } else if ($name == 'cellnr') $out .= "</td></tr><tr><td $attr>";
  304. else $out .= "</td><td $attr>";
  305. $cf['cell'] = '';
  306. } else {
  307. $out .= "<div $attr>";
  308. $cf[$key] = '</div>';
  309. }
  310. return $out;
  311. }
  312. Markup('table', '<block',
  313. '/^\\(:(table|cell|cellnr|tableend|div\\d*(?:end)?)(\\s.*?)?:\\)/ie',
  314. "Cells('$1',PSS('$2'))");
  315. Markup('^>>', '<table',
  316. '/^&gt;&gt;(.+?)&lt;&lt;(.*)$/',
  317. '(:div:)%div $1 apply=div%$2 ');
  318. Markup('^>><<', '<^>>',
  319. '/^&gt;&gt;&lt;&lt;/',
  320. '(:divend:)');
  321. #### special stuff ####
  322. ## (:markup:) for displaying markup examples
  323. function MarkupMarkup($pagename, $text, $opt = '') {
  324. $MarkupMarkupOpt = array('class' => 'vert');
  325. $opt = array_merge($MarkupMarkupOpt, ParseArgs($opt));
  326. $html = MarkupToHTML($pagename, $text, array('escape' => 0));
  327. if (@$opt['caption'])
  328. $caption = str_replace("'", '&#039;',
  329. "<caption>{$opt['caption']}</caption>");
  330. $class = preg_replace('/[^-\\s\\w]+/', ' ', @$opt['class']);
  331. if (strpos($class, 'horiz') !== false)
  332. { $sep = ''; $pretext = wordwrap($text, 40); }
  333. else
  334. { $sep = '</tr><tr>'; $pretext = wordwrap($text, 75); }
  335. return Keep("<table class='markup $class' align='center'>$caption
  336. <tr><td class='markup1' valign='top'><pre>$pretext</pre></td>$sep<td
  337. class='markup2' valign='top'>$html</td></tr></table>");
  338. }
  339. Markup('markup', '<[=',
  340. "/\\(:markup(\\s+([^\n]*?))?:\\)[^\\S\n]*\\[([=@])(.*?)\\3\\]/sei",
  341. "MarkupMarkup(\$pagename, PSS('$4'), PSS('$2'))");
  342. Markup('markupend', '>markup',
  343. "/\\(:markup(\\s+([^\n]*?))?:\\)[^\\S\n]*\n(.*?)\\(:markupend:\\)/sei",
  344. "MarkupMarkup(\$pagename, PSS('$3'), PSS('$1'))");
  345. SDV($HTMLStylesFmt['markup'], "
  346. table.markup { border:2px dotted #ccf; width:90%; }
  347. td.markup1, td.markup2 { padding-left:10px; padding-right:10px; }
  348. table.vert td.markup1 { border-bottom:1px solid #ccf; }
  349. table.horiz td.markup1 { width:23em; border-right:1px solid #ccf; }
  350. table.markup caption { text-align:left; }
  351. div.faq p, div.faq pre { margin-left:2em; }
  352. div.faq p.question { margin:1em 0 0.75em 0; font-weight:bold; }
  353. ");
  354. #### Special conditions ####
  355. ## The code below adds (:if date:) conditions to the markup.
  356. $Conditions['date'] = "CondDate(\$condparm)";
  357. function CondDate($condparm) {
  358. global $Now;
  359. NoCache();
  360. if (!preg_match('/^(.*?)(\\.\\.(.*))?$/', $condparm, $match)) return false;
  361. if ($match[2]) {
  362. $t0 = $match[1]; if ($t0 == '') $t0 = '19700101';
  363. $t1 = $match[3]; if ($t1 == '') $t1 = '20380101';
  364. } else $t0 = $t1 = $match[1];
  365. $t0 = preg_replace('/\\D/', '', $t0);
  366. if (!preg_match('/^(\\d{4})(\\d\\d)(\\d\\d)$/', $t0, $m)) return false;
  367. $g0 = mktime(0, 0, 0, $m[2], $m[3], $m[1]);
  368. if ($Now < $g0) return false;
  369. $t1 = preg_replace('/\\D/', '', $t1);
  370. $t1++;
  371. if (!preg_match('/^(\\d{4})(\\d\\d)(\\d\\d)$/', $t1, $m)) return false;
  372. $g1 = mktime(0, 0, 0, $m[2], $m[3], $m[1]);
  373. if ($Now >= $g1) return false;
  374. return true;
  375. }
  376. # This pattern enables the (:encrypt <phrase>:) markup/replace-on-save
  377. # pattern.
  378. SDV($ROSPatterns['/\\(:encrypt\\s+([^\\s:=]+).*?:\\)/e'], "crypt(PSS('$1'))");