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

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