function test_depth() { $pagelist = new PluginSonotsPagelist($this->pages); $pagelist->gen_metas('depth'); $depths = $pagelist->get_metas('depth'); $truth = array(0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 4, 5 => 4); $this->assertTrue($depths, $truth); // do not use negative interval for depth $depth = PluginSonotsOption::parse_interval('2:3'); list($offset, $length) = $depth; list($min, $max) = PluginSonotsOption::conv_interval(array($offset, $length), array(1, PHP_INT_MAX)); $pagelist->grep_by('depth', 'ge', $min); $pagelist->grep_by('depth', 'le', $max); $pages = $pagelist->get_metas('page'); $truth = array(1 => 'test/a', 2 => 'test/a/aa'); $this->assertTrue($pages, $truth); // depth measures relname $pagelist = new PluginSonotsPagelist($this->pages); $prefix = 'test/a/'; $pagelist->grep_by('page', 'prefix', $prefix); $pagelist->gen_metas('relname', array(sonots::get_dirname($prefix))); $pagelist->gen_metas('depth'); $depths = $pagelist->get_metas('depth'); $truth = array(2 => 1, 3 => 2, 4 => 2); $this->assertTrue($depths, $truth); }
/** * Display Table of Contents * * @access static * @param string $page * @param array $options * @return string html */ function display_toc($page, $options) { $toc = new PluginSonotsToc($page, $options['cache']); if ($options['include']) { $toc->expand_includes(); } $headlines = $toc->get_headlines(); if ($options['fromhere']) { $fromhere = $toc->get_fromhere(); $offset = 0; $headline = reset($headlines); while (!($headline->page === $page && $headline->linenum > $fromhere)) { ++$offset; if (($headline = next($headlines)) === false) { break; } } $headlines = sonots::array_slice($headlines, $offset, null, true); } if (isset($options['filter'])) { sonots::grep_by($headlines, 'string', 'preg', '/' . str_replace('/', '\\/', $options['filter']) . '/'); } if (isset($options['except'])) { sonots::grep_by($headlines, 'string', 'preg', '/' . str_replace('/', '\\/', $options['except']) . '/', true); // inverse } if (is_array($options['depth'])) { // Do not use negative offsets list($min, $max) = PluginSonotsOption::conv_interval($options['depth'], array(1, PHP_INT_MAX)); sonots::grep_by($headlines, 'depth', 'ge', $min); sonots::grep_by($headlines, 'depth', 'le', $max); } if (is_array($options['num'])) { list($offset, $length) = $options['num']; $headlines = sonots::array_slice($headlines, $offset, $length, true); } if ($options['hierarchy']) { if ($options['include'] && count($toc->get_includes()) >= 1) { // depth of included page is 0, shift up sonots::map_members($headlines, 'depth', create_function('$x', 'return $x+1;')); } if ($options['compact']) { PluginSonotsToc::compact_depth($headlines); } } else { sonots::init_members($headlines, 'depth', 1); // flatten (to all 1) } $html = PluginSonotsToc::display_toc($headlines, 'contentsx', $options['link']); return $html; }
/** * List pages * * @param array $pages * @param array $options * @param array $argoptions * @return string html */ function pagelist($pages, $options, $argoptions) { $pagelist = new PluginSonotsPagelist($pages); if ($options['non_list']) { $pattern = '/' . $GLOBALS['non_list'] . '/'; $pagelist->grep_by('page', 'preg', $pattern, true); // inverse } if (isset($options['filter']) && $options['filter'] !== '') { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['filter']) . '/'); } if (isset($options['except'])) { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['except']) . '/', true); // inverse } if (isset($options['newpage'])) { switch ($options['newpage']) { case 'on': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', true); break; case 'except': case 'off': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', false); break; default: break; } } if (is_array($options['info']) || $options['sort'] === 'date') { $pagelist->gen_metas('timestamp'); } if ($options['sort'] === 'popular') { $pagelist->gen_metas('popular', array($options['popular'])); } if ($options['sort'] === 'reading') { $pagelist->gen_metas('reading'); } if ($options['sort'] === 'title') { $pagelist->gen_metas('title'); } $pagelist->sort_by($options['sort'], $options['reverse']); $max = count($pagelist->metapages); // for next option if (is_array($options['num'])) { list($offset, $length) = $options['num']; $pagelist->slice($offset, $length); } //// display if (isset($options['include'])) { $pages = $pagelist->get_metas('page'); $include = new PluginIncludex(); // just want static var $includes = array(); foreach ($pages as $i => $page) { $includes[$i] = PluginIncludex::display_include($page, $options['include'], $include->syntax); } $html = implode("\n", $includes); } else { $pagelist->init_metas('depth', 1); $pagelist->gen_metas('link', array($options['linkstr'], $options['link'])); $links = $pagelist->get_metas('link'); $infos = array(); if (is_array($options['info'])) { $pagelist->gen_metas('info', array($options['info'])); $infos = $pagelist->get_metas('info'); } $tocs = array(); if (isset($options['contents'])) { $pages = $pagelist->get_metas('page'); foreach ($pages as $i => $page) { $toc_options = PluginContentsx::check_options($page, '', $options['contents']); $tocs[$i] = PluginContentsx::display_toc($page, $toc_options); } } $items = array(); foreach ($links as $i => $link) { $items[$i] = $links[$i]; if (isset($infos[$i])) { $items[$i] .= ' ' . $infos[$i]; } if (isset($tocs[$i])) { $items[$i] .= $tocs[$i]; } } $levels = $pagelist->get_metas('depth'); $html = sonots::display_list($items, $levels, $this->plugin); } if ($options['next'] && is_array($options['num'])) { $argoptions['tag'] = $options['tag']; unset($argoptions['num']); $argoptions = array_intersect_key($argoptions, $options); $argline = PluginSonotsOption::glue_uri_option_line($argoptions); $basehref = get_script_uri() . '?cmd=' . $this->plugin; $basehref .= empty($argline) ? '' : '&' . htmlspecialchars($argline); $current = PluginSonotsOption::conv_interval($options['num']); $html .= $pagelist->display_navi($current, array(1, $max), $basehref, $this->plugin); } return $html; }
/** * List pages * * @param array $pages * @param array $options * @param array $argoptions * @return string html */ function pagelist($pages, $options, $argoptions) { $pagelist = new PluginSonotsPagelist($pages); if (isset($options['prefix']) && $options['prefix'] !== '') { $pagelist->gen_metas('relname', array(sonots::get_dirname($options['prefix']))); } if ($options['non_list']) { $pattern = '/' . $GLOBALS['non_list'] . '/'; $pagelist->grep_by('page', 'preg', $pattern, true); // inverse } if (isset($options['filter']) && $options['filter'] !== '') { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['filter']) . '/'); } if (isset($options['except'])) { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['except']) . '/', true); // inverse } if (isset($options['newpage'])) { switch ($options['newpage']) { case 'on': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', true); break; case 'except': case 'off': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', false); break; default: break; } } if (isset($options['depth']) || $options['hierarchy'] || $options['tree']) { $pagelist->gen_metas('depth'); } if (isset($options['depth'])) { // do not use negative interval for depth list($min, $max) = PluginSonotsOption::conv_interval($options['depth'], array(1, PHP_INT_MAX)); $pagelist->grep_by('depth', 'ge', $min); $pagelist->grep_by('depth', 'le', $max); } switch ($options['tree']) { case 'leaf': $pagelist->gen_metas('leaf'); $pagelist->grep_by('leaf', 'eq', true); break; case 'dir': $pagelist->gen_metas('leaf'); $pagelist->grep_by('leaf', 'eq', false); break; default: break; } if (is_array($options['info']) || $options['sort'] === 'date') { $pagelist->gen_metas('timestamp'); } if ($options['sort'] === 'popular') { $pagelist->gen_metas('popular', array($options['popular'])); } if ($options['sort'] === 'reading') { $pagelist->gen_metas('reading'); } if ($options['sort'] === 'title') { $pagelist->gen_metas('title'); } $pagelist->sort_by($options['sort'], $options['reverse']); if (is_array($options['num'])) { list($offset, $length) = $options['num']; $pagelist->slice($offset, $length); } return $pagelist; }
/** * List pages * * @param array $pages * @param array $options * @param array $argoptions * @return string html */ function pagelist($pages, $options, $argoptions) { $pagelist = new PluginSonotsPagelist($pages); if ($options['non_list']) { $pattern = '/' . $GLOBALS['non_list'] . '/'; $pagelist->grep_by('page', 'preg', $pattern, true); // inverse } if (isset($options['filter']) && $options['filter'] !== '') { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['filter']) . '/'); } if (isset($options['except'])) { $pagelist->grep_by('relname', 'preg', '/' . str_replace('/', '\\/', $options['except']) . '/', true); // inverse } if (isset($options['newpage'])) { switch ($options['newpage']) { case 'on': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', true); break; case 'except': case 'off': $pagelist->gen_metas('newpage'); $pagelist->grep_by('newpage', 'eq', false); break; default: break; } } if (isset($options['depth']) || $options['tree']) { $pagelist->gen_metas('depth'); } if (isset($options['depth'])) { // do not use negative interval for depth list($min, $max) = PluginSonotsOption::conv_interval($options['depth'], array(1, PHP_INT_MAX)); $pagelist->grep_by('depth', 'ge', $min); $pagelist->grep_by('depth', 'le', $max); } switch ($options['tree']) { case 'leaf': $pagelist->gen_metas('leaf'); $pagelist->grep_by('leaf', 'eq', true); break; case 'dir': $pagelist->gen_metas('leaf'); $pagelist->grep_by('leaf', 'eq', false); break; default: break; } if (isset($options['popular'])) { $pagelist->gen_metas('popular', array($options['popular'])); } $pagelist->sort_by('popular', $options['reverse']); $max = count($pagelist->metapages); // for next option if (is_array($options['num'])) { list($offset, $length) = $options['num']; $pagelist->slice($offset, $length); } //// display $pagelist->gen_metas('linkstr', array($options['linkstr'])); $linkstrs = $pagelist->get_metas('linkstr'); $pages = $pagelist->get_metas('page'); $counts = $pagelist->get_metas('popular'); $links = $this->get_popular_links($pages, $linkstrs, $counts, $GLOBALS['var']['page']); if (empty($links)) { return '<p>#' . $this->plugin . '(): no counter information is available.</p>'; } $levels = array_map(create_function('', 'return 1;'), $links); $html = sonots::display_list($links, $levels, 'popularx'); //// display navi. $max is needed, $argoptions is need. if ($options['next'] && is_array($options['num'])) { $argoptions['popular'] = $options['popular']; unset($argoptions['num']); $argoptions = array_intersect_key($argoptions, $options); $argline = PluginSonotsOption::glue_uri_option_line($argoptions); $basehref = get_script_uri() . '?cmd=' . $this->plugin; $basehref .= empty($argline) ? '' : '&' . htmlspecialchars($argline); $current = PluginSonotsOption::conv_interval($options['num']); $html .= $pagelist->display_navi($current, array(1, $max), $basehref, $this->plugin); } return $html; }
function test_evaluate_options() { $conf_options = array('hierarchy' => array('bool', true), 'num' => array('interval', null), 'filter' => array('string', null), 'sort' => array('enum', 'name', array('name', 'reading', 'date'))); $options = array('Hoge/' => true, 'filter' => 'AAA'); list($options, $unknowns) = PluginSonotsOption::evaluate_options($options, $conf_options); $truth = array('hierarchy' => true, 'num' => null, 'filter' => 'AAA', 'sort' => 'name'); $this->assertIdentical($options, $truth); $truth = array('Hoge/' => true); $this->assertIdentical($unknowns, $truth); $conf_options = array('hierarchy' => array('bool', true), 'non_list' => array('bool', true), 'reverse' => array('bool', false), 'basename' => array('bool', false), 'sort' => array('enum', 'name', array('name', 'reading', 'date')), 'tree' => array('enum', false, array(false, 'leaf', 'dir')), 'depth' => array('interval', null), 'num' => array('interval', null), 'next' => array('bool', false), 'except' => array('string', null), 'filter' => array('string', null), 'prefix' => array('string', null), 'contents' => array('array', null), 'include' => array('array', null), 'info' => array('enumarray', null, array('date', 'new')), 'date' => array('bool', false), 'new' => array('bool', false), 'tag' => array('string', null), 'linkstr' => array('enum', 'relative', array('relative', 'absolute', 'basename', 'title', 'headline')), 'link' => array('enum', 'page', array('page', 'anchor', 'off')), 'newpage' => array('enum', null, array('on', 'except')), 'popular' => array('enum', null, array('total', 'today', 'yesterday', 'recent'))); $options = array('prefix' => 'Hoge/', 'num' => '1:5', 'contents' => array('num' => '1', 'firsthead')); list($result, $unknowns) = PluginSonotsOption::evaluate_options($options, $conf_options); $truth = array('hierarchy' => true, 'non_list' => true, 'reverse' => false, 'basename' => false, 'sort' => 'name', 'tree' => false, 'depth' => null, 'num' => array(0 => 0, 1 => 5), 'next' => false, 'except' => null, 'filter' => null, 'prefix' => 'Hoge/', 'contents' => array('num' => '1', 0 => 'firsthead'), 'include' => null, 'info' => null, 'date' => false, 'new' => false, 'tag' => null, 'linkstr' => 'relative', 'link' => 'page', 'newpage' => null, 'popular' => null); $this->assertEqual($result, $truth); $options[''] = TRUE; $options['cmd'] = 'read'; list($result, $unknowns) = PluginSonotsOption::evaluate_options($options, $conf_options); $this->assertEqual($result, $truth); $this->assertIdentical($unknowns, array('' => TRUE, 'cmd' => 'read')); $conf_options = array('num' => array('interval', null), 'except' => array('string', null), 'filter' => array('string', null), 'title' => array('enum', 'on', array('on', 'off', 'nolink', 'basename')), 'titlestr' => array('enum', 'title', array('name', 'pagename', 'absolute', 'relname', 'relative', 'basename', 'title', 'headline', 'off')), 'titlelink' => array('bool', true), 'section' => array('array', null), 'permalink' => array('string', null), 'firsthead' => array('bool', true), 'section' => array('options', null, array('num' => array('interval', null), 'depth' => array('interval', null), 'except' => array('string', null), 'filter' => array('string', null), 'inclsub' => array('bool', false)))); $options = array('num' => '1:5'); list($result, $unknowns) = PluginSonotsOption::evaluate_options($options, $conf_options); $truth = array('num' => array(0 => 0, 1 => 5), 'except' => null, 'filter' => null, 'title' => 'on', 'titlestr' => 'title', 'titlelink' => true, 'section' => null, 'permalink' => null, 'firsthead' => true); $this->assertIdentical($result, $truth); $options = array('num' => '1:5', 'section' => array('num' => '1')); list($result, $unknowns) = PluginSonotsOption::evaluate_options($options, $conf_options); $truth['section'] = array('num' => array(0 => 0, 1 => 1), 'depth' => null, 'except' => null, 'filter' => null, 'inclsub' => false); $this->assertIdentical($result, $truth); }
function get_sections($lines, $page, $options) { $toc = new PluginSonotsToc($page, $options['cache']); $headlines = $toc->get_headlines(); if (isset($options['filter'])) { sonots::grep_by($headlines, 'string', 'preg', '/' . str_replace('/', '\\/', $options['filter']) . '/'); } if (isset($options['except'])) { sonots::grep_by($headlines, 'string', 'preg', '/' . str_replace('/', '\\/', $options['except']) . '/', TRUE); // inverse } if (is_array($options['depth'])) { // Do not use negative offsets list($min, $max) = PluginSonotsOption::conv_interval($options['depth'], array(1, PHP_INT_MAX)); sonots::grep_by($headlines, 'depth', 'ge', $min); sonots::grep_by($headlines, 'depth', 'le', $max); } $outlines = array(); if (is_array($options['num'])) { array_unshift($headlines, new PluginSonotsHeadline($page, 0, 0, '', '')); list($offset, $length) = $options['num']; $headlines = sonots::array_slice($headlines, $offset, $length, true); } $linenums = sonots::get_members($headlines, 'linenum'); // extract from current head till next head - 1 $allheadlines = $toc->get_headlines(); $alllinenums = sonots::get_members($allheadlines, 'linenum'); if (!isset($alllinenums[0])) { array_unshift($alllinenums, 0); } // virtual head at the file head array_push($alllinenums, end(array_keys($lines)) + 1); // virtual head at the file tail $outlines = array(); $current = 0; foreach ($alllinenums as $next) { if (in_array($current, $linenums)) { if ($next == $current) { continue; } $outlines += sonots::array_slice($lines, $current, $next - $current, true); } $current = $next; } return $outlines; }
/** * Evaluate an option * * Lists of Supported Types) * - bool : boolean true or false * - string : string * - array : array * - enum : take only one element of possible values * - enumarray : take only elements in possible values * - number : number * - interval : interval string. See parse_interval for details * - options : options * * @access private * @static * @param mixed $val option value. * @param string $type option type * @param mixed $conf config. See evaluate_options. * @return array array(evaluated value, invalid value) * @uses parse_interval * @uses evaluate_options * @version $Id: v 1.7 2008-07-30 11:14:46 sonots $ * @since v 1.0 */ function evaluate_option($val, $type, $conf = null) { if (is_null($val)) { return array(null, null); } $retval = $unknown = null; switch ($type) { case 'bool': if ($val === true && is_bool($conf)) { $retval = $conf; break; } if ($val === false || $val === '0' || $val === 'off' || $val === 'false' || $val === 'FALSE') { $retval = false; } elseif ($val === true || $val === '' || $val === '1' || $val === 'on' || $val === 'true' || $val === 'TRUE') { $retval = true; } else { $unknown = $val; } break; case 'string': if ($val === true) { // no "=value" option is set to true at parse_option_line $retval = is_string($conf) ? $conf : null; break; } if (is_string($val)) { $retval = $val; } else { $unknown = $val; } break; case 'array': if ($val === true) { // no "=value" option is set to true at parse_option_line $retval = is_array($conf) ? $conf : null; break; } $retval = PluginSonotsOption::boolean_to_numeric((array) $val); break; case 'enum': if ($val === true) { $retval = is_array($conf) ? reset($conf) : null; break; } if (in_array($val, $conf)) { $retval = $val; } else { $unknown = $val; } break; case 'enumarray': // special array type if ($val === true) { $retval = is_array($conf) ? $conf : null; break; } $retval = array(); $unknown = array(); $val = PluginSonotsOption::boolean_to_numeric((array) $val); foreach ($val as $elem) { if (in_array($elem, $conf)) { $retval[] = $elem; } else { $unknown[] = $elem; } } if (empty($retval)) { $retval = null; } if (empty($unknown)) { $unknown = null; } break; case 'options': if ($val === true) { $val = array(); } list($retval, $unknown) = PluginSonotsOption::evaluate_options($val, $conf); if (empty($retval)) { $retval = null; } if (empty($unknown)) { $unknown = null; } break; case 'number': if ($val === true) { $retval = is_int($conf) || is_float($conf) ? $conf : null; break; } if (is_numeric($val)) { $retval = $val; } else { $unknown = $val; } break; case 'interval': // $conf is default2 or array(default2, start) if ($val === true) { $val = is_array($conf) ? $conf[0] : $conf; } $start = is_array($conf) ? $conf[1] : 1; $retval = PluginSonotsOption::parse_interval($val, $start); if (is_null($retval)) { $unknown = $val; } break; default: $unknown = $val; break; } return array($retval, $unknown); }