From: Neil Smith <neil.github@njae.me.uk> Date: Thu, 30 Jun 2011 15:43:26 +0000 (+0100) Subject: Final pre-release commit X-Git-Tag: v1.0.0~1 X-Git-Url: https://git.njae.me.uk/?p=porter2stemmer.git;a=commitdiff_plain;h=b8f204e08d491bd5185d3d9e94ed98366a359af7 Final pre-release commit --- diff --git a/README.md b/README.md new file mode 100644 index 0000000..2150b26 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +The Porter 2 stemmer +==================== +This is the Porter 2 stemming algorithm, as described at +http://snowball.tartarus.org/algorithms/english/stemmer.html +The original paper is: + +Porter, 1980, "An algorithm for suffix stripping", _Program_, Vol. 14, +no. 3, pp 130-137 + +Features of this implementation +=============================== +This stemmer is written in pure Ruby, making it easy to modify for language variants. +For instance, the original Porter stemmer only works for American English and does +not recognise British English's '-ise' as an alternate spelling of '-ize'. This +implementation has been extended to handle correctly British English. + +This stemmer also features a comprehensive test set of over 29,000 words, taken from the +[Porter 2 stemmer website](http://snowball.tartarus.org/algorithms/english/stemmer.html). + +Files +===== +Constants for the stemmer are in the Porter2 module. + +Procedures that implement the stemmer are added to the String class. + +The stemmer algorithm is implemented in the String#porter2_stem procedure. + +Internationalisation +==================== +There isn't much, as this is a stemmer that only works for English. + +The `gb_english` flag to the various procedures allows the stemmer to treat the British +English '-ise' the same as the American English '-ize'. + +Longest suffixes +================ +Several places in the algorithm require matching the longest suffix of a word. The +regexp engine in Ruby 1.9 seems to handle alterntives in regexps by finding the +alternative that matches at the first position in the string. As we're only talking +about suffixes, that first match is also the longest suffix. If the regexp engine changes, +this behaviour may change and break the stemmer. + +Usage +===== +Call the String#porter2_stem or String#stem methods on a string to return its stem + "consistency".stem # => "consist" + "knitting".stem # => "knit" + "articulated".stem # => "articul" + "nationalize".stem # => "nation" + "nationalise".stem # => "nationalis" + "nationalise".stem(true) # => "nation" + +Author +====== +The Porter 2 stemming algorithm was developed by +[Martin Porter](http://snowball.tartarus.org/algorithms/english/stemmer.html). +This implementation is by [Neil Smith](http://www.njae.me.uk). + diff --git a/pkg/porter2stemmer-1.0.0.gem b/pkg/porter2stemmer-1.0.0.gem new file mode 100644 index 0000000..71bdd5f Binary files /dev/null and b/pkg/porter2stemmer-1.0.0.gem differ diff --git a/rdoc/Porter2.html b/rdoc/Porter2.html new file mode 100644 index 0000000..3df1a20 --- /dev/null +++ b/rdoc/Porter2.html @@ -0,0 +1,249 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>Module: Porter2</title> + + <link rel="stylesheet" href="./rdoc.css" type="text/css" media="screen" /> + + <script src="./js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/darkfish.js" type="text/javascript" + charset="utf-8"></script> + +</head> +<body class="module"> + + <div id="metadata"> + <div id="home-metadata"> + <div id="home-section" class="section"> + <h3 class="section-header"> + <a href="./index.html">Home</a> + <a href="./index.html#classes">Classes</a> + <a href="./index.html#methods">Methods</a> + </h3> + </div> + </div> + + <div id="file-metadata"> + <div id="file-list-section" class="section"> + <h3 class="section-header">In Files</h3> + <div class="section-body"> + <ul> + + <li><a href="./lib/porter2stemmer/constants_rb.html?TB_iframe=true&height=550&width=785" + class="thickbox" title="lib/porter2stemmer/constants.rb">lib/porter2stemmer/constants.rb</a></li> + + </ul> + </div> + </div> + + + </div> + + <div id="class-metadata"> + + <!-- Parent Class --> + + + <!-- Namespace Contents --> + + + <!-- Method Quickref --> + + + <!-- Included Modules --> + + </div> + + <div id="project-metadata"> + + + <div id="fileindex-section" class="section project-section"> + <h3 class="section-header">Files</h3> + <ul> + + <li class="file"><a href="./README_rdoc.html">README.rdoc</a></li> + + </ul> + </div> + + + <div id="classindex-section" class="section project-section"> + <h3 class="section-header">Class Index + <span class="search-toggle"><img src="./images/find.png" + height="16" width="16" alt="[+]" + title="show/hide quicksearch" /></span></h3> + <form action="#" method="get" accept-charset="utf-8" class="initially-hidden"> + <fieldset> + <legend>Quicksearch</legend> + <input type="text" name="quicksearch" value="" + class="quicksearch-field" /> + </fieldset> + </form> + + <ul class="link-list"> + + <li><a href="./Porter2.html">Porter2</a></li> + + <li><a href="./String.html">String</a></li> + + </ul> + <div id="no-class-search-results" style="display: none;">No matching classes.</div> + </div> + + + </div> + </div> + + <div id="documentation"> + <h1 class="module">Porter2</h1> + + <div id="description"> + <p> +Constants for the Porter 2 stemmer +</p> + + </div> + + <!-- Constants --> + + <div id="constants-list" class="section"> + <h3 class="section-header">Constants</h3> + <dl> + + <dt><a name="C">C</a></dt> + + <dd class="description"><p> +A non-vowel +</p></dd> + + + <dt><a name="V">V</a></dt> + + <dd class="description"><p> +A vowel: a e i o u y +</p></dd> + + + <dt><a name="CW">CW</a></dt> + + <dd class="description"><p> +A non-vowel other than w, x, or Y +</p></dd> + + + <dt><a name="Double">Double</a></dt> + + <dd class="description"><p> +Doubles created when adding a suffix: these are undoubled when stemmed +</p></dd> + + + <dt><a name="Valid_LI">Valid_LI</a></dt> + + <dd class="description"><p> +A valid letter that can come before ‘li’ (or ‘ly’) +</p></dd> + + + <dt><a name="SHORT_SYLLABLE">SHORT_SYLLABLE</a></dt> + + <dd class="description"><p> +A specification for a short syllable. +</p> +<p> +A short syllable in a word is either: +</p> +<ol> +<li><p> +a vowel followed by a non-vowel other than w, x or Y and preceded by a +non-vowel, or +</p> +</li> +<li><p> +a vowel at the beginning of the word followed by a non-vowel. +</p> +</li> +</ol> +<p> +(The original document is silent on whether sequences of two or more +non-vowels make a syllable long. But as this specification is only used to +find sequences of non-vowel - vowel - non-vowel - end-of-word, this +ambiguity does not have an effect.) +</p></dd> + + + <dt><a name="STEP_2_MAPS">STEP_2_MAPS</a></dt> + + <dd class="description"><p> +Suffix transformations used in porter2_step2. (ogi, li endings dealt with +in procedure) +</p></dd> + + + <dt><a name="STEP_3_MAPS">STEP_3_MAPS</a></dt> + + <dd class="description"><p> +Suffix transformations used in porter2_step3. (ative ending dealt with in +procedure) +</p></dd> + + + <dt><a name="STEP_4_MAPS">STEP_4_MAPS</a></dt> + + <dd class="description"><p> +Suffix transformations used in porter2_step4. (ion ending dealt with in +procedure) +</p></dd> + + + <dt><a name="SPECIAL_CASES">SPECIAL_CASES</a></dt> + + <dd class="description"><p> +Special-case stemmings +</p></dd> + + + <dt><a name="STEP_1A_SPECIAL_CASES">STEP_1A_SPECIAL_CASES</a></dt> + + <dd class="description"><p> +Special case words to stop processing after step 1a. +</p></dd> + + + </dl> + </div> + + + <!-- Attributes --> + + + <!-- Methods --> + + + </div> + + + <div id="rdoc-debugging-section-dump" class="debugging-section"> + + <p>Disabled; run with --debug to generate this.</p> + + </div> + + <div id="validator-badges"> + <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p> + <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish + Rdoc Generator</a> 1.1.6</small>.</p> + </div> + +</body> +</html> + diff --git a/rdoc/README_rdoc.html b/rdoc/README_rdoc.html new file mode 100644 index 0000000..d7ac8d3 --- /dev/null +++ b/rdoc/README_rdoc.html @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>File: README.rdoc [porter2stemmer 1.0.0]</title> + + <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" /> + + <script src="./js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/darkfish.js" type="text/javascript" + charset="utf-8"></script> +</head> + +<body class="file"> + <div id="metadata"> + <div id="home-metadata"> + <div id="home-section" class="section"> + <h3 class="section-header"> + <a href="./index.html">Home</a> + <a href="./index.html#classes">Classes</a> + <a href="./index.html#methods">Methods</a> + </h3> + </div> + </div> + + <div id="project-metadata"> + + + <div id="fileindex-section" class="section project-section"> + <h3 class="section-header">Files</h3> + <ul> + + <li class="file"><a href="./README_rdoc.html">README.rdoc</a></li> + + </ul> + </div> + + + <div id="classindex-section" class="section project-section"> + <h3 class="section-header">Class Index + <span class="search-toggle"><img src="./images/find.png" + height="16" width="16" alt="[+]" + title="show/hide quicksearch" /></span></h3> + <form action="#" method="get" accept-charset="utf-8" class="initially-hidden"> + <fieldset> + <legend>Quicksearch</legend> + <input type="text" name="quicksearch" value="" + class="quicksearch-field" /> + </fieldset> + </form> + + <ul class="link-list"> + + <li><a href="./Porter2.html">Porter2</a></li> + + <li><a href="./String.html">String</a></li> + + </ul> + <div id="no-class-search-results" style="display: none;">No matching classes.</div> + </div> + + + </div> + </div> + + <div id="documentation"> + <h1>porter2stemmer</h1> +<h2>The Porter 2 stemmer</h2> +<p> +This is the Porter 2 stemming algorithm, as described at <a +href="http://snowball.tartarus.org/algorithms/english/stemmer.html">snowball.tartarus.org/algorithms/english/stemmer.html</a> +The original paper is: +</p> +<p> +Porter, 1980, “An algorithm for suffix stripping”, +<em>Program</em>, Vol. 14, no. 3, pp 130-137 +</p> +<h2>Features of this implementation</h2> +<p> +This stemmer is written in pure Ruby, making it easy to modify for language +variants. For instance, the original Porter stemmer only works for +American English and does not recognise British English’s +’-ise’ as an alternate spelling of ’-ize’. This +implementation has been extended to handle correctly British English. +</p> +<p> +This stemmer also features a comprehensive test set of over 29,000 words, +taken from the <a +href="http://snowball.tartarus.org/algorithms/english/stemmer.html">Porter +2 stemmer website</a>. +</p> +<h2>Files</h2> +<p> +Constants for the stemmer are in the <a href="Porter2.html">Porter2</a> +module. +</p> +<p> +Procedures that implement the stemmer are added to the <a +href="String.html">String</a> class. +</p> +<p> +The stemmer algorithm is implemented in the <a +href="String.html#method-i-porter2_stem">String#porter2_stem</a> procedure. +</p> +<h2>Internationalisation</h2> +<p> +There isn’t much, as this is a stemmer that only works for English. +</p> +<p> +The <tt>gb_english</tt> flag to the various procedures allows the stemmer +to treat the British English ’-ise’ the same as the American +English ’-ize’. +</p> +<h2>Longest suffixes</h2> +<p> +Several places in the algorithm require matching the longest suffix of a +word. The regexp engine in Ruby 1.9 seems to handle alterntives in regexps +by finding the alternative that matches at the first position in the +string. As we’re only talking about suffixes, that first match is +also the longest suffix. If the regexp engine changes, this behaviour may +change and break the stemmer. +</p> +<h2>Usage</h2> +<p> +Call the <a +href="String.html#method-i-porter2_stem">String#porter2_stem</a> or <a +href="String.html#method-i-stem">String#stem</a> methods on a string to +return its stem +</p> +<pre> + "consistency".stem # => "consist" + "knitting".stem # => "knit" + "articulated".stem # => "articul" + "nationalize".stem # => "nation" + "nationalise".stem # => "nationalis" + "nationalise".stem(true) # => "nation" +</pre> +<h2>Author</h2> +<p> +The Porter 2 stemming algorithm was developed by <a +href="http://snowball.tartarus.org/algorithms/english/stemmer.html">Martin +Porter</a>. This implementation is by <a href="http://www.njae.me.uk">Neil +Smith</a>. +</p> +<h2>Contributing to porter2stemmer</h2> +<ul> +<li><p> +Check out the latest master to make sure the feature hasn’t been +implemented or the bug hasn’t been fixed yet +</p> +</li> +<li><p> +Check out the issue tracker to make sure someone already hasn’t +requested it and/or contributed it +</p> +</li> +<li><p> +Fork the project +</p> +</li> +<li><p> +Start a feature/bugfix branch +</p> +</li> +<li><p> +Commit and push until you are happy with your contribution +</p> +</li> +<li><p> +Make sure to add tests for it. This is important so I don’t break it +in a future version unintentionally. +</p> +</li> +<li><p> +Please try not to mess with the Rakefile, version, or history. If you want +to have your own version, or is otherwise necessary, that is fine, but +please isolate to its own commit so I can cherry-pick around it. +</p> +</li> +</ul> +<h2>Copyright</h2> +<p> +Copyright © 2011 Neil Smith. See LICENSE.txt for further details. +</p> + + </div> + + <div id="validator-badges"> + <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p> + <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish + Rdoc Generator</a> 1.1.6</small>.</p> + </div> +</body> +</html> + diff --git a/rdoc/String.html b/rdoc/String.html new file mode 100644 index 0000000..37dcde8 --- /dev/null +++ b/rdoc/String.html @@ -0,0 +1,1142 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>Class: String</title> + + <link rel="stylesheet" href="./rdoc.css" type="text/css" media="screen" /> + + <script src="./js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="./js/darkfish.js" type="text/javascript" + charset="utf-8"></script> + +</head> +<body class="class"> + + <div id="metadata"> + <div id="home-metadata"> + <div id="home-section" class="section"> + <h3 class="section-header"> + <a href="./index.html">Home</a> + <a href="./index.html#classes">Classes</a> + <a href="./index.html#methods">Methods</a> + </h3> + </div> + </div> + + <div id="file-metadata"> + <div id="file-list-section" class="section"> + <h3 class="section-header">In Files</h3> + <div class="section-body"> + <ul> + + <li><a href="./lib/porter2stemmer/implementation_rb.html?TB_iframe=true&height=550&width=785" + class="thickbox" title="lib/porter2stemmer/implementation.rb">lib/porter2stemmer/implementation.rb</a></li> + + </ul> + </div> + </div> + + + </div> + + <div id="class-metadata"> + + <!-- Parent Class --> + + <div id="parent-class-section" class="section"> + <h3 class="section-header">Parent</h3> + + <p class="link">Object</p> + + </div> + + + <!-- Namespace Contents --> + + + <!-- Method Quickref --> + + <div id="method-list-section" class="section"> + <h3 class="section-header">Methods</h3> + <ul class="link-list"> + + <li><a href="#method-i-porter2_ends_with_short_syllable%3F">#porter2_ends_with_short_syllable?</a></li> + + <li><a href="#method-i-porter2_is_short_word%3F">#porter2_is_short_word?</a></li> + + <li><a href="#method-i-porter2_postprocess">#porter2_postprocess</a></li> + + <li><a href="#method-i-porter2_preprocess">#porter2_preprocess</a></li> + + <li><a href="#method-i-porter2_r1">#porter2_r1</a></li> + + <li><a href="#method-i-porter2_r2">#porter2_r2</a></li> + + <li><a href="#method-i-porter2_stem">#porter2_stem</a></li> + + <li><a href="#method-i-porter2_stem_verbose">#porter2_stem_verbose</a></li> + + <li><a href="#method-i-porter2_step0">#porter2_step0</a></li> + + <li><a href="#method-i-porter2_step1a">#porter2_step1a</a></li> + + <li><a href="#method-i-porter2_step1b">#porter2_step1b</a></li> + + <li><a href="#method-i-porter2_step1c">#porter2_step1c</a></li> + + <li><a href="#method-i-porter2_step2">#porter2_step2</a></li> + + <li><a href="#method-i-porter2_step3">#porter2_step3</a></li> + + <li><a href="#method-i-porter2_step4">#porter2_step4</a></li> + + <li><a href="#method-i-porter2_step5">#porter2_step5</a></li> + + <li><a href="#method-i-porter2_tidy">#porter2_tidy</a></li> + + <li><a href="#method-i-stem">#stem</a></li> + + </ul> + </div> + + + <!-- Included Modules --> + + </div> + + <div id="project-metadata"> + + + <div id="fileindex-section" class="section project-section"> + <h3 class="section-header">Files</h3> + <ul> + + <li class="file"><a href="./README_rdoc.html">README.rdoc</a></li> + + </ul> + </div> + + + <div id="classindex-section" class="section project-section"> + <h3 class="section-header">Class Index + <span class="search-toggle"><img src="./images/find.png" + height="16" width="16" alt="[+]" + title="show/hide quicksearch" /></span></h3> + <form action="#" method="get" accept-charset="utf-8" class="initially-hidden"> + <fieldset> + <legend>Quicksearch</legend> + <input type="text" name="quicksearch" value="" + class="quicksearch-field" /> + </fieldset> + </form> + + <ul class="link-list"> + + <li><a href="./Porter2.html">Porter2</a></li> + + <li><a href="./String.html">String</a></li> + + </ul> + <div id="no-class-search-results" style="display: none;">No matching classes.</div> + </div> + + + </div> + </div> + + <div id="documentation"> + <h1 class="class">String</h1> + + <div id="description"> + <p> +Implementation of the Porter 2 stemmer. <a +href="String.html#method-i-porter2_stem">String#porter2_stem</a> is the +main stemming procedure. +</p> + + </div> + + <!-- Constants --> + + + <!-- Attributes --> + + + <!-- Methods --> + + <div id="public-instance-method-details" class="method-section section"> + <h3 class="section-header">Public Instance Methods</h3> + + + <div id="porter-ends-with-short-syllable--method" class="method-detail "> + <a name="method-i-porter2_ends_with_short_syllable%3F"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_ends_with_short_syllable?</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Returns true if the word ends with a short syllable +</p> + + + + <div class="method-source-code" + id="porter-ends-with-short-syllable--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 59</span> +59: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_ends_with_short_syllable?</span> +60: <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::SHORT_SYLLABLE}$/</span> <span class="ruby-operator">?</span> <span class="ruby-keyword kw">true</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">false</span> +61: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-is-short-word--method" class="method-detail "> + <a name="method-i-porter2_is_short_word%3F"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_is_short_word?</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +A word is short if it ends in a short syllable, and R1 is null +</p> + + + + <div class="method-source-code" + id="porter-is-short-word--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 65</span> +65: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_is_short_word?</span> +66: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_ends_with_short_syllable?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span>.<span class="ruby-identifier">empty?</span> +67: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-postprocess-method" class="method-detail "> + <a name="method-i-porter2_postprocess"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_postprocess</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Turn all Y letters into y +</p> + + + + <div class="method-source-code" + id="porter-postprocess-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 261</span> +261: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_postprocess</span> +262: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">gsub</span>(<span class="ruby-regexp re">/Y/</span>, <span class="ruby-value str">'y'</span>) +263: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-preprocess-method" class="method-detail "> + <a name="method-i-porter2_preprocess"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_preprocess</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Preprocess the word. Remove any initial ’, if present. Then, set +initial y, or y after a vowel, to Y +</p> +<p> +(The comment to ‘establish the regions R1 and R2’ in the +original description is an implementation optimisation that identifies +where the regions start. As no modifications are made to the word that +affect those positions, you may want to cache them now. This implementation +doesn’t do that.) +</p> + + + + <div class="method-source-code" + id="porter-preprocess-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 25</span> +25: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_preprocess</span> +26: <span class="ruby-identifier">w</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">dup</span> +27: +28: <span class="ruby-comment cmt"># remove any initial apostrophe</span> +29: <span class="ruby-identifier">w</span>.<span class="ruby-identifier">gsub!</span>(<span class="ruby-regexp re">/^'*(.)/</span>, <span class="ruby-value str">'\1'</span>) +30: +31: <span class="ruby-comment cmt"># set initial y, or y after a vowel, to Y</span> +32: <span class="ruby-identifier">w</span>.<span class="ruby-identifier">gsub!</span>(<span class="ruby-regexp re">/^y/</span>, <span class="ruby-value str">"Y"</span>) +33: <span class="ruby-identifier">w</span>.<span class="ruby-identifier">gsub!</span>(<span class="ruby-node">/(#{Porter2::V})y/</span>, <span class="ruby-value str">'\1Y'</span>) +34: +35: <span class="ruby-identifier">w</span> +36: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-r--method" class="method-detail "> + <a name="method-i-porter2_r1"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_r1</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +R1 is the portion of the word after the first non-vowel after the first +vowel (with words beginning ‘gener-’, ‘commun-’, +and ‘arsen-’ treated as special cases +</p> + + + + <div class="method-source-code" + id="porter-r--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 41</span> +41: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_r1</span> +42: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^(gener|commun|arsen)(?<r1>.*)/</span> +43: <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">last_match</span>(<span class="ruby-value">:r1</span>) +44: <span class="ruby-keyword kw">else</span> +45: <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::V}#{Porter2::C}(?<r1>.*)$/</span> +46: <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">last_match</span>(<span class="ruby-value">:r1</span>) <span class="ruby-operator">||</span> <span class="ruby-value str">""</span> +47: <span class="ruby-keyword kw">end</span> +48: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-r--method" class="method-detail "> + <a name="method-i-porter2_r2"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_r2</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +R2 is the portion of R1 (<a +href="String.html#method-i-porter2_r1">porter2_r1</a>) after the first +non-vowel after the first vowel +</p> + + + + <div class="method-source-code" + id="porter-r--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 52</span> +52: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_r2</span> +53: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::V}#{Porter2::C}(?<r2>.*)$/</span> +54: <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">last_match</span>(<span class="ruby-value">:r2</span>) <span class="ruby-operator">||</span> <span class="ruby-value str">""</span> +55: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-stem-method" class="method-detail "> + <a name="method-i-porter2_stem"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_stem</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Perform the stemming procedure. If <tt>gb_english</tt> is true, treat +’-ise’ and similar suffixes as ’-ize’ in American +English. +</p> + + + + <div class="method-source-code" + id="porter-stem-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 269</span> +269: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_stem</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +270: <span class="ruby-identifier">preword</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_tidy</span> +271: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">preword</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator"><=</span> <span class="ruby-value">2</span> +272: +273: <span class="ruby-identifier">word</span> = <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">porter2_preprocess</span> +274: +275: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CASES</span>.<span class="ruby-identifier">has_key?</span> <span class="ruby-identifier">word</span> +276: <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CASES</span>[<span class="ruby-identifier">word</span>] +277: <span class="ruby-keyword kw">else</span> +278: <span class="ruby-identifier">w1a</span> = <span class="ruby-identifier">word</span>.<span class="ruby-identifier">porter2_step0</span>.<span class="ruby-identifier">porter2_step1a</span> +279: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">STEP_1A_SPECIAL_CASES</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">w1a</span> +280: <span class="ruby-identifier">w1a</span> +281: <span class="ruby-keyword kw">else</span> +282: <span class="ruby-identifier">w1a</span>.<span class="ruby-identifier">porter2_step1b</span>(<span class="ruby-identifier">gb_english</span>).<span class="ruby-identifier">porter2_step1c</span>.<span class="ruby-identifier">porter2_step2</span>(<span class="ruby-identifier">gb_english</span>).<span class="ruby-identifier">porter2_step3</span>(<span class="ruby-identifier">gb_english</span>).<span class="ruby-identifier">porter2_step4</span>(<span class="ruby-identifier">gb_english</span>).<span class="ruby-identifier">porter2_step5</span>.<span class="ruby-identifier">porter2_postprocess</span> +283: <span class="ruby-keyword kw">end</span> +284: <span class="ruby-keyword kw">end</span> +285: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + <div class="aliases"> + Also aliased as: <a href="String.html#method-i-stem">stem</a> + </div> + + + + </div> + + + <div id="porter-stem-verbose-method" class="method-detail "> + <a name="method-i-porter2_stem_verbose"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_stem_verbose</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +A verbose version of <a +href="String.html#method-i-porter2_stem">porter2_stem</a> that prints the +output of each stage to STDOUT +</p> + + + + <div class="method-source-code" + id="porter-stem-verbose-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 288</span> +288: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_stem_verbose</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +289: <span class="ruby-identifier">preword</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_tidy</span> +290: <span class="ruby-identifier">puts</span> <span class="ruby-node">"Preword: #{preword}"</span> +291: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">preword</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator"><=</span> <span class="ruby-value">2</span> +292: +293: <span class="ruby-identifier">word</span> = <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">porter2_preprocess</span> +294: <span class="ruby-identifier">puts</span> <span class="ruby-node">"Preprocessed: #{word}"</span> +295: +296: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CASES</span>.<span class="ruby-identifier">has_key?</span> <span class="ruby-identifier">word</span> +297: <span class="ruby-identifier">puts</span> <span class="ruby-node">"Returning #{word} as special case #{Porter2::SPECIAL_CASES[word]}"</span> +298: <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">SPECIAL_CASES</span>[<span class="ruby-identifier">word</span>] +299: <span class="ruby-keyword kw">else</span> +300: <span class="ruby-identifier">r1</span> = <span class="ruby-identifier">word</span>.<span class="ruby-identifier">porter2_r1</span> +301: <span class="ruby-identifier">r2</span> = <span class="ruby-identifier">word</span>.<span class="ruby-identifier">porter2_r2</span> +302: <span class="ruby-identifier">puts</span> <span class="ruby-node">"R1 = #{r1}, R2 = #{r2}"</span> +303: +304: <span class="ruby-identifier">w0</span> = <span class="ruby-identifier">word</span>.<span class="ruby-identifier">porter2_step0</span> ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 0: #{w0} (R1 = #{w0.porter2_r1}, R2 = #{w0.porter2_r2})"</span> +305: <span class="ruby-identifier">w1a</span> = <span class="ruby-identifier">w0</span>.<span class="ruby-identifier">porter2_step1a</span> ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 1a: #{w1a} (R1 = #{w1a.porter2_r1}, R2 = #{w1a.porter2_r2})"</span> +306: +307: <span class="ruby-keyword kw">if</span> <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">STEP_1A_SPECIAL_CASES</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">w1a</span> +308: <span class="ruby-identifier">puts</span> <span class="ruby-node">"Returning #{w1a} as 1a special case"</span> +309: <span class="ruby-identifier">w1a</span> +310: <span class="ruby-keyword kw">else</span> +311: <span class="ruby-identifier">w1b</span> = <span class="ruby-identifier">w1a</span>.<span class="ruby-identifier">porter2_step1b</span>(<span class="ruby-identifier">gb_english</span>) ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 1b: #{w1b} (R1 = #{w1b.porter2_r1}, R2 = #{w1b.porter2_r2})"</span> +312: <span class="ruby-identifier">w1c</span> = <span class="ruby-identifier">w1b</span>.<span class="ruby-identifier">porter2_step1c</span> ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 1c: #{w1c} (R1 = #{w1c.porter2_r1}, R2 = #{w1c.porter2_r2})"</span> +313: <span class="ruby-identifier">w2</span> = <span class="ruby-identifier">w1c</span>.<span class="ruby-identifier">porter2_step2</span>(<span class="ruby-identifier">gb_english</span>) ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 2: #{w2} (R1 = #{w2.porter2_r1}, R2 = #{w2.porter2_r2})"</span> +314: <span class="ruby-identifier">w3</span> = <span class="ruby-identifier">w2</span>.<span class="ruby-identifier">porter2_step3</span>(<span class="ruby-identifier">gb_english</span>) ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 3: #{w3} (R1 = #{w3.porter2_r1}, R2 = #{w3.porter2_r2})"</span> +315: <span class="ruby-identifier">w4</span> = <span class="ruby-identifier">w3</span>.<span class="ruby-identifier">porter2_step4</span>(<span class="ruby-identifier">gb_english</span>) ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 4: #{w4} (R1 = #{w4.porter2_r1}, R2 = #{w4.porter2_r2})"</span> +316: <span class="ruby-identifier">w5</span> = <span class="ruby-identifier">w4</span>.<span class="ruby-identifier">porter2_step5</span> ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After step 5: #{w5}"</span> +317: <span class="ruby-identifier">wpost</span> = <span class="ruby-identifier">w5</span>.<span class="ruby-identifier">porter2_postprocess</span> ; <span class="ruby-identifier">puts</span> <span class="ruby-node">"After postprocess: #{wpost}"</span> +318: <span class="ruby-identifier">wpost</span> +319: <span class="ruby-keyword kw">end</span> +320: <span class="ruby-keyword kw">end</span> +321: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step--method" class="method-detail "> + <a name="method-i-porter2_step0"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step0</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the suffixes, +</p> +<ul> +<li><p> +‘ +</p> +</li> +<li><p> +’s +</p> +</li> +<li><p> +’s’ +</p> +</li> +</ul> +<p> +and remove if found. +</p> + + + + <div class="method-source-code" + id="porter-step--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 75</span> +75: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step0</span> +76: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub!</span>(<span class="ruby-regexp re">/(.)('s'|'s|')$/</span>, <span class="ruby-value str">'\1'</span>) <span class="ruby-operator">||</span> <span class="ruby-keyword kw">self</span> +77: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step-a-method" class="method-detail "> + <a name="method-i-porter2_step1a"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step1a</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the following suffixes, and perform the action +indicated. +</p> +<table> +<tr><td valign="top">sses</td><td><p> +replace by ss +</p> +</td></tr> +<tr><td valign="top">ied, ies</td><td><p> +replace by i if preceded by more than one letter, otherwise by ie +</p> +</td></tr> +<tr><td valign="top">s</td><td><p> +delete if the preceding word part contains a vowel not immediately before +the s +</p> +</td></tr> +<tr><td valign="top">us, ss</td><td><p> +do nothing +</p> +</td></tr> +</table> + + + + <div class="method-source-code" + id="porter-step-a-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 85</span> + 85: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step1a</span> + 86: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/sses$/</span> + 87: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/sses$/</span>, <span class="ruby-value str">'ss'</span>) + 88: <span class="ruby-keyword kw">elsif</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/..(ied|ies)$/</span> + 89: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/(ied|ies)$/</span>, <span class="ruby-value str">'i'</span>) + 90: <span class="ruby-keyword kw">elsif</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(ied|ies)$/</span> + 91: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/(ied|ies)$/</span>, <span class="ruby-value str">'ie'</span>) + 92: <span class="ruby-keyword kw">elsif</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(us|ss)$/</span> + 93: <span class="ruby-keyword kw">self</span> + 94: <span class="ruby-keyword kw">elsif</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/s$/</span> + 95: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/(#{Porter2::V}.+)s$/</span> + 96: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/s$/</span>, <span class="ruby-value str">''</span>) + 97: <span class="ruby-keyword kw">else</span> + 98: <span class="ruby-keyword kw">self</span> + 99: <span class="ruby-keyword kw">end</span> +100: <span class="ruby-keyword kw">else</span> +101: <span class="ruby-keyword kw">self</span> +102: <span class="ruby-keyword kw">end</span> +103: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step-b-method" class="method-detail "> + <a name="method-i-porter2_step1b"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step1b</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the following suffixes, and perform the action +indicated. +</p> +<table> +<tr><td valign="top">eed, eedly</td><td><p> +replace by ee if the suffix is also in R1 +</p> +</td></tr> +<tr><td valign="top">ed, edly, ing, ingly</td><td><p> +delete if the preceding word part contains a vowel and, after the +deletion: +</p> +<ul> +<li><p> +if the word ends at, bl or iz: add e, or +</p> +</li> +</ul> +<ul> +<li><p> +if the word ends with a double: remove the last letter, or +</p> +</li> +</ul> +<ul> +<li><p> +if the word is short: add e +</p> +</li> +</ul> +</td></tr> +</table> +<p> +(If gb_english is <tt>true</tt>, treat the ‘is’ suffix as +‘iz’ above.) +</p> + + + + <div class="method-source-code" + id="porter-step-b-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 115</span> +115: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step1b</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +116: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(eed|eedly)$/</span> +117: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(eed|eedly)$/</span> +118: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/(eed|eedly)$/</span>, <span class="ruby-value str">'ee'</span>) +119: <span class="ruby-keyword kw">else</span> +120: <span class="ruby-keyword kw">self</span> +121: <span class="ruby-keyword kw">end</span> +122: <span class="ruby-keyword kw">else</span> +123: <span class="ruby-identifier">w</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">dup</span> +124: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">w</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::V}.*(ed|edly|ing|ingly)$/</span> +125: <span class="ruby-identifier">w</span>.<span class="ruby-identifier">sub!</span>(<span class="ruby-regexp re">/(ed|edly|ing|ingly)$/</span>, <span class="ruby-value str">''</span>) +126: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">w</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(at|lb|iz)$/</span> +127: <span class="ruby-identifier">w</span> <span class="ruby-operator">+=</span> <span class="ruby-value str">'e'</span> +128: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">w</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/is$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">gb_english</span> +129: <span class="ruby-identifier">w</span> <span class="ruby-operator">+=</span> <span class="ruby-value str">'e'</span> +130: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">w</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::Double}$/</span> +131: <span class="ruby-identifier">w</span>.<span class="ruby-identifier">chop!</span> +132: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">w</span>.<span class="ruby-identifier">porter2_is_short_word?</span> +133: <span class="ruby-identifier">w</span> <span class="ruby-operator">+=</span> <span class="ruby-value str">'e'</span> +134: <span class="ruby-keyword kw">end</span> +135: <span class="ruby-keyword kw">end</span> +136: <span class="ruby-identifier">w</span> +137: <span class="ruby-keyword kw">end</span> +138: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step-c-method" class="method-detail "> + <a name="method-i-porter2_step1c"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step1c</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Replace a suffix of y or Y by i if it is preceded by a non-vowel which is +not the first letter of the word. +</p> + + + + <div class="method-source-code" + id="porter-step-c-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 143</span> +143: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step1c</span> +144: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/.+#{Porter2::C}(y|Y)$/</span> +145: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/(y|Y)$/</span>, <span class="ruby-value str">'i'</span>) +146: <span class="ruby-keyword kw">else</span> +147: <span class="ruby-keyword kw">self</span> +148: <span class="ruby-keyword kw">end</span> +149: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step--method" class="method-detail "> + <a name="method-i-porter2_step2"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step2</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the suffixes listed in the keys of +Porter2::STEP_2_MAPS. If one is found and that suffix occurs in R1, +replace it with the value found in STEP_2_MAPS. +</p> +<p> +(Suffixes ‘ogi’ and ‘li’ are treated as special +cases in the procedure.) +</p> +<p> +(If gb_english is <tt>true</tt>, replace the ‘iser’ and +‘isation’ suffixes with ‘ise’, similarly to how +‘izer’ and ‘ization’ are treated.) +</p> + + + + <div class="method-source-code" + id="porter-step--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 160</span> +160: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step2</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +161: <span class="ruby-identifier">r1</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span> +162: <span class="ruby-identifier">s2m</span> = <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">STEP_2_MAPS</span>.<span class="ruby-identifier">dup</span> +163: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">gb_english</span> +164: <span class="ruby-identifier">s2m</span>[<span class="ruby-value str">"iser"</span>] = <span class="ruby-value str">"ise"</span> +165: <span class="ruby-identifier">s2m</span>[<span class="ruby-value str">"isation"</span>] = <span class="ruby-value str">"ise"</span> +166: <span class="ruby-keyword kw">end</span> +167: <span class="ruby-identifier">step_2_re</span> = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">union</span>(<span class="ruby-identifier">s2m</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">r</span><span class="ruby-operator">|</span> <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">r</span> <span class="ruby-operator">+</span> <span class="ruby-value str">"$"</span>)}) +168: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-identifier">step_2_re</span> +169: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">r1</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{$&}$/</span> +170: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-node">/#{$&}$/</span>, <span class="ruby-identifier">s2m</span>[<span class="ruby-node">$&</span>]) +171: <span class="ruby-keyword kw">else</span> +172: <span class="ruby-keyword kw">self</span> +173: <span class="ruby-keyword kw">end</span> +174: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">r1</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/li$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/(#{Porter2::Valid_LI})li$/</span> +175: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/li$/</span>, <span class="ruby-value str">''</span>) +176: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">r1</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/ogi$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/logi$/</span> +177: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/ogi$/</span>, <span class="ruby-value str">'og'</span>) +178: <span class="ruby-keyword kw">else</span> +179: <span class="ruby-keyword kw">self</span> +180: <span class="ruby-keyword kw">end</span> +181: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step--method" class="method-detail "> + <a name="method-i-porter2_step3"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step3</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the suffixes listed in the keys of +Porter2::STEP_3_MAPS. If one is found and that suffix occurs in R1, +replace it with the value found in STEP_3_MAPS. +</p> +<p> +(Suffix ‘ative’ is treated as a special case in the procedure.) +</p> +<p> +(If gb_english is <tt>true</tt>, replace the ‘alise’ suffix +with ‘al’, similarly to how ‘alize’ is treated.) +</p> + + + + <div class="method-source-code" + id="porter-step--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 192</span> +192: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step3</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +193: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/ative$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r2</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/ative$/</span> +194: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/ative$/</span>, <span class="ruby-value str">''</span>) +195: <span class="ruby-keyword kw">else</span> +196: <span class="ruby-identifier">s3m</span> = <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">STEP_3_MAPS</span>.<span class="ruby-identifier">dup</span> +197: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">gb_english</span> +198: <span class="ruby-identifier">s3m</span>[<span class="ruby-value str">"alise"</span>] = <span class="ruby-value str">"al"</span> +199: <span class="ruby-keyword kw">end</span> +200: <span class="ruby-identifier">step_3_re</span> = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">union</span>(<span class="ruby-identifier">s3m</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">r</span><span class="ruby-operator">|</span> <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">r</span> <span class="ruby-operator">+</span> <span class="ruby-value str">"$"</span>)}) +201: <span class="ruby-identifier">r1</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span> +202: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-identifier">step_3_re</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">r1</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{$&}$/</span> +203: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-node">/#{$&}$/</span>, <span class="ruby-identifier">s3m</span>[<span class="ruby-node">$&</span>]) +204: <span class="ruby-keyword kw">else</span> +205: <span class="ruby-keyword kw">self</span> +206: <span class="ruby-keyword kw">end</span> +207: <span class="ruby-keyword kw">end</span> +208: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step--method" class="method-detail "> + <a name="method-i-porter2_step4"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step4</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the longest among the suffixes listed in the keys of +Porter2::STEP_4_MAPS. If one is found and that suffix occurs in R2, +replace it with the value found in STEP_4_MAPS. +</p> +<p> +(Suffix ‘ion’ is treated as a special case in the procedure.) +</p> +<p> +(If gb_english is <tt>true</tt>, delete the ‘ise’ suffix if +found.) +</p> + + + + <div class="method-source-code" + id="porter-step--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 218</span> +218: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step4</span>(<span class="ruby-identifier">gb_english</span> = <span class="ruby-keyword kw">false</span>) +219: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r2</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/ion$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(s|t)ion$/</span> +220: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/ion$/</span>, <span class="ruby-value str">''</span>) +221: <span class="ruby-keyword kw">else</span> +222: <span class="ruby-identifier">s4m</span> = <span class="ruby-constant">Porter2</span><span class="ruby-operator">::</span><span class="ruby-constant">STEP_4_MAPS</span>.<span class="ruby-identifier">dup</span> +223: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">gb_english</span> +224: <span class="ruby-identifier">s4m</span>[<span class="ruby-value str">"ise"</span>] = <span class="ruby-value str">""</span> +225: <span class="ruby-keyword kw">end</span> +226: <span class="ruby-identifier">step_4_re</span> = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">union</span>(<span class="ruby-identifier">s4m</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">r</span><span class="ruby-operator">|</span> <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">r</span> <span class="ruby-operator">+</span> <span class="ruby-value str">"$"</span>)}) +227: <span class="ruby-identifier">r2</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r2</span> +228: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-identifier">step_4_re</span> +229: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">r2</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{$&}/</span> +230: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-node">/#{$&}$/</span>, <span class="ruby-identifier">s4m</span>[<span class="ruby-node">$&</span>]) +231: <span class="ruby-keyword kw">else</span> +232: <span class="ruby-keyword kw">self</span> +233: <span class="ruby-keyword kw">end</span> +234: <span class="ruby-keyword kw">else</span> +235: <span class="ruby-keyword kw">self</span> +236: <span class="ruby-keyword kw">end</span> +237: <span class="ruby-keyword kw">end</span> +238: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-step--method" class="method-detail "> + <a name="method-i-porter2_step5"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_step5</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Search for the the following suffixes, and, if found, perform the action +indicated. +</p> +<table> +<tr><td valign="top">e</td><td><p> +delete if in R2, or in R1 and not preceded by a short syllable +</p> +</td></tr> +<tr><td valign="top">l</td><td><p> +delete if in R2 and preceded by l +</p> +</td></tr> +</table> + + + + <div class="method-source-code" + id="porter-step--source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 244</span> +244: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_step5</span> +245: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/ll$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r2</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/l$/</span> +246: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/ll$/</span>, <span class="ruby-value str">'l'</span>) +247: <span class="ruby-keyword kw">elsif</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/e$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r2</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/e$/</span> +248: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/e$/</span>, <span class="ruby-value str">''</span>) +249: <span class="ruby-keyword kw">else</span> +250: <span class="ruby-identifier">r1</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">porter2_r1</span> +251: <span class="ruby-keyword kw">if</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/e$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">r1</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/e$/</span> <span class="ruby-keyword kw">and</span> <span class="ruby-keyword kw">not</span> <span class="ruby-keyword kw">self</span> <span class="ruby-operator">=~</span> <span class="ruby-node">/#{Porter2::SHORT_SYLLABLE}e$/</span> +252: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/e$/</span>, <span class="ruby-value str">''</span>) +253: <span class="ruby-keyword kw">else</span> +254: <span class="ruby-keyword kw">self</span> +255: <span class="ruby-keyword kw">end</span> +256: <span class="ruby-keyword kw">end</span> +257: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="porter-tidy-method" class="method-detail "> + <a name="method-i-porter2_tidy"></a> + + <div class="method-heading"> + + <span class="method-name">porter2_tidy</span><span + class="method-args">()</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + <p> +Tidy up the word before we get down to the algorithm +</p> + + + + <div class="method-source-code" + id="porter-tidy-source"> +<pre> + <span class="ruby-comment cmt"># File lib/porter2stemmer/implementation.rb, line 7</span> + 7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">porter2_tidy</span> + 8: <span class="ruby-identifier">preword</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">strip</span>.<span class="ruby-identifier">downcase</span> + 9: +10: <span class="ruby-comment cmt"># map apostrophe-like characters to apostrophes</span> +11: <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">gsub!</span>(<span class="ruby-regexp re">/â/</span>, <span class="ruby-value str">"'"</span>) +12: <span class="ruby-identifier">preword</span>.<span class="ruby-identifier">gsub!</span>(<span class="ruby-regexp re">/â/</span>, <span class="ruby-value str">"'"</span>) +13: +14: <span class="ruby-identifier">preword</span> +15: <span class="ruby-keyword kw">end</span></pre> + </div> + + </div> + + + + + </div> + + + <div id="stem-method" class="method-detail method-alias"> + <a name="method-i-stem"></a> + + <div class="method-heading"> + + <span class="method-name">stem</span><span + class="method-args">(gb_english = false)</span> + <span class="method-click-advice">click to toggle source</span> + + </div> + + <div class="method-description"> + + + + + + </div> + + + + + <div class="aliases"> + Alias for: <a href="String.html#method-i-porter2_stem">porter2_stem</a> + </div> + + </div> + + + </div> + + + </div> + + + <div id="rdoc-debugging-section-dump" class="debugging-section"> + + <p>Disabled; run with --debug to generate this.</p> + + </div> + + <div id="validator-badges"> + <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p> + <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish + Rdoc Generator</a> 1.1.6</small>.</p> + </div> + +</body> +</html> + diff --git a/rdoc/lib/porter2stemmer/constants_rb.html b/rdoc/lib/porter2stemmer/constants_rb.html new file mode 100644 index 0000000..2b525f3 --- /dev/null +++ b/rdoc/lib/porter2stemmer/constants_rb.html @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>File: constants.rb [porter2stemmer 1.0.0]</title> + + <link type="text/css" media="screen" href="../../rdoc.css" rel="stylesheet" /> + + <script src="../../js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/darkfish.js" type="text/javascript" + charset="utf-8"></script> +</head> + +<body class="file file-popup"> + <div id="metadata"> + <dl> + <dt class="modified-date">Last Modified</dt> + <dd class="modified-date">2011-01-09 09:20:05 +0000</dd> + + + <dt class="requires">Requires</dt> + <dd class="requires"> + <ul> + + </ul> + </dd> + + + + </dl> + </div> + + <div id="documentation"> + + <div class="description"> + <h2>Description</h2> + <p> +coding: utf-8 +</p> + + </div> + + </div> +</body> +</html> + diff --git a/rdoc/lib/porter2stemmer/implementation_rb.html b/rdoc/lib/porter2stemmer/implementation_rb.html new file mode 100644 index 0000000..754ad35 --- /dev/null +++ b/rdoc/lib/porter2stemmer/implementation_rb.html @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>File: implementation.rb [porter2stemmer 1.0.0]</title> + + <link type="text/css" media="screen" href="../../rdoc.css" rel="stylesheet" /> + + <script src="../../js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="../../js/darkfish.js" type="text/javascript" + charset="utf-8"></script> +</head> + +<body class="file file-popup"> + <div id="metadata"> + <dl> + <dt class="modified-date">Last Modified</dt> + <dd class="modified-date">2011-01-08 10:20:57 +0000</dd> + + + <dt class="requires">Requires</dt> + <dd class="requires"> + <ul> + + </ul> + </dd> + + + + </dl> + </div> + + <div id="documentation"> + + <div class="description"> + <h2>Description</h2> + <p> +coding: utf-8 +</p> + + </div> + + </div> +</body> +</html> + diff --git a/rdoc/lib/porter2stemmer_rb.html b/rdoc/lib/porter2stemmer_rb.html new file mode 100644 index 0000000..a5be8cb --- /dev/null +++ b/rdoc/lib/porter2stemmer_rb.html @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> + + <title>File: porter2stemmer.rb [porter2stemmer 1.0.0]</title> + + <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" /> + + <script src="../js/jquery.js" type="text/javascript" + charset="utf-8"></script> + <script src="../js/thickbox-compressed.js" type="text/javascript" + charset="utf-8"></script> + <script src="../js/quicksearch.js" type="text/javascript" + charset="utf-8"></script> + <script src="../js/darkfish.js" type="text/javascript" + charset="utf-8"></script> +</head> + +<body class="file file-popup"> + <div id="metadata"> + <dl> + <dt class="modified-date">Last Modified</dt> + <dd class="modified-date">2011-03-18 14:12:11 +0000</dd> + + + <dt class="requires">Requires</dt> + <dd class="requires"> + <ul> + + <li>porter2stemmer/constants</li> + + <li>porter2stemmer/implementation</li> + + </ul> + </dd> + + + + </dl> + </div> + + <div id="documentation"> + + <div class="description"> + <h2>Description</h2> + <p> +coding: utf-8 +</p> + + </div> + + </div> +</body> +</html> + diff --git a/rdoc/rdoc.css b/rdoc/rdoc.css new file mode 100644 index 0000000..ffe9960 --- /dev/null +++ b/rdoc/rdoc.css @@ -0,0 +1,706 @@ +/* + * "Darkfish" Rdoc CSS + * $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $ + * + * Author: Michael Granger <ged@FaerieMUD.org> + * + */ + +/* Base Green is: #6C8C22 */ + +*{ padding: 0; margin: 0; } + +body { + background: #efefef; + font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif; +} +body.class, body.module, body.file { + margin-left: 40px; +} +body.file-popup { + font-size: 90%; + margin-left: 0; +} + +h1 { + font-size: 300%; + text-shadow: rgba(135,145,135,0.65) 2px 2px 3px; + color: #6C8C22; +} +h2,h3,h4 { margin-top: 1.5em; } + +:link, +:visited { + color: #6C8C22; + text-decoration: none; +} +:link:hover, +:visited:hover { + border-bottom: 1px dotted #6C8C22; +} + +pre { + background: #ddd; + padding: 0.5em 0; +} + + +/* @group Generic Classes */ + +.initially-hidden { + display: none; +} + +.quicksearch-field { + width: 98%; + background: #ddd; + border: 1px solid #aaa; + height: 1.5em; + -webkit-border-radius: 4px; +} +.quicksearch-field:focus { + background: #f1edba; +} + +.missing-docs { + font-size: 120%; + background: white url(images/wrench_orange.png) no-repeat 4px center; + color: #ccc; + line-height: 2em; + border: 1px solid #d00; + opacity: 1; + padding-left: 20px; + text-indent: 24px; + letter-spacing: 3px; + font-weight: bold; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; +} + +.target-section { + border: 2px solid #dcce90; + border-left-width: 8px; + padding: 0 1em; + background: #fff3c2; +} + +/* @end */ + + +/* @group Index Page, Standalone file pages */ +body.indexpage { + margin: 1em 3em; +} +body.indexpage p, +body.indexpage div, +body.file p { + margin: 1em 0; +} + +.indexpage ul, +.file #documentation ul { + line-height: 160%; + list-style: none; +} +.indexpage ul :link, +.indexpage ul :visited { + font-size: 16px; +} + +.indexpage li, +.file #documentation li { + padding-left: 20px; + background: url(images/bullet_black.png) no-repeat left 4px; +} +.indexpage li.module { + background: url(images/package.png) no-repeat left 4px; +} +.indexpage li.class { + background: url(images/ruby.png) no-repeat left 4px; +} +.indexpage li.file { + background: url(images/page_white_text.png) no-repeat left 4px; +} +.file li p, +.indexpage li p { + margin: 0 0; +} + +/* @end */ + +/* @group Top-Level Structure */ + +.class #metadata, +.file #metadata, +.module #metadata { + float: left; + width: 260px; +} + +.class #documentation, +.file #documentation, +.module #documentation { + margin: 2em 1em 5em 300px; + min-width: 340px; +} + +.file #metadata { + margin: 0.8em; +} + +#validator-badges { + clear: both; + margin: 1em 1em 2em; +} + +/* @end */ + +/* @group Metadata Section */ +#metadata .section { + background-color: #dedede; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border: 1px solid #aaa; + margin: 0 8px 16px; + font-size: 90%; + overflow: hidden; +} +#metadata h3.section-header { + margin: 0; + padding: 2px 8px; + background: #ccc; + color: #666; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-bottom: 1px solid #aaa; +} +#metadata #home-section h3.section-header { + border-bottom: 0; +} + +#metadata ul, +#metadata dl, +#metadata p { + padding: 8px; + list-style: none; +} + +#file-metadata ul { + padding-left: 28px; + list-style-image: url(images/page_green.png); +} + +dl.svninfo { + color: #666; + margin: 0; +} +dl.svninfo dt { + font-weight: bold; +} + +ul.link-list li { + white-space: nowrap; +} +ul.link-list .type { + font-size: 8px; + text-transform: uppercase; + color: white; + background: #969696; + padding: 2px 4px; + -webkit-border-radius: 5px; +} + +/* @end */ + + +/* @group Project Metadata Section */ +#project-metadata { + margin-top: 3em; +} + +.file #project-metadata { + margin-top: 0em; +} + +#project-metadata .section { + border: 1px solid #aaa; +} +#project-metadata h3.section-header { + border-bottom: 1px solid #aaa; + position: relative; +} +#project-metadata h3.section-header .search-toggle { + position: absolute; + right: 5px; +} + + +#project-metadata form { + color: #777; + background: #ccc; + padding: 8px 8px 16px; + border-bottom: 1px solid #bbb; +} +#project-metadata fieldset { + border: 0; +} + +#no-class-search-results { + margin: 0 auto 1em; + text-align: center; + font-size: 14px; + font-weight: bold; + color: #aaa; +} + +/* @end */ + + +/* @group Documentation Section */ +#description { + font-size: 100%; + color: #333; +} + +#description p { + margin: 1em 0.4em; +} + +#description li p { + margin: 0; +} + +#description ul { + margin-left: 1.5em; +} +#description ul li { + line-height: 1.4em; +} + +#description dl, +#documentation dl { + margin: 8px 1.5em; + border: 1px solid #ccc; +} +#description dl { + font-size: 14px; +} + +#description dt, +#documentation dt { + padding: 2px 4px; + font-weight: bold; + background: #ddd; +} +#description dd, +#documentation dd { + padding: 2px 12px; +} +#description dd + dt, +#documentation dd + dt { + margin-top: 0.7em; +} + +#documentation .section { + font-size: 90%; +} +#documentation h3.section-header { + margin-top: 2em; + padding: 0.75em 0.5em; + background-color: #dedede; + color: #333; + font-size: 150%; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + +#constants-list > dl, +#attributes-list > dl { + margin: 1em 0 2em; + border: 0; +} +#constants-list > dl dt, +#attributes-list > dl dt { + padding-left: 0; + font-weight: bold; + font-family: Monaco, "Andale Mono"; + background: inherit; +} +#constants-list > dl dt a, +#attributes-list > dl dt a { + color: inherit; +} +#constants-list > dl dd, +#attributes-list > dl dd { + margin: 0 0 1em 0; + padding: 0; + color: #666; +} + +/* @group Method Details */ + +#documentation .method-source-code { + display: none; +} + +#documentation .method-detail { + margin: 0.5em 0; + padding: 0.5em 0; + cursor: pointer; +} +#documentation .method-detail:hover { + background-color: #f1edba; +} +#documentation .method-heading { + position: relative; + padding: 2px 4px 0 20px; + font-size: 125%; + font-weight: bold; + color: #333; + background: url(images/brick.png) no-repeat left bottom; +} +#documentation .method-heading :link, +#documentation .method-heading :visited { + color: inherit; +} +#documentation .method-click-advice { + position: absolute; + top: 2px; + right: 5px; + font-size: 10px; + color: #9b9877; + visibility: hidden; + padding-right: 20px; + line-height: 20px; + background: url(images/zoom.png) no-repeat right top; +} +#documentation .method-detail:hover .method-click-advice { + visibility: visible; +} + +#documentation .method-alias .method-heading { + color: #666; + background: url(images/brick_link.png) no-repeat left bottom; +} + +#documentation .method-description, +#documentation .aliases { + margin: 0 20px; + line-height: 1.2em; + color: #666; +} +#documentation .aliases { + padding-top: 4px; + font-style: italic; + cursor: default; +} +#documentation .method-description p { + padding: 0; +} +#documentation .method-description p + p { + margin-bottom: 0.5em; +} +#documentation .method-description ul { + margin-left: 1.5em; +} + +#documentation .attribute-method-heading { + background: url(images/tag_green.png) no-repeat left bottom; +} +#documentation #attribute-method-details .method-detail:hover { + background-color: transparent; + cursor: default; +} +#documentation .attribute-access-type { + font-size: 60%; + text-transform: uppercase; + vertical-align: super; + padding: 0 2px; +} +/* @end */ + +/* @end */ + + + +/* @group Source Code */ + +div.method-source-code { + background: #262626; + color: #efefef; + margin: 1em; + padding: 0.5em; + border: 1px dashed #999; + overflow: hidden; +} + +div.method-source-code pre { + background: inherit; + padding: 0; + color: white; + overflow: auto; +} + +/* @group Ruby keyword styles */ + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } + +/* @end */ +/* @end */ + + +/* @group File Popup Contents */ + +.file #metadata, +.file-popup #metadata { +} + +.file-popup dl { + font-size: 80%; + padding: 0.75em; + background-color: #dedede; + color: #333; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} +.file dt { + font-weight: bold; + padding-left: 22px; + line-height: 20px; + background: url(images/page_white_width.png) no-repeat left top; +} +.file dt.modified-date { + background: url(images/date.png) no-repeat left top; +} +.file dt.requires { + background: url(images/plugin.png) no-repeat left top; +} +.file dt.scs-url { + background: url(images/wrench.png) no-repeat left top; +} + +.file dl dd { + margin: 0 0 1em 0; +} +.file #metadata dl dd ul { + list-style: circle; + margin-left: 20px; + padding-top: 0; +} +.file #metadata dl dd ul li { +} + + +.file h2 { + margin-top: 2em; + padding: 0.75em 0.5em; + background-color: #dedede; + color: #333; + font-size: 120%; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + +/* @end */ + + + + +/* @group ThickBox Styles */ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color:#666666; +} + +#TB_window :link, +#TB_window :visited { color: #666666; } +#TB_window :link:hover, +#TB_window :visited:hover { color: #000; } +#TB_window :link:active, +#TB_window :visited:active { color: #666666; } +#TB_window :link:focus, +#TB_window :visited:focus { color: #666666; } + +#TB_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; +} + +.TB_overlayMacFFBGHack {background: url(images/macFFBgHack.png) repeat;} +.TB_overlayBG { + background-color:#000; + filter:alpha(opacity=75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +* html #TB_overlay { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + color:#000000; + display:none; + border: 4px solid #525252; + text-align:left; + top:50%; + left:50%; +} + +* html #TB_window { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_window img#TB_Image { + display:block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption{ + height:25px; + padding:7px 30px 10px 25px; + float:left; +} + +#TB_closeWindow{ + height:25px; + padding:11px 25px 10px 0; + float:right; +} + +#TB_closeAjaxWindow{ + padding:7px 10px 5px 0; + margin-bottom:1px; + text-align:right; + float:right; +} + +#TB_ajaxWindowTitle{ + float:left; + padding:7px 0 5px 10px; + margin-bottom:1px; + font-size: 22px; +} + +#TB_title{ + background-color: #6C8C22; + color: #dedede; + height:40px; +} +#TB_title :link, +#TB_title :visited { + color: white !important; + border-bottom: 1px dotted #dedede; +} + +#TB_ajaxContent{ + clear:both; + padding:2px 15px 15px 15px; + overflow:auto; + text-align:left; + line-height:1.4em; +} + +#TB_ajaxContent.TB_modal{ + padding:15px; +} + +#TB_ajaxContent p{ + padding:5px 0px 5px 0px; +} + +#TB_load{ + position: fixed; + display:none; + height:13px; + width:208px; + z-index:103; + top: 50%; + left: 50%; + margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ +} + +* html #TB_load { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_HideSelect{ + z-index:99; + position:fixed; + top: 0; + left: 0; + background-color:#fff; + border:none; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + height:100%; + width:100%; +} + +* html #TB_HideSelect { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_iframeContent{ + clear:both; + border:none; + margin-bottom:-1px; + margin-top:1px; + _margin-bottom:1px; +} + +/* @end */ + +/* @group Debugging Section */ + +#debugging-toggle { + text-align: center; +} +#debugging-toggle img { + cursor: pointer; +} + +#rdoc-debugging-section-dump { + display: none; + margin: 0 2em 2em; + background: #ccc; + border: 1px solid #999; +} + + + +/* @end */