Text_Wiki
[ class tree: Text_Wiki ] [ index: Text_Wiki ] [ all elements ]

Source for file Wiki.php

Documentation is available at Wiki.php

  1. <?php
  2.  
  3. /**
  4. * The baseline abstract parser class.
  5. */
  6.  
  7. require_once 'Text/Wiki/Parse.php';
  8.  
  9. /**
  10. * The baseline abstract render class.
  11. */
  12.  
  13. require_once 'Text/Wiki/Render.php';
  14.  
  15. /**
  16. * Parse structured wiki text and render into arbitrary formats such as XHTML.
  17. * This is the "master" class for handling the management and convenience
  18. * functions to transform Wiki-formatted text.
  19. * $Id: Wiki.php,v 1.24 2004/09/30 13:42:14 pmjones Exp $
  20. @author Paul M. Jones <pmjones@ciaweb.net>
  21. @package Text_Wiki
  22. @version 0.23.0
  23. *
  24. @license LGPL
  25. */
  26.  
  27. class Text_Wiki {
  28.     
  29.     /**
  30.     * 
  31.     * The default list of rules, in order, to apply to the source text.
  32.     * 
  33.     * @access public
  34.     * 
  35.     * @var array 
  36.     * 
  37.     */
  38.     
  39.     var $rules = array(
  40.         'Prefilter',
  41.         'Delimiter',
  42.         'Code',
  43.         'Function',
  44.         'Html',
  45.         'Raw',
  46.         'Include',
  47.         'Embed',
  48.         'Anchor',
  49.         'Heading',
  50.         'Toc',
  51.         'Horiz',
  52.         'Break',
  53.         'Blockquote',
  54.         'List',
  55.         'Deflist',
  56.         'Table',
  57.         'Image',
  58.         'Phplookup',
  59.         'Center',
  60.         'Newline',
  61.         'Paragraph',
  62.         'Url',
  63.         'Freelink',
  64.         'Interwiki',
  65.         'Wikilink',
  66.         'Colortext',
  67.         'Strong',
  68.         'Bold',
  69.         'Emphasis',
  70.         'Italic',
  71.         'Tt',
  72.         'Superscript',
  73.         'Revise',
  74.         'Tighten'
  75.     );
  76.     
  77.     
  78.     /**
  79.     * 
  80.     * The list of rules to not-apply to the source text.
  81.     * 
  82.     * @access public
  83.     * 
  84.     * @var array 
  85.     * 
  86.     */
  87.     
  88.     var $disable = array(
  89.         'Html',
  90.         'Include',
  91.         'Embed'
  92.     );
  93.     
  94.     
  95.     /**
  96.     * 
  97.     * Custom configuration for rules at the parsing stage.
  98.     *
  99.     * In this array, the key is the parsing rule name, and the value is
  100.     * an array of key-value configuration pairs corresponding to the $conf
  101.     * property in the target parsing rule.
  102.     * 
  103.     * For example:
  104.     * 
  105.     * <code>
  106.     * $parseConf = array(
  107.     *     'Include' => array(
  108.     *         'base' => '/path/to/scripts/'
  109.     *     )
  110.     * );
  111.     * </code>
  112.     * 
  113.     * Note that most default rules do not need any parsing configuration.
  114.     * 
  115.     * @access public
  116.     * 
  117.     * @var array 
  118.     * 
  119.     */
  120.     
  121.     var $parseConf = array();
  122.     
  123.     
  124.     /**
  125.     * 
  126.     * Custom configuration for rules at the rendering stage.
  127.     *
  128.     * Because rendering may be different for each target format, the
  129.     * first-level element in this array is always a format name (e.g.,
  130.     * 'Xhtml').
  131.     * 
  132.     * Within that first level element, the subsequent elements match the
  133.     * $parseConf format. That is, the sub-key is the rendering rule name,
  134.     * and the sub-value is an array of key-value configuration pairs
  135.     * corresponding to the $conf property in the target rendering rule.
  136.     * 
  137.     * @access public
  138.     * 
  139.     * @var array 
  140.     * 
  141.     */
  142.     
  143.     var $renderConf = array(
  144.         'Docbook' => array(),
  145.         'Latex' => array(),
  146.         'Pdf' => array(),
  147.         'Plain' => array(),
  148.         'Rtf' => array(),
  149.         'Xhtml' => array()
  150.     );
  151.     
  152.     
  153.     /**
  154.     * 
  155.     * Custom configuration for the output format itself.
  156.     *
  157.     * Even though Text_Wiki will render the tokens from parsed text,
  158.     * the format itself may require some configuration.  For example,
  159.     * RTF needs to know font names and sizes, PDF requires page layout
  160.     * information, and DocBook needs a section hierarchy.  This array
  161.     * matches the $conf property of the the format-level renderer
  162.     * (e.g., Text_Wiki_Render_Xhtml).
  163.     * 
  164.     * In this array, the key is the rendering format name, and the value is
  165.     * an array of key-value configuration pairs corresponding to the $conf
  166.     * property in the rendering format rule.
  167.     * 
  168.     * @access public
  169.     * 
  170.     * @var array 
  171.     * 
  172.     */
  173.     
  174.     var $formatConf = array(
  175.         'Docbook' => array(),
  176.         'Latex' => array(),
  177.         'Pdf' => array(),
  178.         'Plain' => array(),
  179.         'Rtf' => array(),
  180.         'Xhtml' => array()
  181.     );
  182.     
  183.     
  184.     /**
  185.     * 
  186.     * The delimiter for token numbers of parsed elements in source text.
  187.     * 
  188.     * @access public
  189.     * 
  190.     * @var string 
  191.     * 
  192.     */
  193.     
  194.     var $delim = "\xFF"
  195.     
  196.     
  197.     /**
  198.     * 
  199.     * The tokens generated by rules as the source text is parsed.
  200.     * 
  201.     * As Text_Wiki applies rule classes to the source text, it will
  202.     * replace portions of the text with a delimited token number.  This
  203.     * is the array of those tokens, representing the replaced text and
  204.     * any options set by the parser for that replaced text.
  205.     * 
  206.     * The tokens array is sequential; each element is itself a sequential
  207.     * array where element 0 is the name of the rule that generated the
  208.     * token, and element 1 is an associative array where the key is an
  209.     * option name and the value is an option value.
  210.     * 
  211.     * @access private
  212.     * 
  213.     * @var array 
  214.     * 
  215.     */
  216.     
  217.     var $tokens = array();
  218.     
  219.     
  220.     /**
  221.     * 
  222.     * The source text to which rules will be applied.
  223.     * 
  224.     * This text will be transformed in-place, which means that it will
  225.     * change as the rules are applied.
  226.     * 
  227.     * @access private
  228.     * 
  229.     * @var string 
  230.     * 
  231.     */
  232.     
  233.     var $source '';
  234.     
  235.     
  236.     /**
  237.     * 
  238.     * Array of rule parsers.
  239.     * 
  240.     * Text_Wiki creates one instance of every rule that is applied to
  241.     * the source text; this array holds those instances.  The array key
  242.     * is the rule name, and the array value is an instance of the rule
  243.     * class.
  244.     * 
  245.     * @access private
  246.     * 
  247.     * @var array 
  248.     * 
  249.     */
  250.     
  251.     var $parseObj = array();
  252.     
  253.     
  254.     /**
  255.     * 
  256.     * Array of rule renderers.
  257.     * 
  258.     * Text_Wiki creates one instance of every rule that is applied to
  259.     * the source text; this array holds those instances.  The array key
  260.     * is the rule name, and the array value is an instance of the rule
  261.     * class.
  262.     * 
  263.     * @access private
  264.     * 
  265.     * @var array 
  266.     * 
  267.     */
  268.     
  269.     var $renderObj = array();
  270.     
  271.     
  272.     /**
  273.     * 
  274.     * Array of format renderers.
  275.     * 
  276.     * @access private
  277.     * 
  278.     * @var array 
  279.     * 
  280.     */
  281.     
  282.     var $formatObj = array();
  283.     
  284.     
  285.     /**
  286.     * 
  287.     * Array of paths to search, in order, for parsing and rendering rules.
  288.     * 
  289.     * @access private
  290.     * 
  291.     * @var array 
  292.     * 
  293.     */
  294.     
  295.     var $path = array(
  296.         'parse' => array(),
  297.         'render' => array()
  298.     );
  299.     
  300.     
  301.     
  302.     /**
  303.     * 
  304.     * The directory separator character.
  305.     * 
  306.     * @access private
  307.     * 
  308.     * @var string 
  309.     * 
  310.     */
  311.     
  312.     var $_dirSep = DIRECTORY_SEPARATOR;
  313.     
  314.     
  315.     /**
  316.     * 
  317.     * Constructor.
  318.     * 
  319.     * @access public
  320.     * 
  321.     * @param array $rules The set of rules to load for this object.
  322.     *     
  323.     */
  324.     
  325.     function Text_Wiki($rules = null)
  326.     {
  327.         if (is_array($rules)) {
  328.             $this->rules = $rules;
  329.         }
  330.         
  331.         $this->addPath(
  332.             'parse',
  333.             $this->fixPath(dirname(__FILE__)) 'Wiki/Parse/'
  334.         );
  335.         
  336.         $this->addPath(
  337.             'render',
  338.             $this->fixPath(dirname(__FILE__)) 'Wiki/Render/'
  339.         );
  340.         
  341.     }
  342.     
  343.     
  344.     /**
  345.     * 
  346.     * Set parser configuration for a specific rule and key.
  347.     * 
  348.     * @access public
  349.     * 
  350.     * @param string $rule The parse rule to set config for.
  351.     * 
  352.     * @param array|string$arg1 The full config array to use for the
  353.     *  parse rule, or a conf key in that array.
  354.     * 
  355.     * @param string $arg2 The config value for the key.
  356.     * 
  357.     * @return void 
  358.     *
  359.     */
  360.     
  361.     function setParseConf($rule$arg1$arg2 = null)
  362.     {
  363.         $rule ucwords(strtolower($rule));
  364.         
  365.         if (isset($this->parseConf[$rule])) {
  366.             $this->parseConf[$rule= array();
  367.         }
  368.         
  369.         // if first arg is an array, use it as the entire
  370.         // conf array for the rule.  otherwise, treat arg1
  371.         // as a key and arg2 as a value for the rule conf.
  372.         if (is_array($arg1)) {
  373.             $this->parseConf[$rule$arg1;
  374.         else {
  375.             $this->parseConf[$rule][$arg1$arg2;
  376.         }
  377.     }
  378.     
  379.     
  380.     /**
  381.     * 
  382.     * Get parser configuration for a specific rule and key.
  383.     * 
  384.     * @access public
  385.     * 
  386.     * @param string $rule The parse rule to get config for.
  387.     * 
  388.     * @param string $key A key in the conf array; if null,
  389.     *  returns the entire conf array.
  390.     * 
  391.     * @return mixed The whole conf array if no key is specified,
  392.     *  or the specific conf key value.
  393.     *
  394.     */
  395.     
  396.     function getParseConf($rule$key = null)
  397.     {
  398.         $rule ucwords(strtolower($rule));
  399.         
  400.         // the rule does not exist
  401.         if (isset($this->parseConf[$rule])) {
  402.             return null;
  403.         }
  404.         
  405.         // no key requested, return the whole array
  406.         if (is_null($key)) {
  407.             return $this->parseConf[$rule];
  408.         }
  409.         
  410.         // does the requested key exist?
  411.         if (isset($this->parseConf[$rule][$key])) {
  412.             // yes, return that value
  413.             return $this->parseConf[$rule][$key];
  414.         else {
  415.             // no
  416.             return null;
  417.         }
  418.     }
  419.     
  420.     
  421.     /**
  422.     * 
  423.     * Set renderer configuration for a specific format, rule, and key.
  424.     * 
  425.     * @access public
  426.     * 
  427.     * @param string $format The render format to set config for.
  428.     * 
  429.     * @param string $rule The render rule to set config for in the format.
  430.     * 
  431.     * @param array|string$arg1 The config array, or the config key
  432.     *  within the render rule.
  433.     * 
  434.     * @param string $arg2 The config value for the key.
  435.     * 
  436.     * @return void 
  437.     *
  438.     */
  439.     
  440.     function setRenderConf($format$rule$arg1$arg2 = null)
  441.     {
  442.         $format ucwords(strtolower($format));
  443.         $rule ucwords(strtolower($rule));
  444.         
  445.         if (isset($this->renderConf[$format])) {
  446.             $this->renderConf[$format= array();
  447.         }
  448.         
  449.         if (isset($this->renderConf[$format][$rule])) {
  450.             $this->renderConf[$format][$rule= array();
  451.         }
  452.         
  453.         // if first arg is an array, use it as the entire
  454.         // conf array for the render rule.  otherwise, treat arg1
  455.         // as a key and arg2 as a value for the render rule conf.
  456.         if (is_array($arg1)) {
  457.             $this->renderConf[$format][$rule$arg1;
  458.         else {
  459.             $this->renderConf[$format][$rule][$arg1$arg2;
  460.         }
  461.     }
  462.     
  463.     
  464.     /**
  465.     * 
  466.     * Get renderer configuration for a specific format, rule, and key.
  467.     * 
  468.     * @access public
  469.     * 
  470.     * @param string $format The render format to get config for.
  471.     * 
  472.     * @param string $rule The render format rule to get config for.
  473.     * 
  474.     * @param string $key A key in the conf array; if null,
  475.     *  returns the entire conf array.
  476.     * 
  477.     * @return mixed The whole conf array if no key is specified,
  478.     *  or the specific conf key value.
  479.     *
  480.     */
  481.     
  482.     function getRenderConf($format$rule$key = null)
  483.     {
  484.         $format ucwords(strtolower($format));
  485.         $rule ucwords(strtolower($rule));
  486.         
  487.         if (isset($this->renderConf[$format]||
  488.             isset($this->renderConf[$format][$rule])) {
  489.             return null;
  490.         }
  491.         
  492.         // no key requested, return the whole array
  493.         if (is_null($key)) {
  494.             return $this->renderConf[$format][$rule];
  495.         }
  496.         
  497.         // does the requested key exist?
  498.         if (isset($this->renderConf[$format][$rule][$key])) {
  499.             // yes, return that value
  500.             return $this->renderConf[$format][$rule][$key];
  501.         else {
  502.             // no
  503.             return null;
  504.         }
  505.         
  506.     }
  507.     
  508.     /**
  509.     * 
  510.     * Set format configuration for a specific rule and key.
  511.     * 
  512.     * @access public
  513.     * 
  514.     * @param string $format The format to set config for.
  515.     * 
  516.     * @param string $key The config key within the format.
  517.     * 
  518.     * @param string $val The config value for the key.
  519.     * 
  520.     * @return void 
  521.     *
  522.     */
  523.     
  524.     function setFormatConf($format$arg1$arg2 = null)
  525.     {
  526.         if (is_array($this->formatConf[$format])) {
  527.             $this->formatConf[$format= array();
  528.         }
  529.         
  530.         // if first arg is an array, use it as the entire
  531.         // conf array for the format.  otherwise, treat arg1
  532.         // as a key and arg2 as a value for the format conf.
  533.         if (is_array($arg1)) {
  534.             $this->formatConf[$format$arg1;
  535.         else {
  536.             $this->formatConf[$format][$arg1$arg2;
  537.         }
  538.     }
  539.     
  540.     
  541.     
  542.     /**
  543.     * 
  544.     * Get configuration for a specific format and key.
  545.     * 
  546.     * @access public
  547.     * 
  548.     * @param string $format The format to get config for.
  549.     * 
  550.     * @param mixed $key A key in the conf array; if null,
  551.     *  returns the entire conf array.
  552.     * 
  553.     * @return mixed The whole conf array if no key is specified,
  554.     *  or the specific conf key value.
  555.     *
  556.     */
  557.     
  558.     function getFormatConf($format$key = null)
  559.     {
  560.         // the format does not exist
  561.         if (isset($this->formatConf[$format])) {
  562.             return null;
  563.         }
  564.         
  565.         // no key requested, return the whole array
  566.         if (is_null($key)) {
  567.             return $this->formatConf[$format];
  568.         }
  569.         
  570.         // does the requested key exist?
  571.         if (isset($this->formatConf[$format][$key])) {
  572.             // yes, return that value
  573.             return $this->formatConf[$format][$key];
  574.         else {
  575.             // no
  576.             return null;
  577.         }
  578.     }
  579.     
  580.     
  581.     /**
  582.     * 
  583.     * Inserts a rule into to the rule set.
  584.     * 
  585.     * @access public
  586.     * 
  587.     * @param string $name The name of the rule.  Should be different from
  588.     *  all other keys in the rule set.
  589.     * 
  590.     * @param string $tgt The rule after which to insert this new rule.  By
  591.     *  default (null) the rule is inserted at the end; if set to '', inserts
  592.     *  at the beginning.
  593.     * 
  594.     * @return void 
  595.     * 
  596.     */
  597.     
  598.     function insertRule($name$tgt = null)
  599.     {
  600.         $name ucwords(strtolower($name));
  601.         if (is_null($tgt)) {
  602.             $tgt ucwords(strtolower($tgt));
  603.         }
  604.         
  605.         // does the rule name to be inserted already exist?
  606.         if (in_array($name$this->rules)) {
  607.             // yes, return
  608.             return null;
  609.         }
  610.         
  611.         // the target name is not null, and not '', but does not exist
  612.         // in the list of rules. this means we're trying to insert after
  613.         // a target key, but the target key isn't there.
  614.         if (is_null($tgt&& $tgt != '' &&
  615.             in_array($tgt$this->rules)) {
  616.             return false;
  617.         }
  618.         
  619.         // if $tgt is null, insert at the end.  We know this is at the
  620.         // end (instead of resetting an existing rule) becuase we exited
  621.         // at the top of this method if the rule was already in place.
  622.         if (is_null($tgt)) {
  623.             $this->rules[$name;
  624.             return true;
  625.         }
  626.         
  627.         // save a copy of the current rules, then reset the rule set
  628.         // so we can insert in the proper place later.
  629.         // where to insert the rule?
  630.         if ($tgt == ''{
  631.             // insert at the beginning
  632.             array_unshift($this->rules$name);
  633.             return true;
  634.         }
  635.         
  636.         // insert after the named rule
  637.         $tmp $this->rules;
  638.         $this->rules = array();
  639.         
  640.         foreach ($tmp as $val{
  641.             $this->rules[$val;
  642.             if ($val == $tgt{
  643.                 $this->rules[$name;
  644.             }
  645.         }
  646.         
  647.         return true;
  648.         
  649.     }
  650.     
  651.     
  652.     /**
  653.     * 
  654.     * Delete (remove or unset) a rule from the $rules property.
  655.     * 
  656.     * @access public
  657.     * 
  658.     * @param string $rule The name of the rule to remove.
  659.     * 
  660.     * @return void 
  661.     *     
  662.     */
  663.     
  664.     function deleteRule($name)
  665.     {
  666.         $name ucwords(strtolower($name));
  667.         $key array_search($name$this->rules);
  668.         if ($key !== false{
  669.             unset($this->rules[$key]);
  670.         }
  671.     }
  672.     
  673.     
  674.     /**
  675.     * 
  676.     * Change from one rule to another in-place.
  677.     * 
  678.     * @access public
  679.     * 
  680.     * @param string $old The name of the rule to change from.
  681.     * 
  682.     * @param string $new The name of the rule to change to.
  683.     * 
  684.     * @return void 
  685.     *     
  686.     */
  687.     
  688.     function changeRule($old$new)
  689.     {
  690.         $old ucwords(strtolower($old));
  691.         $new ucwords(strtolower($new));
  692.         $key array_search($old$this->rules);
  693.         if ($key !== false{
  694.             $this->rules[$old$new;
  695.         }
  696.     }
  697.     
  698.     
  699.     /**
  700.     * 
  701.     * Enables a rule so that it is applied when parsing.
  702.     * 
  703.     * @access public
  704.     * 
  705.     * @param string $rule The name of the rule to enable.
  706.     * 
  707.     * @return void 
  708.     *     
  709.     */
  710.     
  711.     function enableRule($name)
  712.     {
  713.         $name ucwords(strtolower($name));
  714.         $key array_search($name$this->disable);
  715.         if ($key !== false{
  716.             unset($this->disable[$key]);
  717.         }
  718.     }
  719.     
  720.     
  721.     /**
  722.     * 
  723.     * Disables a rule so that it is not applied when parsing.
  724.     * 
  725.     * @access public
  726.     * 
  727.     * @param string $rule The name of the rule to disable.
  728.     * 
  729.     * @return void 
  730.     *     
  731.     */
  732.     
  733.     function disableRule($name)
  734.     {
  735.         $name ucwords(strtolower($name));
  736.         $key array_search($name$this->disable);
  737.         if ($key === false{
  738.             $this->disable[$name;
  739.         }
  740.     }
  741.     
  742.     
  743.     /**
  744.     * 
  745.     * Parses and renders the text passed to it, and returns the results.
  746.     * 
  747.     * First, the method parses the source text, applying rules to the
  748.     * text as it goes.  These rules will modify the source text
  749.     * in-place, replacing some text with delimited tokens (and
  750.     * populating the $this->tokens array as it goes).
  751.     * 
  752.     * Next, the method renders the in-place tokens into the requested
  753.     * output format.
  754.     * 
  755.     * Finally, the method returns the transformed text.  Note that the
  756.     * source text is transformed in place; once it is transformed, it is
  757.     * no longer the same as the original source text.
  758.     * 
  759.     * @access public
  760.     * 
  761.     * @param string $text The source text to which wiki rules should be
  762.     *  applied, both for parsing and for rendering.
  763.     * 
  764.     * @param string $format The target output format, typically 'xhtml'.
  765.     *   If a rule does not support a given format, the output from that
  766.     *  rule is rule-specific.
  767.     * 
  768.     * @return string The transformed wiki text.
  769.     * 
  770.     */
  771.     
  772.     function transform($text$format 'Xhtml')
  773.     {
  774.         $this->parse($text);
  775.         return $this->render($format);
  776.     }
  777.     
  778.     
  779.     /**
  780.     * 
  781.     * Sets the $_source text property, then parses it in place and
  782.     * retains tokens in the $_tokens array property.
  783.     * 
  784.     * @access public
  785.     * 
  786.     * @param string $text The source text to which wiki rules should be
  787.     *  applied, both for parsing and for rendering.
  788.     * 
  789.     * @return void 
  790.     * 
  791.     */
  792.     
  793.     function parse($text)
  794.     {
  795.         // set the object property for the source text
  796.         $this->source $text;
  797.         
  798.         // reset the tokens.
  799.         $this->tokens = array();
  800.         
  801.         // apply the parse() method of each requested rule to the source
  802.         // text.
  803.         foreach ($this->rules as $name{
  804.             // do not parse the rules listed in $disable
  805.             if (in_array($name$this->disable)) {
  806.                 
  807.                 // load the parsing object
  808.                 $this->loadParseObj($name);
  809.                 
  810.                 // load may have failed; only parse if
  811.                 // an object is in the array now
  812.                 if (is_object($this->parseObj[$name])) {
  813.                     $this->parseObj[$name]->parse();
  814.                 }
  815.             }
  816.         }
  817.     }
  818.     
  819.     
  820.     /**
  821.     * 
  822.     * Renders tokens back into the source text, based on the requested format.
  823.     * 
  824.     * @access public
  825.     * 
  826.     * @param string $format The target output format, typically 'xhtml'.
  827.     *  If a rule does not support a given format, the output from that
  828.     *  rule is rule-specific.
  829.     * 
  830.     * @return string The transformed wiki text.
  831.     * 
  832.     */
  833.     
  834.     function render($format 'Xhtml')
  835.     {
  836.         // the rendering method we're going to use from each rule
  837.         $format ucwords(strtolower($format));
  838.         
  839.         // the eventual output text
  840.         $output '';
  841.         
  842.         // when passing through the parsed source text, keep track of when
  843.         // we are in a delimited section
  844.         $in_delim = false;
  845.         
  846.         // when in a delimited section, capture the token key number
  847.         $key '';
  848.         
  849.         // load the format object
  850.         $this->loadFormatObj($format);
  851.         
  852.         // pre-rendering activity
  853.         if (is_object($this->formatObj[$format])) {
  854.             $output .= $this->formatObj[$format]->pre();
  855.         }
  856.         
  857.         // load the render objects
  858.         foreach (array_keys($this->parseObjas $rule{
  859.             $this->loadRenderObj($format$rule);
  860.         }
  861.         
  862.         // pass through the parsed source text character by character
  863.         $k strlen($this->source);
  864.         for ($i = 0; $i $k$i++{
  865.             
  866.             // the current character
  867.             $char $this->source{$i};
  868.             
  869.             // are alredy in a delimited section?
  870.             if ($in_delim{
  871.             
  872.                 // yes; are we ending the section?
  873.                 if ($char == $this->delim{
  874.                     
  875.                     // yes, get the replacement text for the delimited
  876.                     // token number and unset the flag.
  877.                     $key = (int)$key;
  878.                     $rule $this->tokens[$key][0];
  879.                     $opts $this->tokens[$key][1];
  880.                     $output .= $this->renderObj[$rule]->token($opts);
  881.                     $in_delim = false;
  882.                     
  883.                 else {
  884.                 
  885.                     // no, add to the dlimited token key number
  886.                     $key .= $char;
  887.                     
  888.                 }
  889.                 
  890.             else {
  891.                 
  892.                 // not currently in a delimited section.
  893.                 // are we starting into a delimited section?
  894.                 if ($char == $this->delim{
  895.                     // yes, reset the previous key and
  896.                     // set the flag.
  897.                     $key '';
  898.                     $in_delim = true;
  899.                 else {
  900.                     // no, add to the output as-is
  901.                     $output .= $char;
  902.                 }
  903.             }
  904.         }
  905.         
  906.         // post-rendering activity
  907.         if (is_object($this->formatObj[$format])) {
  908.             $output .= $this->formatObj[$format]->post();
  909.         }
  910.         
  911.         // return the rendered source text.
  912.         return $output;
  913.     }
  914.     
  915.     
  916.     /**
  917.     * 
  918.     * Returns the parsed source text with delimited token placeholders.
  919.     * 
  920.     * @access public
  921.     * 
  922.     * @return string The parsed source text.
  923.     * 
  924.     */
  925.     
  926.     function getSource()
  927.     {
  928.         return $this->source;
  929.     }
  930.     
  931.     
  932.     /**
  933.     * 
  934.     * Returns tokens that have been parsed out of the source text.
  935.     * 
  936.     * @access public
  937.     * 
  938.     * @param array $rules If an array of rule names is passed, only return
  939.     *  tokens matching these rule names.  If no array is passed, return all
  940.     *  tokens.
  941.     * 
  942.     * @return array An array of tokens.
  943.     * 
  944.     */
  945.     
  946.     function getTokens($rules = null)
  947.     {
  948.         if (is_null($rules)) {
  949.             return $this->tokens;
  950.         else {
  951.             settype($rules'array');
  952.             $result = array();
  953.             foreach ($this->tokens as $key => $val{
  954.                 if (in_array($val[0]$rules)) {
  955.                     $result[$val;
  956.                 }
  957.             }
  958.             return $result;
  959.         }
  960.     }
  961.     
  962.     
  963.     /**
  964.     * 
  965.     * Add a token to the Text_Wiki tokens array, and return a delimited
  966.     * token number.
  967.     * 
  968.     * @access public
  969.     * 
  970.     * @param array $options An associative array of options for the new
  971.     *  token array element.  The keys and values are specific to the
  972.     *  rule, and may or may not be common to other rule options.  Typical
  973.     *  options keys are 'text' and 'type' but may include others.
  974.     * 
  975.     * @param boolean $id_only If true, return only the token number, not
  976.     *  a delimited token string.
  977.     * 
  978.     * @return string|intBy default, return the number of the
  979.     *  newly-created token array element with a delimiter prefix and
  980.     *  suffix; however, if $id_only is set to true, return only the token
  981.     *  number (no delimiters).
  982.     * 
  983.     */
  984.     
  985.     function addToken($rule$options = array()$id_only = false)
  986.     {
  987.         // increment the token ID number.  note that if you parse
  988.         // multiple times with the same Text_Wiki object, the ID number
  989.         // will not reset to zero.
  990.         static $id;
  991.         if (isset($id)) {
  992.             $id = 0;
  993.         else {
  994.             $id ++;
  995.         }
  996.         
  997.         // force the options to be an array
  998.         settype($options'array');
  999.         
  1000.         // add the token
  1001.         $this->tokens[$id= array(
  1002.             0 => $rule,
  1003.             1 => $options
  1004.         );
  1005.         
  1006.         // return a value
  1007.         if ($id_only{
  1008.             // return the last token number
  1009.             return $id;
  1010.         else {
  1011.             // return the token number with delimiters
  1012.             return $this->delim . $id $this->delim;
  1013.         }
  1014.     }
  1015.     
  1016.     
  1017.     /**
  1018.     * 
  1019.     * Set or re-set a token with specific information, overwriting any
  1020.     * previous rule name and rule options.
  1021.     * 
  1022.     * @access public
  1023.     * 
  1024.     * @param int $id The token number to reset.
  1025.     * 
  1026.     * @param int $rule The rule name to use.
  1027.     * 
  1028.     * @param array $options An associative array of options for the
  1029.     *  token array element.  The keys and values are specific to the
  1030.     *  rule, and may or may not be common to other rule options.  Typical
  1031.     *  options keys are 'text' and 'type' but may include others.
  1032.     * 
  1033.     * @return void 
  1034.     * 
  1035.     */
  1036.     
  1037.     function setToken($id$rule$options = array())
  1038.     {
  1039.         // reset the token
  1040.         $this->tokens[$id= array(
  1041.             0 => $rule,
  1042.             1 => $options
  1043.         );
  1044.     }
  1045.     
  1046.     
  1047.     /**
  1048.     * 
  1049.     * Load a rule parser class file.
  1050.     * 
  1051.     * @access public
  1052.     * 
  1053.     * @return bool True if loaded, false if not.
  1054.     * 
  1055.     */
  1056.     
  1057.     function loadParseObj($rule)
  1058.     {
  1059.         $rule ucwords(strtolower($rule));
  1060.         $file $rule '.php';
  1061.         $class = "Text_Wiki_Parse_$rule";
  1062.         
  1063.         if (class_exists($class)) {
  1064.             $loc $this->findFile('parse'$file);
  1065.             if ($loc{
  1066.                 // found the class
  1067.                 include_once $loc;
  1068.             else {
  1069.                 // can't find the class
  1070.                 $this->parseObj[$rule= null;
  1071.                 return false;
  1072.             }
  1073.         }
  1074.         
  1075.         $this->parseObj[$rule=new $class($this);
  1076.  
  1077.     }
  1078.     
  1079.     
  1080.     /**
  1081.     * 
  1082.     * Load a rule-render class file.
  1083.     * 
  1084.     * @access public
  1085.     * 
  1086.     * @return bool True if loaded, false if not.
  1087.     * 
  1088.     */
  1089.     
  1090.     function loadRenderObj($format$rule)
  1091.     {
  1092.         $format ucwords(strtolower($format));
  1093.         $rule ucwords(strtolower($rule));
  1094.         $file = "$format/$rule.php";
  1095.         $class = "Text_Wiki_Render_$format" . "_$rule";
  1096.         
  1097.         if (class_exists($class)) {
  1098.             // load the class
  1099.             $loc $this->findFile('render'$file);
  1100.             if ($loc{
  1101.                 // found the class
  1102.                 include_once $loc;
  1103.             else {
  1104.                 // can't find the class
  1105.                 return false;
  1106.             }
  1107.         }
  1108.         
  1109.         $this->renderObj[$rule=new $class($this);
  1110.     }
  1111.     
  1112.     
  1113.     /**
  1114.     * 
  1115.     * Load a format-render class file.
  1116.     * 
  1117.     * @access public
  1118.     * 
  1119.     * @return bool True if loaded, false if not.
  1120.     * 
  1121.     */
  1122.     
  1123.     function loadFormatObj($format)
  1124.     {
  1125.         $format ucwords(strtolower($format));
  1126.         $file $format '.php';
  1127.         $class = "Text_Wiki_Render_$format";
  1128.         
  1129.         if (class_exists($class)) {
  1130.             $loc $this->findFile('render'$file);
  1131.             if ($loc{
  1132.                 // found the class
  1133.                 include_once $loc;
  1134.             else {
  1135.                 // can't find the class
  1136.                 return false;
  1137.             }
  1138.         }
  1139.         
  1140.         $this->formatObj[$format=new $class($this);
  1141.     }
  1142.     
  1143.     
  1144.     /**
  1145.     * 
  1146.     * Add a path to a path array.
  1147.     * 
  1148.     * @access public
  1149.     * 
  1150.     * @param string $type The path-type to add (parse or render).
  1151.     * 
  1152.     * @param string $dir The directory to add to the path-type.
  1153.     * 
  1154.     * @return void 
  1155.     * 
  1156.     */
  1157.     
  1158.     function addPath($type$dir)
  1159.     {
  1160.         $dir $this->fixPath($dir);
  1161.         if (isset($this->path[$type])) {
  1162.             $this->path[$type= array($dir);
  1163.         else {
  1164.             array_unshift($this->path[$type]$dir);
  1165.         }
  1166.     }
  1167.     
  1168.     
  1169.     /**
  1170.     * 
  1171.     * Get the current path array for a path-type.
  1172.     * 
  1173.     * @access public
  1174.     * 
  1175.     * @param string $type The path-type to look up (plugin, filter, or
  1176.     *  template).  If not set, returns all path types.
  1177.     * 
  1178.     * @return array The array of paths for the requested type.
  1179.     * 
  1180.     */
  1181.     
  1182.     function getPath($type = null)
  1183.     {
  1184.         if (is_null($type)) {
  1185.             return $this->path;
  1186.         elseif (isset($this->path[$type])) {
  1187.             return array();
  1188.         else {
  1189.             return $this->path[$type];
  1190.         }
  1191.     }
  1192.     
  1193.     
  1194.     /**
  1195.     * 
  1196.     * Searches a series of paths for a given file.
  1197.     * 
  1198.     * @param array $type The type of paths to search (template, plugin,
  1199.     *  or filter).
  1200.     * 
  1201.     * @param string $file The file name to look for.
  1202.     * 
  1203.     * @return string|boolThe full path and file name for the target file,
  1204.     *  or boolean false if the file is not found in any of the paths.
  1205.     *
  1206.     */
  1207.     
  1208.     function findFile($type$file)
  1209.     {
  1210.         // get the set of paths
  1211.         $set $this->getPath($type);
  1212.         
  1213.         // start looping through them
  1214.         foreach ($set as $path{
  1215.             $fullname $path $file;
  1216.             if (file_exists($fullname&& is_readable($fullname)) {
  1217.                 return $fullname;
  1218.             }
  1219.         }
  1220.         
  1221.         // could not find the file in the set of paths
  1222.         return false;
  1223.     }
  1224.     
  1225.     
  1226.     /**
  1227.     * 
  1228.     * Append a trailing '/' to paths, unless the path is empty.
  1229.     * 
  1230.     * @access private
  1231.     * 
  1232.     * @param string $path The file path to fix
  1233.     * 
  1234.     * @return string The fixed file path
  1235.     * 
  1236.     */
  1237.     
  1238.     function fixPath($path)
  1239.     {
  1240.         $len strlen($this->_dirSep);
  1241.         
  1242.         if (empty($path&&
  1243.             substr($path-1 * $len$len!= $this->_dirSep)    {
  1244.             return $path $this->_dirSep;
  1245.         else {
  1246.             return $path;
  1247.         }
  1248.     }
  1249. }
  1250.  
  1251. ?>

Documentation generated on Mon, 11 Mar 2019 13:56:12 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.