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

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