summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--artists.php98
-rwxr-xr-xdocs/CHANGELOG2
-rw-r--r--lib/class/artist.class.php139
-rw-r--r--lib/duplicates.php2
-rw-r--r--lib/ui.lib.php2
-rw-r--r--templates/show_artist_box.inc.php1
-rw-r--r--templates/show_rename_artist.inc.php2
-rw-r--r--templates/show_similar_artists.inc159
8 files changed, 377 insertions, 28 deletions
diff --git a/artists.php b/artists.php
index cbaa6e0a..b1f4452a 100644
--- a/artists.php
+++ b/artists.php
@@ -47,6 +47,7 @@ switch($action) {
$artist = new Artist($_REQUEST['artist']);
$artist->format_artist();
$song_ids = $artist->get_song_ids();
+ $artist_id = $artist->id;
require(conf('prefix') . '/templates/show_artist_box.inc.php');
show_songs($song_ids);
break;
@@ -64,6 +65,62 @@ switch($action) {
echo "<a href=\"" . conf('web_path') . "/artists.php?action=show&amp;artist=" . $_REQUEST['artist'] . "\">[" . _("Return") . "]</a>";
break;
+ case 'rename_similar':
+ if (!$user->has_access('100')) { access_denied(); }
+ $count = 0;
+ if (isset($_REQUEST['artist']) && is_numeric($_REQUEST['artist']) && isset($_REQUEST['artists']) && is_array($_REQUEST['artists'])) {
+ $artist = new Artist($_REQUEST['artist']);
+ if ($artist->id)
+ foreach ($_REQUEST['artists'] as $artist_id) {
+ if (is_numeric($artist_id)) {
+ $that_artist = new Artist($artist_id);
+ if ($that_artist->id) {
+ $that_artist->merge($artist->id);
+ $count++;
+ } else
+ $GLOBALS['error']->add_error('general',"Error: No such artist '$artist_id'");
+ } else {
+ $GLOBALS['error']->add_error('general',"Error: '$artist_id' is not a valid ID");
+ }
+ }
+ else
+ $GLOBALS['error']->add_error('general',"Error: No such artist '" . $_REQUEST['artist'] . "'");
+ } else {
+ $GLOBALS['error']->add_error('general',"Error: Errenous request");
+ }
+ if ($count > 0) {
+ show_confirmation (
+ "Renamed artist(s)",
+ "$count artists have been merged with " . $artist->name,
+ conf('web_path') . "/artists.php?action=show&artist=" . $artist->id
+ );
+ } else {
+ $GLOBALS['error']->print_error('general');
+ }
+
+ break;
+ case 'show_similar':
+ if (!$user->has_access('100')) { access_denied(); }
+
+ if (isset($_REQUEST['artist'])) {
+ $artist = new Artist($_REQUEST['artist']);
+ //options
+ $similar_artists = $artist->get_similar_artists(
+ make_bool($_POST['n_rep_uml']),
+ $_POST['n_filter'],
+ $_POST['n_ignore'],
+ $_POST['c_mode'],
+ $_POST['c_count_w'],
+ $_POST['c_percent_w'],
+ $_POST['c_distance_l'],
+ make_bool($_POST['c_ignins_l']));
+ $artist_id = $artist->id;
+ $artist_name = $artist->name;
+ require (conf('prefix') . '/templates/show_similar_artists.inc');
+ } else {
+ $GLOBALS['error']->add_error('general',"Error: No artist given");
+ }
+ break;
case 'rename':
//die if not enough permissions
if (!$user->has_access('100')) { access_denied(); }
@@ -78,39 +135,50 @@ switch($action) {
//if we want to update id3 tags, then get the array of ids now, it's too late afterwards
if (make_bool($_POST['update_id3']))
$songs = $artist->get_songs();
-
- //the manual rename takes priority
- if ($_POST['artist_name'] != "") {
- //then just change the name of the artist in the db
- $newid = $artist->rename($_POST['artist_name']);
+ $ret = 0;
+ //the manual rename takes priority, but if they tested out the insert thing ignore
+ if ($_POST['artist_name'] != "" && $_POST['artist_name'] != $artist->name) {
+ //then just change the name of the artist in the db
+ $ret = $artist->rename($_POST['artist_name']);
+ $newid = $ret;
+ $newname = $_POST['artist_name'];
}
+ //new id?
elseif ($_POST['artist_id'] != $artist->id) {
- if ($_POST['test_stats'] == 'yes') {
- $catalog->merge_stats("artist",$artist->id,$_POST['artist_id']);
- }
- else {
//merge with other artist
- $artist->merge($_POST['artist_id']);
- $newid = $_POST['artist_id'];
- }
+ $ret = $artist->merge($_POST['artist_id']);
+ $newid = $_POST['artist_id'];
+ $newname = $ret;
} // elseif different artist and id
+ //if no changes, no changes
- //now flag for id3tag update if selected, and song id changed
- if ($_POST['update_id3'] == "yes" && $newid != $artist->id) {
+ //now flag for id3tag update if selected, and something actually happaned
+ if ($ret && make_bool($_POST['update_id3'])) {
/* Set the rename information in the db */
foreach ($songs as $song) {
+ $flag = new Flag();
+ $flag->add($song->id,"song","retag","Renamed artist, retag");
$flag_qstring = "REPLACE INTO flagged " .
"SET type = 'setid3', song = '" . $song->id . "', date = '" . time() . "', user = '" . $GLOBALS['user']->username . "'";
mysql_query($flag_qstring, dbh());
}
} // end if they wanted to update
+
+ // show something other than a blank screen after this
+ if ($ret) {
+ show_confirmation (
+ "Renamed artist",
+ $artist->name . " is now known as " . $newname,
+ conf('web_path') . "/artists.php?action=show&artist=" . $newid
+ );
+ }
} // if we've got the needed variables
- /* Else we've got an error! */
+ /* Else we've got an error! But be lenient, and just show the form again */
else {
require (conf('prefix') . '/templates/show_rename_artist.inc.php');
}
diff --git a/docs/CHANGELOG b/docs/CHANGELOG
index 0808c354..0185645e 100755
--- a/docs/CHANGELOG
+++ b/docs/CHANGELOG
@@ -4,6 +4,8 @@
--------------------------------------------------------------------------
v.3.3.2-Beta2
+ - Added loose name compare and rename functions to help with sorting
+ similar artist names (Thx SpComb)
- Fixed a problem with not being able to add Albums to a playlist
(Thx eudaimon)
- Fixed a problem with browsing genres that would incorrectly put
diff --git a/lib/class/artist.class.php b/lib/class/artist.class.php
index 1b96b0aa..334472e3 100644
--- a/lib/class/artist.class.php
+++ b/lib/class/artist.class.php
@@ -205,7 +205,7 @@ class Artist {
@param $newname the artist's new name, either a new
artist will be created or songs added to existing
artist if name exists already
- @return the id of the new artist
+ @return the id of the new artist, or false if an error
*/
function rename($newname) {
@@ -221,11 +221,12 @@ class Artist {
/* check that it wasn't just whitespace that we were called to change */
if ($newid == $this->id) {
$GLOBALS['error']->add_error('artist_name',_("Error: Name Identical"));
- return $newid;
+ return false;
}
/* now we can just call merge */
- $this->merge($newid);
+ if (!$this->merge($newid))
+ return false;
//now return id
return $newid;
@@ -237,6 +238,7 @@ class Artist {
@discussion changes the artist id of all songs by this artist
to the given id and deletes self from db
@param $newid the new artist id that this artist's songs should have
+ @return the name of the new artist on success, false if error
*/
function merge($newid) {
@@ -249,15 +251,14 @@ class Artist {
}
// First check newid exists
- $check_exists_qstring = "SELECT name FROM artist WHERE id='" . sql_escape($newid) . "'";
+ $check_exists_qstring = "SELECT name FROM artist WHERE id='" . $newid . "'"; //no need to escape newid, it's numeric
$check_exists_query = mysql_query($check_exists_qstring, dbh());
- if ($check_exists_results = mysql_fetch_assoc($check_exists_query)) {
-
+ if ($check_exists_result = mysql_fetch_assoc($check_exists_query)) {
$NewName = $check_exists_result['name'];
// Now the query
- $sql = "UPDATE song SET artist='" . sql_escape($newid) . "' " .
+ $sql = "UPDATE song SET artist='" . $newid . "' " .
"WHERE artist='" . sql_escape($this->id) . "'";
$db_results = mysql_query($sql, dbh());
@@ -266,9 +267,11 @@ class Artist {
/* If we've done the merege we need to clean up */
$catalog->clean_artists();
$catalog->clean_albums();
+
+ return $NewName;
}
else {
- $GLOBALS['error']->add_error('general',"Error: Invalid Artist ID");
+ $GLOBALS['error']->add_error('general',"Error: No such artist to merge with");
return false;
}
} // merge
@@ -290,7 +293,125 @@ class Artist {
require (conf('prefix') . "/templates/show_artist.inc");
} // show_albums
-
+
+ /*!
+ @function get_similar_artists
+ @discussion returns an array of artist (id,name) arrays that are similar in name
+ All whitespace and special chars are ignored
+ @param extra arguments to normalize and compre, in that order
+ @return array of artist, each element is (id,name)
+ */
+ function get_similar_artists ($n_rep_uml,$n_filter,$n_ignore,$c_mode,$c_count_w,$c_percent_w,$c_distance_l) {
+ //strip out just about everything, including whitespace, numbers and weird chars, and then
+ //lowercase it
+ $name = $this->normalize_name($this->name,$n_rep_uml,$n_filter,$n_ignore);
+
+ //now for a bit of mysql query
+ $sql = "SELECT id, name FROM artist WHERE id != '" . sql_escape($this->id) . "'";
+ $query = mysql_query($sql, dbh());
+ //loop it
+ $similar_artists = array();
+ while ($r = mysql_fetch_assoc($query)) {
+ $artist_name = $this->normalize_name($r['name'],$n_rep_uml,$n_filter,$n_ignore);
+ //echo "'" . $r['name'] . "' => '" . $artist_name . "'<br/>\n";
+ if ($this->compare_loose($name,$artist_name,$c_mode,$c_count_w,$c_percent_w,$c_distance_l)) {
+ //echo "***MATCH***<br/>\n";
+ $similar_artists[] = array($r['id'],$r['name']);
+ }
+ }
+ return $similar_artists;
+ } // get_similar_artists
+
+
+ /*!
+ @function normalize_name
+ @param artist name to normalize
+ @param $replace_umlaut wether to replace umlauts and others with the plain letter, default true
+ @param $filter what to filter out, defulat /[^a-z ]/
+ @param $ignore terms to ignore, default /\s(the|an?)\s/ (name is padded with whitespace beforehand)
+ @returns the normalized version of the given artist name, containing only letters and single spaces
+ */
+ function normalize_name ($name,$replace_umlaut = NULL, $filter = NULL, $ignore = NULL) {
+ if (is_null($replace_umlaut)) $replace_umlaut = true;
+ if (is_null($filter)) $filter = "/[^a-z ]/";
+ if (is_null($ignore)) $ignore = "/\s(the|an?)\s/";
+ if ($replace_umlaut) {
+ //convert ümlauts, idea from http://php.net/manual/en/function.str-replace.php#50081
+ $umlauts = array("uml","acute","grave","cedil","ring","circ","tilde","lig","slash");
+ $name = str_replace($umlauts,"",htmlentities($name));
+ //now replace all &.; with .
+ $name = preg_replace("/&(.);/","\$1",$name);
+ //back to normal
+ $name = html_entity_decode($name);
+ }
+ //lowercase
+ $name = strtolower($name);
+ //now rip out all the special chars and spaces
+ $name = preg_replace($filter,"",$name);
+ //now certains terms can be dropped completely
+ //we have to add spaces on the sides though
+ $name = " " . $name . " ";
+ $name = preg_replace($ignore,"",$name);
+ //now single spaces
+ $name = preg_replace("/\s{2,}/"," ",$name);
+ //return
+ return trim($name);
+ } //normalize_name
+
+ /*!
+ @function compare_loose
+ @discussion percent and count are ORed together
+ @param $name1 artist name
+ @param $name2 artist name to compare against
+ @param $mode the type of matching to perform, one of line or word, default word
+ @param $countwords WORD MODE number of words that must be shared to match, 0 to disable, default 0
+ @param $percentwords WORD MODE percentage of words that must be shared to match, 0 to disable, default 50%
+ @param $distance LETTER MODE max levenshtein distance to pass as a match
+ @return true if given params are similar, false if not
+ */
+ function compare_loose ($name1,$name2,$mode = NULL,$countwords = NULL,$percentwords = NULL,$distance = NULL) {
+ if (is_null($mode)) $mode = "word";
+ if (is_null($countwords)) $countwords = 0;
+ if (is_null($percentwords)) $percentwords = 50;
+ if (is_null($distance)) $distance = 2;
+
+ //echo "Compare '$name1' vs. '$name2'<br/>\n";
+
+ $modes = array("line" => 0,"word" => 0,"letter" => 0);
+ $mode = (isset($modes[$mode]) ? $mode : "word");
+ switch ($mode) {
+ case "line":
+ //this is still relevant because of the normalize
+ return $name1 == $name2;
+ break;
+ case "word":
+ //echo " COMPARE: Word mode<br/>\n";
+ //first, count the number of terms in name1, and then the number that also appear in name2
+ $words = explode(" ",$name1);
+ $num_words = count($words);
+ $num_words_shared = 0;
+ foreach ($words as $word) {
+ //echo " Looking for word '$word'... ";
+ if (strpos($name2,$word) !== false) {
+ //echo "MATCHED";
+ $num_words_shared++;
+ } else {
+ //echo " Nope";
+ }
+ //echo "<br/>\n";
+ }
+ //now make the descision
+ return (
+ ($countwords > 0 && $num_words_shared >= $countwords) ||
+ ($percentwords > 0 && $num_words_shared > 0 && $num_words_shared/$num_words >= $percentwords/100)
+ );
+ break;
+ case "letter":
+ //simple
+ return levenshtein($name1,$name2) <= $distance;
+ break;
+ }
+ } //compare_loose
} //end of artist class
diff --git a/lib/duplicates.php b/lib/duplicates.php
index 75ca2a22..1d03a3da 100644
--- a/lib/duplicates.php
+++ b/lib/duplicates.php
@@ -42,8 +42,6 @@ function get_duplicate_songs($search_type) {
$sql = $sql." HAVING count(title) > 1";
$sql = $sql." ORDER BY ctitle";
- //echo $sql."<BR>";
-
$result = mysql_query($sql, dbh());
$arr = array();
diff --git a/lib/ui.lib.php b/lib/ui.lib.php
index 44a67710..128ba533 100644
--- a/lib/ui.lib.php
+++ b/lib/ui.lib.php
@@ -880,7 +880,7 @@ function show_artist_pulldown ($artist_id,$select_name='artist') {
$artist->get_count();
if ( $artist_id == $r['id'] ) {
- echo "\t<option value=\"" . $artist->id . "\" selected=\"selected\">". scrub_out($artist->name) . " (" . $artist->songs . ")</option>\n";
+ echo "\t<option value=\"" . $artist->id . "\" selected=\"selected\">". scrub_out($artist->name) . "</option>\n";
}
else {
echo "\t<option value=\"" . $artist->id . "\">". scrub_out($artist->name) ."</option>\n";
diff --git a/templates/show_artist_box.inc.php b/templates/show_artist_box.inc.php
index 75026d7e..8c9779f4 100644
--- a/templates/show_artist_box.inc.php
+++ b/templates/show_artist_box.inc.php
@@ -33,6 +33,7 @@ $web_path = conf('web_path');
<?php if ($user->has_access('100')) { ?>
<li><a href="<?php echo $web_path; ?>/artists.php?action=update_from_tags&amp;artist=<?php echo $artist_id; ?>"><?php echo _("Update from tags"); ?></a></li>
<li><a href="<?php echo $web_path; ?>/artists.php?action=show_rename&amp;artist=<?php echo $artist_id; ?>"><?php echo _("Rename Artist"); ?></a></li>
+ <li><a href="<?php echo $web_path; ?>/artists.php?action=show_similar&amp;artist=<?php echo $artist_id; ?>"><?php echo _("Find duplicate artists"); ?></a></li>
<?php } ?>
</ul>
</td>
diff --git a/templates/show_rename_artist.inc.php b/templates/show_rename_artist.inc.php
index 929c54c2..72f707ff 100644
--- a/templates/show_rename_artist.inc.php
+++ b/templates/show_rename_artist.inc.php
@@ -45,7 +45,7 @@ function insert()
</td>
</tr>
<tr>
- <td><input type="checkbox" name="update_id3" value="1" />&nbsp; <?php echo _("Update id3 tags"); ?></td>
+ <td><input type="checkbox" name="update_id3" value="yes" />&nbsp; <?php echo _("Update id3 tags"); ?></td>
</tr>
<tr>
<td>
diff --git a/templates/show_similar_artists.inc b/templates/show_similar_artists.inc
new file mode 100644
index 00000000..25a9f6d2
--- /dev/null
+++ b/templates/show_similar_artists.inc
@@ -0,0 +1,159 @@
+<?php
+/*
+
+ Copyright (c) 2001 - 2006 Ampache.org
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+$web_path = conf('web_path');
+?>
+<form name="artists" method="post" enctype="multipart/form-data" action="<?php echo $web_path; ?>/artists.php?action=rename_similar&artist=<?php echo $artist_id;?>" style="Display:inline;">
+ <h1>Similar Artists</h1>
+ <h3>Please check the artists you want to merge with the current one (<span style='text-decoration: underline;'><?php echo $artist_name;?></span>)</h3>
+ <table class="border" cellspacing="0" cellpadding="0" border="0">
+ <tr class="table-header">
+ <th>&nbsp;&nbsp;Select</th>
+ <th><?php echo _("Artist"); ?></th>
+ </tr>
+<?php
+if (count($similar_artists) > 0) {
+ $show = true;
+ foreach ($similar_artists as $artist_array) {
+?>
+ <tr class="<?php echo flip_class(); ?>">
+ <td align="center">
+ <input type="checkbox" name="artists[]" value="<?php echo $artist_array[0]; ?>" />
+ </td>
+ <td>
+ <a href="<?php echo $web_path; ?>/artists.php?action=show&amp;artist=<?php echo $artist_array[0]; ?>" title="<?php echo htmlspecialchars($artist_array[1]); ?>" <?php echo $text_class; ?>><?php echo htmlspecialchars($artist_array[1]); ?></a>
+ </td>
+ </tr>
+<?php
+ }// foreach loop
+} else { // no similar artists
+ $show = false;
+?>
+ <tr class="<?php echo flip_class(); ?>">
+ <td align="center">
+ &nbsp;
+ </td>
+ <td>
+ No Similar Artists found
+ </td>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <td align="center">
+ &nbsp;
+ </td>
+ <td>
+ <input class="button" type="button" name="action" value="<?php echo _("Back"); ?>" onclick="window.location.href = '<?php echo $web_path; ?>/artists.php?action=show&artist=<?php echo $artist_id;?>';" />
+ </td>
+ </tr>
+<?php
+}
+?>
+<?php
+if ($show) {
+?>
+<tr align="left" class="<?php echo flip_class(); ?>">
+ <td colspan='2'>
+ <input class="button" type="button" name="action" value="<?php echo _("Rename selected"); ?>" onclick="document.artists.submit();" />
+ <input class="button" type="button" name="action" value="<?php echo _("Cancel"); ?>" onclick="window.location.href = '<?php echo $web_path; ?>/artists.php?action=show&artist=<?php echo $artist_id;?>';" />
+ </td>
+</tr>
+<?php
+}
+?>
+</table>
+</form>
+<form name='advanced' action='<?php echo $web_path; ?>/artists.php?action=show_similar&artist=<?php echo $artist_id; ?>' method='POST'>
+<table class="border" cellspacing="0" cellpadding="0" border="0" style='margin-left: 10px; margin-top: 20px;'>
+<!--Advanced-->
+ <tr class="table-header">
+ <th colspan='2'>Advanced options</th>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <th colspan='2' style='text-align: left;'>Normalize options</th>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <td colspan='2'>
+ <label for='n_rep_uml' style='display: inline;'>Replace ümlauts and áccents with normal letters</label>
+ <input type='checkbox' name='n_rep_uml' id='n_rep_uml' value='yes' style='display: inline;' <?php echo (is_null($_POST['n_rep_uml']) || make_bool($_POST['n_rep_uml']) ? "checked='checked'" : ''); ?>/>
+ <br/>
+ <label for='n_filter' style='display: inline;'>filter out (regexp)</label>
+ <input type='text' name='n_filter' id='n_filter' value='<?php echo (is_null($_POST['n_filter']) ? "/[^a-z ]/" : $_POST['n_filter']); ?>' style='display: inline;'/>
+ <a href='javascript:default_filter();'>default</a>
+ <br/>
+ <label for='n_ignore' style='display: inline;'>ignore (regexp)</label>
+ <input type='text' name='n_ignore' id='n_ignore' value='<?php echo (is_null($_POST['n_ignore']) ? "/\s(the|an?)\s/" : $_POST['n_ignore']); ?>' style='display: inline;'/>
+ <a href='javascript:default_ignore();'>default</a>
+ <br/>
+ </td>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <th colspan='2' style='text-align: left;'>Compare options</th>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <td>
+ <label for='c_mode' style='display: inline;'>Line mode</label>
+ <input type='radio' name='c_mode' id='c_mode' value='line' style='display: inline;' <?php echo (is_null($_POST['c_mode']) || $_POST['c_mode'] == "line" ? "checked='checked'" : ''); ?> />
+ </td>
+ <td>
+ &lt;No Options&gt;
+ </td>
+ </tr>
+
+ <tr class="<?php echo flip_class(); ?>">
+ <td>
+ <label for='c_mode' style='display: inline;'>Word mode</label>
+ <input type='radio' name='c_mode' id='c_mode' value='word' style='display: inline;' <?php echo (is_null($_POST['c_mode']) || $_POST['c_mode'] == "word" ? "checked='checked'" : ''); ?> />
+ </td>
+ <td>
+ <label for='c_count_w' style='display: inline;'># words to match (0=disable)</label>
+ <input type='text' name='c_count_w' id='c_count_w' value='<?php echo (is_null($_POST['c_count_w']) ? "0" : $_POST['c_count_w']); ?>' style='display: inline;' size='2'/>
+ <br/>OR<br/>
+ <label for='c_percent_w' style='display: inline;'>% words to match (0=disable)</label>
+ <input type='text' name='c_percent_w' id='c_percent_w' value='<?php echo (is_null($_POST['c_percent_w']) ? "50" : $_POST['c_percent_w']); ?>' style='display: inline;' size='4'/>%
+ <br/>
+ </td>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <td>
+ <label for='c_mode' style='display: inline;'>Letter mode</label>
+ <input type='radio' name='c_mode' id='c_mode' value='letter' style='display: inline;' <?php echo ($_POST['c_mode'] == "letter" ? "checked='checked'" : ''); ?> />
+ </td>
+ <td>
+ <label for='c_distance_l' style='display: inline;'>Max (levenshtein) difference, the larger the looser</label>
+ <input type='text' name='c_distance_l' id='c_distance_l' value='<?php echo (is_null($_POST['c_distance_l']) ? "2" : $_POST['c_distance_l']); ?>' style='display: inline;' size='2'/>
+ </td>
+ </tr>
+ <tr class="<?php echo flip_class(); ?>">
+ <td colspan='2'>
+ <input class="button" type="button" name="action" value="<?php echo _("Search Again"); ?>" onclick="document.advanced.submit();" />
+ </td>
+ </tr>
+
+</table>
+</form>
+<script language='javascript'>
+ function default_filter() {
+ document.getElementById('n_filter').value = "/[^a-z ]/";
+ }
+ function default_ignore() {
+ document.getElementById('n_ignore').value = "/\s(the|an?)\s/";
+ }
+</script> \ No newline at end of file