[pmwiki-devel] WordCount Recipe.

Stirling Westrup sti at pooq.com
Tue Oct 31 03:53:24 CST 2006


I've just finished a word count recipe for NaNoWriMo. Its intended to
replace the existing countglyphs recipe. The major improvements are:

  1) It creates pagevars that support the {Group.Page$Words} syntax.
  2) It can be easily extended to count other entities than words or
     glyphs.
  3) It can save the generated counts as page attributes.

My big question right now is: did I do this right? It seems to work, but
I've never generated page attributes before, and it was far from clear
that I chose the best manner in which to do so. I'm also unsure if it
would be better to enable saving of attributes by default or not. I'm
not really sure of the tradeoffs. I don't /think/ it would be too much
of a burden to calculate a word and/or glyph count on every save, but
all my sites are tiny so I've no experience on what might be burdensome
on the larger sites.

Any advice, comments, or suggestions would be appreciated. The code is
short enough that I've just bodily included it below:


----Start of Recipe----

// Standard Recipe Information for PmWiki
$RecipeInfo['CountWords'] = array
  ( 'Version' => '20061030'
  , 'Author'  => 'Stirling Westrup'
  , 'Email'   => 'sti at pooq.com'
  );

// by default, all we count is words
SDV($WordCount['words'], 1);

// by default, we don't save as page attributes
SDV($WordCountSaveEnable, 0);

foreach($WordCount as $ent => $enabled)
  {
    if( $enabled )
      { $nam = ucfirst($ent);

        SDVA
          ( $WordCountEntity[$ent]
          , array
              ( 'var' => "\$$nam"
              , 'fnc' => "WordCount_$nam"
              , 'prp' => "{$ent}count"
              , 'sav' => true
              )
          );

        $dat = $WordCountEntity[$ent];
        $FmtPV[$dat['var']] = "WordCount(\$pn,'$ent')";
        if( $WordCountSaveEnable && $dat['sav'] )
          $SaveProperties[] = $dat['prp'];
      }
  }

if( $WordCountSaveEnable )
  array_unshift($EditFunctions, 'WordCountAttributes');

function WordCount_Words($t)
  { return count(preg_split('/\s+/', $t, -1, PREG_SPLIT_NO_EMPTY)); }

function WordCount_Glyphs($t)
  { return strlen(preg_replace('/\s+/', '', $t)); }

// Ensure the PCache holds the counts. If necessary, load the page
// given by $pagename (or use $page if provided). If $check is true,
// only define the counts that have 'sav' set true;
function WordCountPCache($pagename, &$page = NULL, $check = false)
  { global $WordCountEntity, $PCache;

    if(!@$PCache[$pagename]['=pagecounts'])
      { $pc = &$PCache[$pagename];

        $pc['=pagecounts'] = 1;
        if(!$page)
          $page = RetrieveAuthPage($pagename, 'read', false,
READPAGE_CURRENT);

        if($page)
          foreach( $WordCountEntity as $d )
            if( !$check || $d['sav'] )
              $pc["=p_{$d['prp']}"] = $d['fnc']($page['text']);
      }
  }

// Count the entities and return the results.
function WordCount($pagename,$ent)
  { global $WordCountEntity, $PCache;

    WordCountPCache($pagename);
    return $PCache[$pagename]["=p_{$WordCountEntity[$ent]['prp']}"];
  }

// Called during save to calculate the counts.
function WordCountAttributes($pagename,&$page,&$new)
  { global $EnablePost;

    if($EnablePost)
      WordCountPCache($pagename,$page,true);
  }


----End-of-Recipe----



More information about the pmwiki-devel mailing list