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.8 2004/06/06 15:55:00 pmjones Exp $
  20. @author Paul M. Jones <pmjones@ciaweb.net>
  21. @package Text_Wiki
  22. @version 0.19 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($name$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.         $tmp $this->rules;
  627.         $this->rules = array();
  628.         
  629.         // where to insert the rule?
  630.         if ($tgt == ''{
  631.             // insert at the beginning
  632.             $this->rules[$name;
  633.             foreach ($tmp as $key => $val{
  634.                 $this->rules[$key$val;
  635.             }
  636.             return true;
  637.         else {
  638.             // insert after the named rule
  639.             foreach ($tmp as $key => $val{
  640.                 $this->rules[$val;
  641.                 if ($key == $tgt{
  642.                     $this->rules[$name;
  643.                 }
  644.             }
  645.         }
  646.         return true;
  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.                 $this->parseObj[$rule=new $class($this);
  1067.             else {
  1068.                 // can't find the class
  1069.                 $this->parseObj[$rule= null;
  1070.                 return false;
  1071.             }
  1072.         }
  1073.     }
  1074.     
  1075.     
  1076.     /**
  1077.     * 
  1078.     * Load a rule-render class file.
  1079.     * 
  1080.     * @access public
  1081.     * 
  1082.     * @return bool True if loaded, false if not.
  1083.     * 
  1084.     */
  1085.     
  1086.     function loadRenderObj($format$rule)
  1087.     {
  1088.         $format ucwords(strtolower($format));
  1089.         $rule ucwords(strtolower($rule));
  1090.         $file = "$format/$rule.php";
  1091.         $class = "Text_Wiki_Render_$format" . "_$rule";
  1092.         
  1093.         if (class_exists($class)) {
  1094.             // load the class
  1095.             $loc $this->findFile('render'$file);
  1096.             if ($loc{
  1097.                 // found the class
  1098.                 include_once $loc;
  1099.             else {
  1100.                 // can't find the class
  1101.                 return false;
  1102.             }
  1103.         }
  1104.         
  1105.         $this->renderObj[$rule=new $class($this);
  1106.     }
  1107.     
  1108.     
  1109.     /**
  1110.     * 
  1111.     * Load a format-render class file.
  1112.     * 
  1113.     * @access public
  1114.     * 
  1115.     * @return bool True if loaded, false if not.
  1116.     * 
  1117.     */
  1118.     
  1119.     function loadFormatObj($format)
  1120.     {
  1121.         $format ucwords(strtolower($format));
  1122.         $file $format '.php';
  1123.         $class = "Text_Wiki_Render_$format";
  1124.         
  1125.         if (class_exists($class)) {
  1126.             $loc $this->findFile('render'$file);
  1127.             if ($loc{
  1128.                 // found the class
  1129.                 include_once $loc;
  1130.             else {
  1131.                 // can't find the class
  1132.                 return false;
  1133.             }
  1134.         }
  1135.         
  1136.         $this->formatObj[$format=new $class($this);
  1137.     }
  1138.     
  1139.     
  1140.     /**
  1141.     * 
  1142.     * Add a path to a path array.
  1143.     * 
  1144.     * @access public
  1145.     * 
  1146.     * @param string $type The path-type to add (parse or render).
  1147.     * 
  1148.     * @param string $dir The directory to add to the path-type.
  1149.     * 
  1150.     * @return void 
  1151.     * 
  1152.     */
  1153.     
  1154.     function addPath($type$dir)
  1155.     {
  1156.         $dir $this->fixPath($dir);
  1157.         if (isset($this->path[$type])) {
  1158.             $this->path[$type= array($dir);
  1159.         else {
  1160.             array_unshift($this->path[$type]$dir);
  1161.         }
  1162.     }
  1163.     
  1164.     
  1165.     /**
  1166.     * 
  1167.     * Get the current path array for a path-type.
  1168.     * 
  1169.     * @access public
  1170.     * 
  1171.     * @param string $type The path-type to look up (plugin, filter, or
  1172.     *  template).  If not set, returns all path types.
  1173.     * 
  1174.     * @return array The array of paths for the requested type.
  1175.     * 
  1176.     */
  1177.     
  1178.     function getPath($type = null)
  1179.     {
  1180.         if (is_null($type)) {
  1181.             return $this->path;
  1182.         elseif (isset($this->path[$type])) {
  1183.             return array();
  1184.         else {
  1185.             return $this->path[$type];
  1186.         }
  1187.     }
  1188.     
  1189.     
  1190.     /**
  1191.     * 
  1192.     * Searches a series of paths for a given file.
  1193.     * 
  1194.     * @param array $type The type of paths to search (template, plugin,
  1195.     *  or filter).
  1196.     * 
  1197.     * @param string $file The file name to look for.
  1198.     * 
  1199.     * @return string|boolThe full path and file name for the target file,
  1200.     *  or boolean false if the file is not found in any of the paths.
  1201.     *
  1202.     */
  1203.     
  1204.     function findFile($type$file)
  1205.     {
  1206.         // get the set of paths
  1207.         $set $this->getPath($type);
  1208.         
  1209.         // start looping through them
  1210.         foreach ($set as $path{
  1211.             $fullname $path $file;
  1212.             if (file_exists($fullname&& is_readable($fullname)) {
  1213.                 return $fullname;
  1214.             }
  1215.         }
  1216.         
  1217.         // could not find the file in the set of paths
  1218.         return false;
  1219.     }
  1220.     
  1221.     
  1222.     /**
  1223.     * 
  1224.     * Append a trailing '/' to paths, unless the path is empty.
  1225.     * 
  1226.     * @access private
  1227.     * 
  1228.     * @param string $path The file path to fix
  1229.     * 
  1230.     * @return string The fixed file path
  1231.     * 
  1232.     */
  1233.     
  1234.     function fixPath($path)
  1235.     {
  1236.         $len strlen($this->_dirSep);
  1237.         
  1238.         if (empty($path&&
  1239.             substr($path-1 * $len$len!= $this->_dirSep)    {
  1240.             return $path $this->_dirSep;
  1241.         else {
  1242.             return $path;
  1243.         }
  1244.     }
  1245.     
  1246.     
  1247. }
  1248.  
  1249. ?>

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