".Keep($text).""; $text = preg_replace("/\n[^\\S\n]+$/", "\n", $text); if ($lead == "" || $lead == "\n") return "$lead
".Keep($text)."
"; return "$lead<:pre,1>".Keep($text); } Markup('[=','_begin',"/(\n[^\\S\n]*)?\\[([=@])(.*?)\\2\\]/s", "MarkupPreserveText"); function MarkupPreserveText($m) {return PreserveText($m[2], $m[3], $m[1]);} Markup('restore','<_end',"/$KeepToken(\\d.*?)$KeepToken/", 'cb_expandkpv'); Markup('<:', '>restore', '/<:[^>]*>/', ''); Markup('', '/', "
"); Markup('

', '<', "/]*)(\\s)class=(['\"])([^>]*?)\\4)?/", "[=', '/\\$\\[(?>([^\\]]+))\\]/', "cb_expandxlang"); # {$var} substitutions Markup('{$var}', '>$[phrase]', '/\\{(\\*|!?[-\\w.\\/\\x80-\\xff]*)(\\$:?\\w[-\\w]*)\\}/', "MarkupPageVar"); function MarkupPageVar($m){ extract($GLOBALS["MarkupToHTML"]); return PRR(PVSE(PageVar($pagename, $m[2], $m[1]))); } # invisible (:textvar:...:) definition Markup('textvar:', '([A-Za-z0-9]+|#\\d+|#[xX][A-Fa-f0-9]+));/', '&$1;'); Markup('&amp;', '<&', '/&amp;/', Keep('&')); ## (:if:)/(:elseif:)/(:else:) SDV($CondTextPattern, "/ \\(:if (\d*) (?:end)? \\b[^\n]*?:\\) .*? (?: \\(: (?:if\\1|if\\1end) \\s* :\\) | (?=\\(:(?:if\\1|if\\1end)\\b[^\n]*?:\\) | $) ) /six"); // SDV($CondTextReplacement, "CondText2(\$pagename, \$m[0], \$m[1])"); SDV($CondTextReplacement, "MarkupCondText2"); Markup('if', 'fulltext', $CondTextPattern, $CondTextReplacement); function MarkupCondText2($m) { extract($GLOBALS["MarkupToHTML"]); return CondText2($pagename, $m[0], $m[1]); } function CondText2($pagename, $text, $code = '') { global $Conditions, $CondTextPattern, $CondTextReplacement; $if = "if$code"; $repl = str_replace('$pagename', "'$pagename'", $CondTextReplacement); $parts = preg_split("/\\(:(?:{$if}end|$if|else *$if|else$code)\\b\\s*(.*?)\\s*:\\)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE); $x = array_shift($parts); while ($parts) { list($condspec, $condtext) = array_splice($parts, 0, 2); if (!preg_match("/^\\s*(!?)\\s*(\\S*)\\s*(.*?)\\s*$/", $condspec, $match)) continue; list($x, $not, $condname, $condparm) = $match; if (!isset($Conditions[$condname])) return preg_replace_callback($CondTextPattern, $repl, $condtext); $tf = @eval("return ({$Conditions[$condname]});"); if ($tf xor $not) return preg_replace_callback($CondTextPattern, $repl, $condtext); } return ''; } ## (:include:) Markup('include', '>if', '/\\(:include\\s+(\\S.*?):\\)/i', "MarkupRedirectInclude"); ## (:redirect:) Markup('redirect', 'include', '/\\(:nogroupheader:\\)/i', "MarkupGroupHeaderFooter"); Markup('nogroupfooter', '>include', '/\\(:nogroupfooter:\\)/i', "MarkupGroupHeaderFooter"); Markup('groupheader', '>nogroupheader', '/\\(:groupheader:\\)/i', "MarkupGroupHeaderFooter"); Markup('groupfooter','>nogroupfooter', '/\\(:groupfooter:\\)/i', "MarkupGroupHeaderFooter"); function MarkupGroupHeaderFooter($m) { extract($GLOBALS["MarkupToHTML"]); global $GroupHeaderFmt, $GroupFooterFmt; switch ($markupid) { case 'nogroupheader': return PZZ($GroupHeaderFmt=''); case 'nogroupfooter': return PZZ($GroupFooterFmt=''); case 'groupheader': return PRR(FmtPageName($GroupHeaderFmt,$pagename)); case 'groupfooter': return PRR(FmtPageName($GroupFooterFmt,$pagename)); } } ## (:nl:) Markup('nl0','(?:\\(:nl:\\))+)([^\n])/i","$1\n$2"); Markup('nl1','>nl0',"/\\(:nl:\\)/i",''); ## \\$ (end of line joins) Markup('\\$','>nl1',"/\\\\(?>(\\\\*))\n/", "MarkupEndLineJoin"); function MarkupEndLineJoin($m) { return str_repeat('
',strlen($m[1])); } ## Remove one <:vspace> after !headings Markup('!vspace', '>\\$', "/^(!(?>[^\n]+)\n)<:vspace>/m", '$1'); ## (:noheader:),(:nofooter:),(:notitle:)... Markup('noheader', 'directives', '/\\(:noheader:\\)/i', "MarkupTmplDisplay"); Markup('nofooter', 'directives', '/\\(:nofooter:\\)/i', "MarkupTmplDisplay"); Markup('notitle', 'directives', '/\\(:notitle:\\)/i', "MarkupTmplDisplay"); Markup('noleft', 'directives', '/\\(:noleft:\\)/i', "MarkupTmplDisplay"); Markup('noright', 'directives', '/\\(:noright:\\)/i', "MarkupTmplDisplay"); Markup('noaction', 'directives', '/\\(:noaction:\\)/i', "MarkupTmplDisplay"); function MarkupTmplDisplay($m) { extract($GLOBALS["MarkupToHTML"]); switch ($markupid) { case 'noheader': return SetTmplDisplay('PageHeaderFmt',0); case 'nofooter': return SetTmplDisplay('PageFooterFmt',0); case 'notitle': return SetTmplDisplay('PageTitleFmt',0); case 'noleft': return SetTmplDisplay('PageLeftFmt',0); case 'noright': return SetTmplDisplay('PageRightFmt',0); case 'noaction': return SetTmplDisplay('PageActionFmt',0); } } ## (:spacewikiwords:) Markup('spacewikiwords', 'directives', '/\\(:(no)?spacewikiwords:\\)/i', "MarkupDirectives"); ## (:linkwikiwords:) Markup('linkwikiwords', 'directives', '/\\(:(no)?linkwikiwords:\\)/i', "MarkupDirectives"); ## (:linebreaks:) Markup('linebreaks', 'directives', '/\\(:(no)?linebreaks:\\)/i', "MarkupDirectives"); ## (:messages:) Markup('messages', 'directives', '/^\\(:messages:\\)/i', "MarkupDirectives"); function MarkupDirectives($m) { extract($GLOBALS["MarkupToHTML"]); switch ($markupid) { case 'linkwikiwords': return PZZ($GLOBALS['LinkWikiWords']=($m[1]!='no')); case 'spacewikiwords': return PZZ($GLOBALS['SpaceWikiWords']=($m[1]!='no')); case 'linebreaks': return PZZ($GLOBALS['HTMLPNewline'] = (@$m[1]!='no') ? '
' : ''); case 'messages': return '<:block>'.Keep(FmtPageName( implode('',(array)$GLOBALS['MessagesFmt']), $pagename)); } } ## (:comment:) Markup('comment', 'directives', '/\\(:comment .*?:\\)/i', ''); ## (:title:) +fix for PITS:00266, 00779 $tmpwhen = IsEnabled($EnablePageTitlePriority, 0) ? ' SetProperty($pagename, 'title', $m[1], NULL, $EnablePageTitlePriority)))); case 'keywords': return PZZ(SetProperty($pagename, 'keywords', $m[1], ', ')); case 'description': return PZZ(SetProperty($pagename, 'description', $m[1], '\n')); } } ## (:keywords:), (:description:) Markup('keywords', 'directives', "/\\(:keywords?\\s+(.+?):\\)/i", "MarkupSetProperty"); Markup('description', 'directives', "/\\(:description\\s+(.+?):\\)/i", "MarkupSetProperty"); $HTMLHeaderFmt['meta'] = 'function:PrintMetaTags'; function PrintMetaTags($pagename, $args) { global $PCache; foreach(array('keywords', 'description') as $n) { foreach((array)@$PCache[$pagename]["=p_$n"] as $v) { $v = str_replace("'", ''', $v); print "\n"; } } } #### inline markups #### ## ''emphasis'' Markup("''",'inline',"/''(.*?)''/",'$1'); ## '''strong''' Markup("'''","<''","/'''(.*?)'''/",'$1'); ## '''''strong emphasis''''' Markup("'''''","<'''","/'''''(.*?)'''''/",'$1'); ## @@code@@ Markup('@@','inline','/@@(.*?)@@/','$1'); ## '+big+', '-small-' Markup("'+","<'''''","/'\\+(.*?)\\+'/",'$1'); Markup("'-","<'''''","/'\\-(.*?)\\-'/",'$1'); ## '^superscript^', '_subscript_' Markup("'^","<'''''","/'\\^(.*?)\\^'/",'$1'); Markup("'_","<'''''","/'_(.*?)_'/",'$1'); ## [+big+], [-small-] Markup('[+','inline','/\\[(([-+])+)(.*?)\\1\\]/', "MarkupBigSmall"); function MarkupBigSmall($m) { return ''. $m[3].''; } ## {+ins+}, {-del-} Markup('{+','inline','/\\{\\+(.*?)\\+\\}/','$1'); Markup('{-','inline','/\\{-(.*?)-\\}/','$1'); ## [[<<]] (break) Markup('[[<<]]','inline','/\\[\\[<<\\]\\]/',"
"); ###### Links ###### function MarkupLinks($m){ extract($GLOBALS["MarkupToHTML"]); switch ($markupid) { case '[[': return Keep(MakeLink($pagename,$m[1],NULL,$m[2]),'L'); case '[[!': global $CategoryGroup, $LinkCategoryFmt; return Keep(MakeLink($pagename,"$CategoryGroup/{$m[1]}",NULL,'', $LinkCategoryFmt),'L'); case '[[|': return Keep(MakeLink($pagename,$m[1],$m[2],$m[3]),'L'); case '[[->': return Keep(MakeLink($pagename,$m[2],$m[1],$m[3]),'L'); case '[[|#': return Keep(MakeLink($pagename,$m[1], '['.++$GLOBALS['MarkupFrame'][0]['ref'].']'),'L'); case '[[#': return Keep(TrackAnchors($m[1]) ? '' : "", 'L'); case 'urllink': return Keep(MakeLink($pagename,$m[0],$m[0]),'L'); case 'mailto': return Keep(MakeLink($pagename,$m[0],$m[1]),'L'); case 'img': global $LinkFunctions, $ImgTagFmt; return Keep($LinkFunctions[$m[1]]($pagename,$m[1],$m[2],@$m[4],$m[1].$m[2], $ImgTagFmt),'L'); } } ## [[free links]] Markup('[[','links',"/(?>\\[\\[\\s*(.*?)\\]\\])($SuffixPattern)/", "MarkupLinks"); ## [[!Category]] SDV($CategoryGroup,'Category'); SDV($LinkCategoryFmt,"\$LinkText"); Markup('[[!','<[[','/\\[\\[!(.*?)\\]\\]/', "MarkupLinks"); # This is a temporary workaround for blank category pages. # It may be removed in a future release (Pm, 2006-01-24) if (preg_match("/^$CategoryGroup\\./", $pagename)) { SDV($DefaultPageTextFmt, ''); SDV($PageNotFoundHeaderFmt, 'HTTP/1.1 200 Ok'); } ## [[target | text]] Markup('[[|','<[[', "/(?>\\[\\[([^|\\]]*)\\|\\s*)(.*?)\\s*\\]\\]($SuffixPattern)/", "MarkupLinks"); ## [[text -> target ]] Markup('[[->','>[[|', "/(?>\\[\\[([^\\]]+?)\\s*-+>\\s*)(.*?)\\]\\]($SuffixPattern)/", "MarkupLinks"); ## [[#anchor]] Markup('[[#','<[[','/(?>\\[\\[#([A-Za-z][-.:\\w]*))\\]\\]/', "MarkupLinks"); function TrackAnchors($x) { global $SeenAnchor; return @$SeenAnchor[$x]++; } ## [[target |#]] reference links Markup('[[|#', '<[[|', "/(?>\\[\\[([^|\\]]+))\\|\\s*#\\s*\\]\\]/", "MarkupLinks"); ## [[target |+]] title links moved inside LinkPage() ## bare urllinks Markup('urllink','>[[', "/\\b(?>(\\L))[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]/", "MarkupLinks"); ## mailto: links Markup('mailto','(\\L))([^\\s$UrlExcludeChars]+$ImgExtPattern)(\"([^\"]*)\")?/", "MarkupLinks"); if (IsEnabled($EnableRelativePageLinks, 1)) SDV($QualifyPatterns['/(\\[\\[(?>[^\\]]+?->)?\\s*)([-\\w\\x80-\\xfe\\s\'()]+([|#?].*?)?\\]\\])/'], 'cb_qualifylinks'); function cb_qualifylinks($m) { extract($GLOBALS['tmp_qualify']); return "{$m[1]}$group/{$m[2]}"; } ## bare wikilinks ## v2.2: markup rule moved to scripts/wikiwords.php) Markup('wikilink', '>urllink'); ## escaped `WikiWords ## v2.2: rule kept here for markup compatibility with 2.1 and earlier Markup('`wikiword', ' markup (after all other block markups) Markup('^<:','>block','/^(?=\\s*\\S)(<:([^>]+)>)?/',"MarkupBlock"); function MarkupBlock($m) {return Block(@$m[2]);} ## unblocked lines w/block markup become anonymous <:block> Markup('^!<:', '<^<:', "/^(?!<:)(?=.*(<\\/?($BlockPattern)\\b)|$KeepToken\\d+B$KeepToken)/", '<:block>'); ## Lines that begin with displayed images receive their own block. A ## pipe following the image indicates a "caption" (generates a linebreak). Markup('^img', 'block', "/^((?>(\\s+|%%|%[A-Za-z][-,=:#\\w\\s'\".]*%)*)$KeepToken(\\d+L)$KeepToken)(\\s*\\|\\s?)?(.*)$/", "ImgCaptionDiv"); function ImgCaptionDiv($m) { global $KPV; if (strpos($KPV[$m[3]], '

$ret
"; } ## Whitespace at the beginning of lines can be used to maintain the ## indent level of a previous list item, or a preformatted text block. Markup('^ws', '<^img', '/^\\s+ #1/x', "WSIndent"); function WSIndent($i) { if(is_array($i)) $i = $i[0]; global $MarkupFrame; $icol = strlen($i); for($depth = count(@$MarkupFrame[0]['cs']); $depth > 0; $depth--) if (@$MarkupFrame[0]['is'][$depth] == $icol) { $MarkupFrame[0]['idep'] = $depth; $MarkupFrame[0]['icol'] = $icol; return ''; } return $i; } ## The $EnableWSPre setting uses leading spaces on markup lines to indicate ## blocks of preformatted text. SDV($EnableWSPre, 1); Markup('^ ', 'block', '/^\\s+ #2/x', "MarkupWSPre"); function MarkupWSPre($m) { global $EnableWSPre; return ($EnableWSPre > 0 && strlen($m[0]) >= $EnableWSPre) ? '<:pre,1>'.$m[0] : $m[0]; } ## bullet lists Markup('^*','block','/^(\\*+)\\s?(\\s*)/','<:ul,$1,$0>$2'); ## numbered lists Markup('^#','block','/^(#+)\\s?(\\s*)/','<:ol,$1,$0>$2'); ## indented (->) /hanging indent (-<) text Markup('^->','block','/^(?>(-+))>\\s?(\\s*)/','<:indent,$1,$1 $2>$2'); Markup('^-<','block','/^(?>(-+))<\\s?(\\s*)/','<:outdent,$1,$1 $2>$2'); ## definition lists Markup('^::','block','/^(:+)(\s*)([^:]+):/','<:dl,$1,$1$2>
$2$3
'); ## Q: and A: Markup('^Q:', 'block', '/^Q:(.*)$/', "<:block,1>

$1

"); Markup('^A:', 'block', '/^A:/', Keep('')); ## tables function MarkupTables($m) { extract($GLOBALS["MarkupToHTML"]); switch ($markupid) { case 'table': return Cells(@$m[1],@$m[2]); case '^||||': return FormatTableRow($m[0]); case '^||': $GLOBALS['BlockMarkups']['table'][0] = ''; return '<:block,1>'; } } ## ||cell||, ||!header cell||, ||!caption!|| Markup('^||||', 'block', '/^\\|\\|.*\\|\\|.*$/', "MarkupTables"); ## ||table attributes Markup('^||','>^||||','/^\\|\\|(.*)$/', "MarkupTables"); #### (:table:) markup (AdvancedTables) Markup('table', '>', '><<', '<^>>', '/^>><</', '(:divend:)'); function SimpleTableAttr($attr) { global $SimpleTableDefaultClassName; $qattr = PQA($attr); if(IsEnabled($SimpleTableDefaultClassName) && !preg_match("/(^| )class='.*?' /", $qattr)) $qattr .= "class='$SimpleTableDefaultClassName'"; return $qattr; } #### (:table:) markup (AdvancedTables) function Cells($name,$attr) { global $MarkupFrame, $EnableTableAutoValignTop; $attr = PQA($attr); $tattr = @$MarkupFrame[0]['tattr']; $name = strtolower($name); $key = preg_replace('/end$/', '', $name); if (preg_match("/^(?:head|cell)(nr)?$/", $name)) $key = 'cell'; $out = '<:block>'.MarkupClose($key); if (substr($name, -3) == 'end') return $out; $cf = & $MarkupFrame[0]['closeall']; if ($name == 'table') $MarkupFrame[0]['tattr'] = $attr; else if ($key == 'cell') { if (IsEnabled($EnableTableAutoValignTop, 1) && strpos($attr, "valign=")===false) $attr .= " valign='top'"; $t = (strpos($name, 'head')===0 ) ? 'th' : 'td'; if (!@$cf['table']) { $tattr = @$MarkupFrame[0]['tattr']; $out .= "
<$t $attr>"; $cf['table'] = '
'; } else if ( preg_match("/nr$/", $name)) $out .= "<$t $attr>"; else $out .= "<$t $attr>"; $cf['cell'] = ""; } else { $tag = preg_replace('/\\d+$/', '', $key); $tmp = "<$tag $attr>"; if ($tag == 'details') { $tmp = preg_replace("#($2', $tmp); } $out .= $tmp; $cf[$key] = ""; } return $out; } ## headings Markup('^!', 'block', '/^(!{1,6})\\s?(.*)$/', "MarkupHeadings"); function MarkupHeadings($m) { $len = strlen($m[1]); return "<:block,1>$m[2]"; } ## horiz rule Markup('^----','>^->','/^----+/','<:block,1>
'); #### special stuff #### ## (:markup:) for displaying markup examples function MarkupMarkup($pagename, $text, $opt = '') { global $MarkupWordwrapFunction, $MarkupWrapTag; SDV($MarkupWordwrapFunction, 'IsEnabled'); SDV($MarkupWrapTag, 'pre'); $MarkupMarkupOpt = array('class' => 'vert'); $opt = array_merge($MarkupMarkupOpt, ParseArgs($opt)); $html = MarkupToHTML($pagename, $text, array('escape' => 0)); if (@$opt['caption']) $caption = str_replace("'", ''', "{$opt['caption']}"); $class = preg_replace('/[^-\\s\\w]+/', ' ', @$opt['class']); if (strpos($class, 'horiz') !== false) { $sep = ''; $pretext = $MarkupWordwrapFunction($text, 40); } else { $sep = ''; $pretext = $MarkupWordwrapFunction($text, 75); } return Keep(@"$caption $sep
<$MarkupWrapTag>$pretext$html
"); } Markup('markup', '<[=', "/\\(:markup(\\s+([^\n]*?))?:\\)[^\\S\n]*\\[([=@])(.*?)\\3\\]/si", "MarkupMarkupMarkup"); Markup('markupend', '>markup', # $1 only shifts the other matches "/\\(:(markup)(\\s+([^\n]*?))?:\\)[^\\S\n]*\n(.*?)\\(:markupend:\\)/si", "MarkupMarkupMarkup"); function MarkupMarkupMarkup($m) { # cannot be joined, $markupid resets extract($GLOBALS["MarkupToHTML"]); global $MarkupMarkupLevel; @$MarkupMarkupLevel++; $x = MarkupMarkup($pagename, $m[4], $m[2]); $MarkupMarkupLevel--; return $x; } SDV($HTMLStylesFmt['markup'], " table.markup { border:2px dotted #ccf; width:90%; } td.markup1, td.markup2 { padding-left:10px; padding-right:10px; } table.vert td.markup1 { border-bottom:1px solid #ccf; } table.horiz td.markup1 { width:23em; border-right:1px solid #ccf; } table.markup caption { text-align:left; } div.faq p, div.faq pre { margin-left:2em; } div.faq p.question { margin:1em 0 0.75em 0; font-weight:bold; } div.faqtoc div.faq * { display:none; } div.faqtoc div.faq p.question { display:block; font-weight:normal; margin:0.5em 0 0.5em 20px; line-height:normal; } div.faqtoc div.faq p.question * { display:inline; } td.markup1 pre { white-space: pre-wrap; } "); #### Special conditions #### ## The code below adds (:if date:) conditions to the markup. $Conditions['date'] = "CondDate(\$condparm)"; function CondDate($condparm) { global $Now; if (!preg_match('/^(\\S*?)(\\.\\.(\\S*))?(\\s+\\S.*)?$/', trim($condparm), $match)) return false; if ($match[4] == '') { $x0 = $Now; NoCache(); } else { list($x0, $x1) = DRange($match[4]); } if ($match[1] > '') { list($t0, $t1) = DRange($match[1]); if ($x0 < $t0) return false; if ($match[2] == '' && $x0 >= $t1) return false; } if ($match[3] > '') { list($t0, $t1) = DRange($match[3]); if ($x0 >= $t1) return false; } return true; } # This pattern enables the (:encrypt :) markup/replace-on-save # pattern. SDV($ROSPatterns['/\\(:encrypt\\s+([^\\s:=]+).*?:\\)/'], 'cb_encrypt'); function cb_encrypt($m) { return pmcrypt($m[1]);} # Table of contents, based on Cookbook:AutoTOC by Petko Yotov SDVA($PmTOC, array( 'Enable' => 0, 'MaxLevel' => 6, 'MinNumber' => 3, 'ParentElement'=>'', 'NumberedHeadings'=>'', 'EnableBacklinks'=>0, 'EnableQMarkup' => 0, 'contents' => XL('Contents'), 'hide' => XL('hide'), 'show' => XL('show'), )); if ($action!='browse') $PmTOC['Enable'] = 0; Markup("PmTOC", 'directives', '/^\\(:[#*]?(?:toc|tdm).*?:\\)\\s*$/im', 'FmtPmTOC'); Markup("noPmTOC", 'directives', '/\\(:(no)(?:toc|tdm).*?:\\)/im', 'FmtPmTOC'); function FmtPmTOC($m) { if (@$m[1]) return Keep(''); return "<:block,1>".Keep("
"); } SDV($HTMLStylesFmt['PmTOC'], '.noPmTOC, .PmTOCdiv:empty {display:none;} .PmTOCdiv { display: inline-block; font-size: 13px; overflow: auto; max-height: 500px;} .PmTOCdiv a { text-decoration: none;} .back-arrow {font-size: .9em; text-decoration: none;} #PmTOCchk + label {cursor: pointer;} #PmTOCchk {display: none;} #PmTOCchk:not(:checked) + label > .pmtoc-show {display: none;} #PmTOCchk:checked + label > .pmtoc-hide {display: none;} #PmTOCchk:checked + label + div {display: none;}'); SDV($HTMLStylesFmt['PmSortable'], 'table.sortable th { cursor: pointer; } table.sortable th::after { color: transparent; content: "\00A0\025B8"; } table.sortable th:hover::after { color: inherit; content: "\00A0\025B8"; } table.sortable th.dir-u::after { color: inherit; content: "\00A0\025BE"; } table.sortable th.dir-d::after { color: inherit; content: "\00A0\025B4"; }');