portion & compare it to dottedName.
var pagename = pages[i].substring(0, pages[i].length-2);
if (pagename == dottedName.substring(0,pagename.length)) {
// We've found a page that matches `dottedName`;
// construct its URL, using leftover `dottedName`
// content to form an anchor.
var pagetype = pages[i].charAt(pages[i].length-1);
var url = pagename + ((pagetype=="m")?"-module.html":
"-class.html");
if (dottedName.length > pagename.length)
url += "#" + dottedName.substring(pagename.length+1,
dottedName.length);
return url;
}
}
}
xappy-0.5/docs/api/frames.html 0000644 0001750 0001750 00000001077 11005555242 016201 0 ustar richard richard
xappy
xappy-0.5/docs/api/help.html 0000644 0001750 0001750 00000025222 11005555242 015652 0 ustar richard richard
Help
API Documentation
This document contains the API (Application Programming Interface)
documentation for xappy. Documentation for the Python
objects defined by the project is divided into separate pages for each
package, module, and class. The API documentation also includes two
pages containing information about the project as a whole: a trees
page, and an index page.
Object Documentation
Each Package Documentation page contains:
A description of the package.
A list of the modules and sub-packages contained by the
package.
A summary of the classes defined by the package.
A summary of the functions defined by the package.
A summary of the variables defined by the package.
A detailed description of each function defined by the
package.
A detailed description of each variable defined by the
package.
Each Module Documentation page contains:
A description of the module.
A summary of the classes defined by the module.
A summary of the functions defined by the module.
A summary of the variables defined by the module.
A detailed description of each function defined by the
module.
A detailed description of each variable defined by the
module.
Each Class Documentation page contains:
A class inheritance diagram.
A list of known subclasses.
A description of the class.
A summary of the methods defined by the class.
A summary of the instance variables defined by the class.
A summary of the class (static) variables defined by the
class.
A detailed description of each method defined by the
class.
A detailed description of each instance variable defined by the
class.
A detailed description of each class (static) variable defined
by the class.
Project Documentation
The Trees page contains the module and class hierarchies:
The module hierarchy lists every package and module, with
modules grouped into packages. At the top level, and within each
package, modules and sub-packages are listed alphabetically.
The class hierarchy lists every class, grouped by base
class. If a class has more than one base class, then it will be
listed under each base class. At the top level, and under each base
class, classes are listed alphabetically.
The Index page contains indices of terms and
identifiers:
The term index lists every term indexed by any object's
documentation. For each term, the index provides links to each
place where the term is indexed.
The identifier index lists the (short) name of every package,
module, class, method, function, variable, and parameter. For each
identifier, the index provides a short description, and a link to
its documentation.
The Table of Contents
The table of contents occupies the two frames on the left side of
the window. The upper-left frame displays the project
contents , and the lower-left frame displays the module
contents :
Project Contents ...
API Documentation Frame
Module Contents ...
The project contents frame contains a list of all packages
and modules that are defined by the project. Clicking on an entry
will display its contents in the module contents frame. Clicking on a
special entry, labeled "Everything," will display the contents of
the entire project.
The module contents frame contains a list of every
submodule, class, type, exception, function, and variable defined by a
module or package. Clicking on an entry will display its
documentation in the API documentation frame. Clicking on the name of
the module, at the top of the frame, will display the documentation
for the module itself.
The "frames " and "no frames " buttons below the top
navigation bar can be used to control whether the table of contents is
displayed or not.
The Navigation Bar
A navigation bar is located at the top and bottom of every page.
It indicates what type of page you are currently viewing, and allows
you to go to related pages. The following table describes the labels
on the navigation bar. Note that not some labels (such as
[Parent]) are not displayed on all pages.
Label
Highlighted when...
Links to...
[Parent]
(never highlighted)
the parent of the current package
[Package]
viewing a package
the package containing the current object
[Module]
viewing a module
the module containing the current object
[Class]
viewing a class
the class containing the current object
[Trees]
viewing the trees page
the trees page
[Index]
viewing the index page
the index page
[Help]
viewing the help page
the help page
The "show private " and "hide private " buttons below
the top navigation bar can be used to control whether documentation
for private objects is displayed. Private objects are usually defined
as objects whose (short) names begin with a single underscore, but do
not end with an underscore. For example, "_x
",
"__pprint
", and "epydoc.epytext._tokenize
"
are private objects; but "re.sub
",
"__init__
", and "type_
" are not. However,
if a module defines the "__all__
" variable, then its
contents are used to decide which objects are private.
A timestamp below the bottom navigation bar indicates when each
page was last updated.
xappy-0.5/docs/api/identifier-index.html 0000644 0001750 0001750 00000175421 11005555242 020160 0 ustar richard richard
Identifier Index
xappy-0.5/docs/api/index.html 0000644 0001750 0001750 00000001077 11005555243 016034 0 ustar richard richard
xappy
xappy-0.5/docs/api/module-tree.html 0000644 0001750 0001750 00000014315 11005555242 017145 0 ustar richard richard
Module Hierarchy
[ Module Hierarchy
| Class Hierarchy ]
Module Hierarchy
xappy-0.5/docs/api/redirect.html 0000644 0001750 0001750 00000004414 11005555243 016524 0 ustar richard richard Epydoc Redirect Page
Epydoc Auto-redirect page
When javascript is enabled, this page will redirect URLs of
the form redirect.html#dotted.name to the
documentation for the object with the given fully-qualified
dotted name.
xappy-0.5/docs/api/toc-everything.html 0000644 0001750 0001750 00000012324 11005555242 017670 0 ustar richard richard
Everything
Everything
All Classes
xappy.datastructures.Field xappy.datastructures.ProcessedDocument xappy.datastructures.UnprocessedDocument xappy.errors.IndexerError xappy.errors.SearchEngineError xappy.errors.SearchError xappy.errors.XapianError xappy.fieldactions.ActionContext xappy.fieldactions.FieldActions xappy.fieldactions.SortableMarshaller xappy.fieldmappings.FieldMappings xappy.highlight.Highlighter xappy.indexerconnection.FacetQueryTypeIter xappy.indexerconnection.IndexerConnection xappy.indexerconnection.PrefixedTermIter xappy.indexerconnection.SynonymIter xappy.replaylog.LoggedProxy xappy.replaylog.LoggedProxyMethod xappy.replaylog.NotifyingDeleteObject xappy.replaylog.ReplayLog xappy.schema.Schema xappy.searchconnection.SearchConnection xappy.searchconnection.SearchConnection.ExpandDecider xappy.searchconnection.SearchResult xappy.searchconnection.SearchResultIter xappy.searchconnection.SearchResults All Functions
xappy.marshall.date_to_string xappy.marshall.float_to_string xappy.memutils.get_physical_memory xappy.parsedate.date_from_string xappy.replaylog.log xappy.replaylog.set_replay_path All Variables
xappy.highlight.__test__ xappy.parsedate.yyyy_mm_dd_re xappy.parsedate.yyyymmdd_re
xappy-0.5/docs/api/toc-xappy-module.html 0000644 0001750 0001750 00000001476 11005555242 020136 0 ustar richard richard
xappy
Module xappy
xappy-0.5/docs/api/toc-xappy._checkxapian-module.html 0000644 0001750 0001750 00000001555 11005555242 022550 0 ustar richard richard
_checkxapian
Module _checkxapian
Variables
xappy-0.5/docs/api/toc-xappy.datastructures-module.html 0000644 0001750 0001750 00000002267 11005555242 023211 0 ustar richard richard
datastructures
Module datastructures
Classes
Field ProcessedDocument UnprocessedDocument
xappy-0.5/docs/api/toc-xappy.errors-module.html 0000644 0001750 0001750 00000002355 11005555242 021446 0 ustar richard richard
errors
Module errors
Classes
IndexerError SearchEngineError SearchError XapianError
xappy-0.5/docs/api/toc-xappy.fieldactions-module.html 0000644 0001750 0001750 00000002261 11005555242 022572 0 ustar richard richard
fieldactions
Module fieldactions
Classes
ActionContext FieldActions SortableMarshaller
xappy-0.5/docs/api/toc-xappy.fieldmappings-module.html 0000644 0001750 0001750 00000001730 11005555242 022750 0 ustar richard richard
fieldmappings
Module fieldmappings
Classes
FieldMappings
xappy-0.5/docs/api/toc-xappy.highlight-module.html 0000644 0001750 0001750 00000002107 11005555242 022074 0 ustar richard richard
highlight
Module highlight
Classes
Highlighter Variables
__test__
xappy-0.5/docs/api/toc-xappy.indexerconnection-module.html 0000644 0001750 0001750 00000002505 11005555242 023645 0 ustar richard richard
indexerconnection
Module indexerconnection
Classes
FacetQueryTypeIter IndexerConnection PrefixedTermIter SynonymIter
xappy-0.5/docs/api/toc-xappy.marshall-module.html 0000644 0001750 0001750 00000002071 11005555242 021730 0 ustar richard richard
marshall
Module marshall
Functions
date_to_string float_to_string
xappy-0.5/docs/api/toc-xappy.memutils-module.html 0000644 0001750 0001750 00000001730 11005555242 021765 0 ustar richard richard
memutils
Module memutils
Functions
get_physical_memory
xappy-0.5/docs/api/toc-xappy.parsedate-module.html 0000644 0001750 0001750 00000002302 11005555242 022072 0 ustar richard richard
parsedate
Module parsedate
Functions
date_from_string Variables
yyyy_mm_dd_re yyyymmdd_re
xappy-0.5/docs/api/toc-xappy.replaylog-module.html 0000644 0001750 0001750 00000002756 11005555242 022135 0 ustar richard richard
replaylog
Module replaylog
Classes
LoggedProxy LoggedProxyMethod NotifyingDeleteObject ReplayLog Functions
log set_replay_path
xappy-0.5/docs/api/toc-xappy.schema-module.html 0000644 0001750 0001750 00000001665 11005555242 021375 0 ustar richard richard
schema
Module schema
Classes
Schema
xappy-0.5/docs/api/toc-xappy.searchconnection-module.html 0000644 0001750 0001750 00000002465 11005555242 023461 0 ustar richard richard
searchconnection
Module searchconnection
Classes
SearchConnection SearchResult SearchResultIter SearchResults
xappy-0.5/docs/api/toc.html 0000644 0001750 0001750 00000006550 11005555242 015512 0 ustar richard richard
Table of Contents
Table of Contents
Everything
Modules
xappy xappy.datastructures xappy.errors xappy.fieldactions xappy.fieldmappings xappy.highlight xappy.indexerconnection xappy.marshall xappy.memutils xappy.parsedate xappy.replaylog xappy.schema xappy.searchconnection
xappy-0.5/docs/api/xappy-module.html 0000644 0001750 0001750 00000015604 11005555242 017351 0 ustar richard richard
xappy
Package xappy source code
Xappy.
See the accompanying documentation for details. In particular, there should be
an accompanying file "introduction.html" (or "introduction.rst") which gives
details of how to use the xappy package.
xappy-0.5/docs/api/xappy-pysrc.html 0000644 0001750 0001750 00000031335 11005555243 017224 0 ustar richard richard
xappy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Xappy.
19
20 See the accompanying documentation for details. In particular, there should be
21 an accompanying file "introduction.html" (or "introduction.rst") which gives
22 details of how to use the xappy package.
23
24 """
25 __docformat__ = "restructuredtext en"
26
27 __version__ = '0.5'
28
29 import _checkxapian
30 from datastructures import Field , UnprocessedDocument , ProcessedDocument
31 from errors import *
32 from fieldactions import FieldActions
33 from indexerconnection import IndexerConnection
34 from searchconnection import SearchConnection
35 from replaylog import set_replay_path
36
xappy-0.5/docs/api/xappy._checkxapian-module.html 0000644 0001750 0001750 00000012643 11005555242 021765 0 ustar richard richard
xappy._checkxapian
Module _checkxapian source code
_checkxapian.py: Check the version of xapian used.
Raises an ImportError on import if the version used is too old to be used at
all.
min_xapian_version = (
1,
0,
6)
missing_features = {
}
versions = (
1,
0,
6)
xappy-0.5/docs/api/xappy._checkxapian-pysrc.html 0000644 0001750 0001750 00000033153 11005555243 021640 0 ustar richard richard
xappy._checkxapian
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 r"""_checkxapian.py: Check the version of xapian used.
17
18 Raises an ImportError on import if the version used is too old to be used at
19 all.
20
21 """
22 __docformat__ = "restructuredtext en"
23
24
25 min_xapian_version = ( 1 , 0 , 6 )
26
27
28
29 missing_features = { }
30
31 import xapian
32
33 versions = xapian . major_version ( ) , xapian . minor_version ( ) , xapian . revision ( )
34
35
36 if versions < min_xapian_version :
37 raise ImportError ( """
38 Xapian Python bindings installed, but need at least version %d.%d.%d - got %s
39 """ . strip ( ) % tuple ( list ( min_xapian_version ) + [ xapian . version_string ( ) ] ) )
40
41 if not hasattr ( xapian , 'TermCountMatchSpy' ) :
42 missing_features [ 'tags' ] = 1
43 if not hasattr ( xapian , 'CategorySelectMatchSpy' ) :
44 missing_features [ 'facets' ] = 1
45
xappy-0.5/docs/api/xappy.datastructures-module.html 0000644 0001750 0001750 00000012060 11005555242 022416 0 ustar richard richard
xappy.datastructures
Module datastructures source code
datastructures.py: Datastructures for search engine core.
xappy-0.5/docs/api/xappy.datastructures-pysrc.html 0000644 0001750 0001750 00000207047 11005555243 022305 0 ustar richard richard
xappy.datastructures
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""datastructures.py: Datastructures for search engine core.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import errors
24 from replaylog import log
25 import xapian
26 import cPickle
27
29
30
31 __slots__ = 'name' , 'value'
32
36
38 return 'Field(%r, %r)' % ( self . name , self . value )
39
41 """A unprocessed document to be passed to the indexer.
42
43 This represents an item to be processed and stored in the search engine.
44 Each document will be processed by the indexer to generate a
45 ProcessedDocument, which can then be stored in the search engine index.
46
47 Note that some information in an UnprocessedDocument will not be
48 represented in the ProcessedDocument: therefore, it is not possible to
49 retrieve an UnprocessedDocument from the search engine index.
50
51 An unprocessed document is a simple container with two attributes:
52
53 - `fields` is a list of Field objects, or an iterator returning Field
54 objects.
55 - `id` is a string holding a unique identifier for the document (or
56 None to get the database to allocate a unique identifier automatically
57 when the document is added).
58
59 """
60
61 __slots__ = 'id' , 'fields' ,
62 - def __init__ ( self , id = None , fields = None ) :
68
70 return 'UnprocessedDocument(%r, %r)' % ( self . id , self . fields )
71
73 """A processed document, as stored in the index.
74
75 This represents an item which is ready to be stored in the search engine,
76 or which has been returned by the search engine.
77
78 """
79
80 __slots__ = '_doc' , '_fieldmappings' , '_data' ,
81 - def __init__ ( self , fieldmappings , xapdoc = None ) :
82 """Create a ProcessedDocument.
83
84 `fieldmappings` is the configuration from a database connection used lookup
85 the configuration to use to store each field.
86
87 If supplied, `xapdoc` is a Xapian document to store in the processed
88 document. Otherwise, a new Xapian document is created.
89
90 """
91 if xapdoc is None :
92 self . _doc = log ( xapian . Document )
93 else :
94 self . _doc = xapdoc
95 self . _fieldmappings = fieldmappings
96 self . _data = None
97
98 - def add_term ( self , field , term , wdfinc = 1 , positions = None ) :
99 """Add a term to the document.
100
101 Terms are the main unit of information used for performing searches.
102
103 - `field` is the field to add the term to.
104 - `term` is the term to add.
105 - `wdfinc` is the value to increase the within-document-frequency
106 measure for the term by.
107 - `positions` is the positional information to add for the term.
108 This may be None to indicate that there is no positional information,
109 or may be an integer to specify one position, or may be a sequence of
110 integers to specify several positions. (Note that the wdf is not
111 increased automatically for each position: if you add a term at 7
112 positions, and the wdfinc value is 2, the total wdf for the term will
113 only be increased by 2, not by 14.)
114
115 """
116 prefix = self . _fieldmappings . get_prefix ( field )
117 if len ( term ) > 0 :
118
119
120
121 if ord ( term [ 0 ] ) >= ord ( 'A' ) and ord ( term [ 0 ] ) <= ord ( 'Z' ) :
122 prefix = prefix + ':'
123
124
125
126
127
128
129
130
131
132
133
134
135
136 if len ( prefix + term ) > 220 :
137 raise errors . IndexerError ( "Field %r is too long: maximum length "
138 "220 - was %d (%r)" %
139 ( field , len ( prefix + term ) ,
140 prefix + term ) )
141
142 if positions is None :
143 self . _doc . add_term ( prefix + term , wdfinc )
144 elif isinstance ( positions , int ) :
145 self . _doc . add_posting ( prefix + term , positions , wdfinc )
146 else :
147 self . _doc . add_term ( prefix + term , wdfinc )
148 for pos in positions :
149 self . _doc . add_posting ( prefix + term , pos , 0 )
150
151 - def add_value ( self , field , value , purpose = '' ) :
152 """Add a value to the document.
153
154 Values are additional units of information used when performing
155 searches. Note that values are _not_ intended to be used to store
156 information for display in the search results - use the document data
157 for that. The intention is that as little information as possible is
158 stored in values, so that they can be accessed as quickly as possible
159 during the search operation.
160
161 Unlike terms, each document may have at most one value in each field
162 (whereas there may be an arbitrary number of terms in a given field).
163 If an attempt to add multiple values to a single field is made, only
164 the last value added will be stored.
165
166 """
167 slot = self . _fieldmappings . get_slot ( field , purpose )
168 self . _doc . add_value ( slot , value )
169
171 """Get a value from the document.
172
173 """
174 slot = self . _fieldmappings . get_slot ( field , purpose )
175 return self . _doc . get_value ( slot )
176
178 """Prepare the document for adding to a xapian database.
179
180 This updates the internal xapian document with any changes which have
181 been made, and then returns it.
182
183 """
184 if self . _data is not None :
185 self . _doc . set_data ( cPickle . dumps ( self . _data , 2 ) )
186 self . _data = None
187 return self . _doc
188
190 if self . _data is None :
191 rawdata = self . _doc . get_data ( )
192 if rawdata == '' :
193 self . _data = { }
194 else :
195 self . _data = cPickle . loads ( rawdata )
196 return self . _data
198 if not isinstance ( data , dict ) :
199 raise TypeError ( "Cannot set data to any type other than a dict" )
200 self . _data = data
201 data = property ( _get_data , _set_data , doc =
202 """The data stored in this processed document.
203
204 This data is a dictionary of entries, where the key is a fieldname, and the
205 value is a list of strings.
206
207 """ )
208
210 tl = self . _doc . termlist ( )
211 try :
212 term = tl . skip_to ( 'Q' ) . term
213 if len ( term ) == 0 or term [ 0 ] != 'Q' :
214 return None
215 except StopIteration :
216 return None
217 return term [ 1 : ]
219 tl = self . _doc . termlist ( )
220 try :
221 term = tl . skip_to ( 'Q' ) . term
222 except StopIteration :
223 term = ''
224 if len ( term ) != 0 and term [ 0 ] == 'Q' :
225 self . _doc . remove_term ( term )
226 if id is not None :
227 self . _doc . add_term ( 'Q' + id , 0 )
228 id = property ( _get_id , _set_id , doc =
229 """The unique ID for this document.
230
231 """ )
232
234 return '<ProcessedDocument(%r)>' % ( self . id )
235
236 if __name__ == '__main__' :
237 import doctest , sys
238 doctest . testmod ( sys . modules [ __name__ ] )
239
xappy-0.5/docs/api/xappy.datastructures.Field-class.html 0000644 0001750 0001750 00000022315 11005555242 023264 0 ustar richard richard
xappy.datastructures.Field
Class Field source code
object --+
|
Field
__init__ (self ,
name ,
value )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
name
value
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
repr(x)
Overrides:
object.__repr__
(inherited documentation)
xappy-0.5/docs/api/xappy.datastructures.ProcessedDocument-class.html 0000644 0001750 0001750 00000047765 11005555242 025707 0 ustar richard richard
xappy.datastructures.ProcessedDocument
Class ProcessedDocument source code
object --+
|
ProcessedDocument
Known Subclasses:
searchconnection.SearchResult
A processed document, as stored in the index.
This represents an item which is ready to be stored in the search engine,
or which has been returned by the search engine.
get_value (self ,
field ,
purpose ='
'
)
Get a value from the document.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
data
The data stored in this processed document.
id
The unique ID for this document.
Inherited from object
:
__class__
__init__ (self ,
fieldmappings ,
xapdoc =None )
(Constructor)
source code
Create a ProcessedDocument.
fieldmappings is the configuration from a database connection used lookup
the configuration to use to store each field.
If supplied, xapdoc
is a Xapian document to store in the processed
document. Otherwise, a new Xapian document is created.
Overrides:
object.__init__
add_term (self ,
field ,
term ,
wdfinc =1 ,
positions =None )
source code
Add a term to the document.
Terms are the main unit of information used for performing searches.
field
is the field to add the term to.
term
is the term to add.
wdfinc
is the value to increase the within-document-frequency
measure for the term by.
positions
is the positional information to add for the term.
This may be None to indicate that there is no positional information,
or may be an integer to specify one position, or may be a sequence of
integers to specify several positions. (Note that the wdf is not
increased automatically for each position: if you add a term at 7
positions, and the wdfinc value is 2, the total wdf for the term will
only be increased by 2, not by 14.)
Add a value to the document.
Values are additional units of information used when performing
searches. Note that values are _not_ intended to be used to store
information for display in the search results - use the document data
for that. The intention is that as little information as possible is
stored in values, so that they can be accessed as quickly as possible
during the search operation.
Unlike terms, each document may have at most one value in each field
(whereas there may be an arbitrary number of terms in a given field).
If an attempt to add multiple values to a single field is made, only
the last value added will be stored.
Prepare the document for adding to a xapian database.
This updates the internal xapian document with any changes which have
been made, and then returns it.
repr(x)
Overrides:
object.__repr__
(inherited documentation)
xappy-0.5/docs/api/xappy.datastructures.UnprocessedDocument-class.html 0000644 0001750 0001750 00000025057 11005555242 026240 0 ustar richard richard
xappy.datastructures.UnprocessedDocument
Class UnprocessedDocument source code
object --+
|
UnprocessedDocument
A unprocessed document to be passed to the indexer.
This represents an item to be processed and stored in the search engine.
Each document will be processed by the indexer to generate a
ProcessedDocument, which can then be stored in the search engine index.
Note that some information in an UnprocessedDocument will not be
represented in the ProcessedDocument: therefore, it is not possible to
retrieve an UnprocessedDocument from the search engine index.
An unprocessed document is a simple container with two attributes:
fields is a list of Field objects, or an iterator returning Field
objects.
id is a string holding a unique identifier for the document (or
None to get the database to allocate a unique identifier automatically
when the document is added).
__init__ (self ,
id =None ,
fields =None )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
fields
id
Inherited from object
:
__class__
__init__ (self ,
id =None ,
fields =None )
(Constructor)
source code
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
repr(x)
Overrides:
object.__repr__
(inherited documentation)
xappy-0.5/docs/api/xappy.errors-module.html 0000644 0001750 0001750 00000012564 11005555242 020666 0 ustar richard richard
xappy.errors
Module errors source code
errors.py: Exceptions for the search engine core.
SearchEngineError
Base class for exceptions thrown by the search engine.
IndexerError
Class used to report errors relating to the indexing API.
SearchError
Class used to report errors relating to the search API.
XapianError
Base class for exceptions thrown by the xapian.
xappy-0.5/docs/api/xappy.errors-pysrc.html 0000644 0001750 0001750 00000050175 11005555243 020542 0 ustar richard richard
xappy.errors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""errors.py: Exceptions for the search engine core.
19
20 """
21 __docformat__ = "restructuredtext en"
22
24 r"""Base class for exceptions thrown by the search engine.
25
26 Any errors generated by xappy itself, or by xapian, will be instances of
27 this class or its subclasses.
28
29 """
30
32 r"""Class used to report errors relating to the indexing API.
33
34 """
35
37 r"""Class used to report errors relating to the search API.
38
39 """
40
41
43 r"""Base class for exceptions thrown by the xapian.
44
45 Any errors generated by xapian will be instances of this class or its
46 subclasses.
47
48 """
49
51 """Add new base classes for all the xapian exceptions.
52
53 """
54 import xapian
55 for name in (
56 'AssertionError' ,
57 'DatabaseCorruptError' ,
58 'DatabaseCreateError' ,
59 'DatabaseError' ,
60 'DatabaseLockError' ,
61 'DatabaseModifiedError' ,
62 'DatabaseOpeningError' ,
63 'DatabaseVersionError' ,
64 'DocNotFoundError' ,
65
66
67
68
69
70 'FeatureUnavailableError' ,
71 'InternalError' ,
72 'InvalidArgumentError' ,
73 'InvalidOperationError' ,
74 'LogicError' ,
75 'NetworkError' ,
76 'NetworkTimeoutError' ,
77 'QueryParserError' ,
78 'RangeError' ,
79 'RuntimeError' ,
80 'UnimplementedError' ,
81 ) :
82 xapian_exception = getattr ( xapian , name , None )
83 if xapian_exception is not None :
84 xapian_exception . __bases__ += ( XapianError , )
85 globals ( ) [ 'Xapian' + name ] = xapian_exception
86
87 _rebase_xapian_exceptions ( )
88
xappy-0.5/docs/api/xappy.errors.IndexerError-class.html 0000644 0001750 0001750 00000014221 11005555242 023105 0 ustar richard richard
xappy.errors.IndexerError
Class IndexerError source code
object --+
|
exceptions.BaseException --+
|
exceptions.Exception --+
|
SearchEngineError --+
|
IndexerError
Class used to report errors relating to the indexing API.
Inherited from exceptions.Exception
:
__init__
,
__new__
Inherited from exceptions.BaseException
:
__delattr__
,
__getattribute__
,
__getitem__
,
__getslice__
,
__reduce__
,
__repr__
,
__setattr__
,
__setstate__
,
__str__
Inherited from object
:
__hash__
,
__reduce_ex__
Inherited from exceptions.BaseException
:
args
,
message
Inherited from object
:
__class__
xappy-0.5/docs/api/xappy.errors.SearchEngineError-class.html 0000644 0001750 0001750 00000014575 11005555242 024056 0 ustar richard richard
xappy.errors.SearchEngineError
Class SearchEngineError source code
object --+
|
exceptions.BaseException --+
|
exceptions.Exception --+
|
SearchEngineError
Known Subclasses:
IndexerError ,
SearchError ,
XapianError
Base class for exceptions thrown by the search engine.
Any errors generated by xappy itself, or by xapian, will be instances of
this class or its subclasses.
Inherited from exceptions.Exception
:
__init__
,
__new__
Inherited from exceptions.BaseException
:
__delattr__
,
__getattribute__
,
__getitem__
,
__getslice__
,
__reduce__
,
__repr__
,
__setattr__
,
__setstate__
,
__str__
Inherited from object
:
__hash__
,
__reduce_ex__
Inherited from exceptions.BaseException
:
args
,
message
Inherited from object
:
__class__
xappy-0.5/docs/api/xappy.errors.SearchError-class.html 0000644 0001750 0001750 00000014211 11005555242 022713 0 ustar richard richard
xappy.errors.SearchError
Class SearchError source code
object --+
|
exceptions.BaseException --+
|
exceptions.Exception --+
|
SearchEngineError --+
|
SearchError
Class used to report errors relating to the search API.
Inherited from exceptions.Exception
:
__init__
,
__new__
Inherited from exceptions.BaseException
:
__delattr__
,
__getattribute__
,
__getitem__
,
__getslice__
,
__reduce__
,
__repr__
,
__setattr__
,
__setstate__
,
__str__
Inherited from object
:
__hash__
,
__reduce_ex__
Inherited from exceptions.BaseException
:
args
,
message
Inherited from object
:
__class__
xappy-0.5/docs/api/xappy.errors.XapianError-class.html 0000644 0001750 0001750 00000014341 11005555242 022732 0 ustar richard richard
xappy.errors.XapianError
Class XapianError source code
object --+
|
exceptions.BaseException --+
|
exceptions.Exception --+
|
SearchEngineError --+
|
XapianError
Base class for exceptions thrown by the xapian.
Any errors generated by xapian will be instances of this class or its
subclasses.
Inherited from exceptions.Exception
:
__init__
,
__new__
Inherited from exceptions.BaseException
:
__delattr__
,
__getattribute__
,
__getitem__
,
__getslice__
,
__reduce__
,
__repr__
,
__setattr__
,
__setstate__
,
__str__
Inherited from object
:
__hash__
,
__reduce_ex__
Inherited from exceptions.BaseException
:
args
,
message
Inherited from object
:
__class__
xappy-0.5/docs/api/xappy.fieldactions-module.html 0000644 0001750 0001750 00000012164 11005555242 022012 0 ustar richard richard
xappy.fieldactions
Module fieldactions source code
fieldactions.py: Definitions and implementations of field actions.
xappy-0.5/docs/api/xappy.fieldactions-pysrc.html 0000644 0001750 0001750 00000375322 11005555243 021676 0 ustar richard richard
xappy.fieldactions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""fieldactions.py: Definitions and implementations of field actions.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import _checkxapian
24 import errors
25 import marshall
26 from replaylog import log
27 import xapian
28 import parsedate
29
30 - def _act_store_content ( fieldname , doc , value , context ) :
31 """Perform the STORE_CONTENT action.
32
33 """
34 try :
35 fielddata = doc . data [ fieldname ]
36 except KeyError :
37 fielddata = [ ]
38 doc . data [ fieldname ] = fielddata
39 fielddata . append ( value )
40
42 """Perform the INDEX_EXACT action.
43
44 """
45 doc . add_term ( fieldname , value , 0 )
46
47 - def _act_tag ( fieldname , doc , value , context ) :
48 """Perform the TAG action.
49
50 """
51 doc . add_term ( fieldname , value . lower ( ) , 0 )
52
53 - def _act_facet ( fieldname , doc , value , context , type = None ) :
54 """Perform the FACET action.
55
56 """
57 if type is None or type == 'string' :
58 value = value . lower ( )
59 doc . add_term ( fieldname , value , 0 )
60 serialiser = log ( xapian . StringListSerialiser ,
61 doc . get_value ( fieldname , 'facet' ) )
62 serialiser . append ( value )
63 doc . add_value ( fieldname , serialiser . get ( ) , 'facet' )
64 else :
65 marshaller = SortableMarshaller ( )
66 fn = marshaller . get_marshall_function ( fieldname , type )
67 doc . add_value ( fieldname , fn ( fieldname , value ) , 'facet' )
68
69 - def _act_index_freetext ( fieldname , doc , value , context , weight = 1 ,
70 language = None , stop = None , spell = False ,
71 nopos = False ,
72 allow_field_specific = True ,
73 search_by_default = True ) :
74 """Perform the INDEX_FREETEXT action.
75
76 """
77 termgen = log ( xapian . TermGenerator )
78 if language is not None :
79 termgen . set_stemmer ( log ( xapian . Stem , language ) )
80
81 if stop is not None :
82 stopper = log ( xapian . SimpleStopper )
83 for term in stop :
84 stopper . add ( term )
85 termgen . set_stopper ( stopper )
86
87 if spell :
88 termgen . set_database ( context . index )
89 termgen . set_flags ( termgen . FLAG_SPELLING )
90
91 termgen . set_document ( doc . _doc )
92
93 if search_by_default :
94 termgen . set_termpos ( context . current_position )
95
96
97 if nopos :
98 termgen . index_text_without_positions ( value , weight , '' )
99 else :
100 termgen . index_text ( value , weight , '' )
101
102 if allow_field_specific :
103
104
105 prefix = doc . _fieldmappings . get_prefix ( fieldname )
106 if len ( prefix ) != 0 :
107 termgen . set_termpos ( context . current_position )
108 if nopos :
109 termgen . index_text_without_positions ( value , weight , prefix )
110 else :
111 termgen . index_text ( value , weight , prefix )
112
113
114
115 termgen . increase_termpos ( 10 )
116 context . current_position = termgen . get_termpos ( )
117
119 """Implementation of marshalling for sortable values.
120
121 """
127
129 """Marshall a value for sorting in lexicograpical order.
130
131 This returns the input as the output, since strings already sort in
132 lexicographical order.
133
134 """
135 return value
136
138 """Marshall a value for sorting as a floating point value.
139
140 """
141
142 try :
143 value = float ( value )
144 except ValueError :
145 raise self . _err ( "Value supplied to field %r must be a "
146 "valid floating point number: was %r" %
147 ( fieldname , value ) )
148 return marshall . float_to_string ( value )
149
161
163 """Get a function used to marshall values of a given sorttype.
164
165 """
166 try :
167 return {
168 None : self . marshall_string ,
169 'string' : self . marshall_string ,
170 'float' : self . marshall_float ,
171 'date' : self . marshall_date ,
172 } [ sorttype ]
173 except KeyError :
174 raise self . _err ( "Unknown sort type %r for field %r" %
175 ( sorttype , fieldname ) )
176
177
186
187 - class ActionContext ( object ) :
188 """The context in which an action is performed.
189
190 This is just used to pass term generators, word positions, and the like
191 around.
192
193 """
194 - def __init__ ( self , index ) :
195 self . current_language = None
196 self . current_position = 0
197 self . index = index
198
200 """An object describing the actions to be performed on a field.
201
202 The supported actions are:
203
204 - `STORE_CONTENT`: store the unprocessed content of the field in the search
205 engine database. All fields which need to be displayed or used when
206 displaying the search results need to be given this action.
207
208 - `INDEX_EXACT`: index the exact content of the field as a single search
209 term. Fields whose contents need to be searchable as an "exact match"
210 need to be given this action.
211
212 - `INDEX_FREETEXT`: index the content of this field as text. The content
213 will be split into terms, allowing free text searching of the field. Four
214 optional parameters may be supplied:
215
216 - 'weight' is a multiplier to apply to the importance of the field. This
217 must be an integer, and the default value is 1.
218 - 'language' is the language to use when processing the field. This can
219 be expressed as an ISO 2-letter language code. The supported languages
220 are those supported by the xapian core in use.
221 - 'stop' is an iterable of stopwords to filter out of the generated
222 terms. Note that due to Xapian design, only non-positional terms are
223 affected, so this is of limited use.
224 - 'spell' is a boolean flag - if true, the contents of the field will be
225 used for spelling correction.
226 - 'nopos' is a boolean flag - if true, positional information is not
227 stored.
228 - 'allow_field_specific' is a boolean flag - if False, prevents terms with the field
229 prefix being generated. This means that searches specific to this
230 field will not work, and thus should only be used when only non-field
231 specific searches are desired. Defaults to True.
232 - 'search_by_default' is a boolean flag - if False, the field will not be
233 searched by non-field specific searches. If True, or omitted, the
234 field will be included in searches for non field-specific searches.
235
236 - `SORTABLE`: index the content of the field such that it can be used to
237 sort result sets. It also allows result sets to be restricted to those
238 documents with a field values in a given range. One optional parameter
239 may be supplied:
240
241 - 'type' is a value indicating how to sort the field. It has several
242 possible values:
243
244 - 'string' - sort in lexicographic (ie, alphabetical) order.
245 This is the default, used if no type is set.
246 - 'float' - treat the values as (decimal representations of) floating
247 point numbers, and sort in numerical order. The values in the field
248 must be valid floating point numbers (according to Python's float()
249 function).
250 - 'date' - sort in date order. The values must be valid dates (either
251 Python datetime.date objects, or ISO 8601 format (ie, YYYYMMDD or
252 YYYY-MM-DD).
253
254 - `COLLAPSE`: index the content of the field such that it can be used to
255 "collapse" result sets, such that only the highest result with each value
256 of the field will be returned.
257
258 - `TAG`: the field contains tags; these are strings, which will be matched
259 in a case insensitive way, but otherwise must be exact matches. Tag
260 fields can be searched for by making an explict query (ie, using
261 query_field(), but not with query_parse()). A list of the most frequent
262 tags in a result set can also be accessed easily.
263
264 - `FACET`: the field represents a classification facet; these are strings
265 which will be matched exactly, but a list of all the facets present in
266 the result set can also be accessed easily - in addition, a suitable
267 subset of the facets, and a selection of the facet values, present in the
268 result set can be calculated. One optional parameter may be supplied:
269
270 - 'type' is a value indicating the type of facet contained in the field:
271
272 - 'string' - the facet values are exact binary strings.
273 - 'float' - the facet values are floating point numbers.
274
275 """
276
277
278 STORE_CONTENT = 1
279 INDEX_EXACT = 2
280 INDEX_FREETEXT = 3
281 SORTABLE = 4
282 COLLAPSE = 5
283 TAG = 6
284 FACET = 7
285
286
287
288
289 SORT_AND_COLLAPSE = - 1
290
291 _unsupported_actions = [ ]
292
293 if 'tags' in _checkxapian . missing_features :
294 _unsupported_actions . append ( TAG )
295 if 'facets' in _checkxapian . missing_features :
296 _unsupported_actions . append ( FACET )
297
299
300 self . _actions = { }
301 self . _fieldname = fieldname
302
303 - def add ( self , field_mappings , action , ** kwargs ) :
304 """Add an action to perform on a field.
305
306 """
307 if action in self . _unsupported_actions :
308 raise errors . IndexerError ( "Action unsupported with this release of xapian" )
309
310 if action not in ( FieldActions . STORE_CONTENT ,
311 FieldActions . INDEX_EXACT ,
312 FieldActions . INDEX_FREETEXT ,
313 FieldActions . SORTABLE ,
314 FieldActions . COLLAPSE ,
315 FieldActions . TAG ,
316 FieldActions . FACET ,
317 ) :
318 raise errors . IndexerError ( "Unknown field action: %r" % action )
319
320 info = self . _action_info [ action ]
321
322
323 for key in kwargs . keys ( ) :
324 if key not in info [ 1 ] :
325 raise errors . IndexerError ( "Unknown parameter name for action %r: %r" % ( info [ 0 ] , key ) )
326
327
328
329
330 if action == FieldActions . INDEX_EXACT :
331 if FieldActions . INDEX_FREETEXT in self . _actions :
332 raise errors . IndexerError ( "Field %r is already marked for indexing "
333 "as free text: cannot mark for indexing "
334 "as exact text as well" % self . _fieldname )
335 if action == FieldActions . INDEX_FREETEXT :
336 if FieldActions . INDEX_EXACT in self . _actions :
337 raise errors . IndexerError ( "Field %r is already marked for indexing "
338 "as exact text: cannot mark for indexing "
339 "as free text as well" % self . _fieldname )
340
341
342
343
344
345
346 if action == FieldActions . SORTABLE or action == FieldActions . COLLAPSE :
347 if action == FieldActions . COLLAPSE :
348 sorttype = None
349 else :
350 try :
351 sorttype = kwargs [ 'type' ]
352 except KeyError :
353 sorttype = 'string'
354 kwargs [ 'type' ] = sorttype
355 action = FieldActions . SORT_AND_COLLAPSE
356
357 try :
358 oldsortactions = self . _actions [ FieldActions . SORT_AND_COLLAPSE ]
359 except KeyError :
360 oldsortactions = ( )
361
362 if len ( oldsortactions ) > 0 :
363 for oldsortaction in oldsortactions :
364 oldsorttype = oldsortaction [ 'type' ]
365
366 if sorttype == oldsorttype or oldsorttype is None :
367
368 self . _actions [ action ] = [ ]
369 elif sorttype is None :
370
371 return
372 else :
373 raise errors . IndexerError ( "Field %r is already marked for "
374 "sorting, with a different "
375 "sort type" % self . _fieldname )
376
377 if 'prefix' in info [ 3 ] :
378 field_mappings . add_prefix ( self . _fieldname )
379 if 'slot' in info [ 3 ] :
380 purposes = info [ 3 ] [ 'slot' ]
381 if isinstance ( purposes , basestring ) :
382 field_mappings . add_slot ( self . _fieldname , purposes )
383 else :
384 slotnum = None
385 for purpose in purposes :
386 slotnum = field_mappings . get_slot ( self . _fieldname , purpose )
387 if slotnum is not None :
388 break
389 for purpose in purposes :
390 field_mappings . add_slot ( self . _fieldname , purpose , slotnum = slotnum )
391
392
393 if action not in self . _actions :
394 self . _actions [ action ] = [ ]
395
396
397 for old_action in self . _actions [ action ] :
398 if old_action == kwargs :
399 return
400
401
402 self . _actions [ action ] . append ( kwargs )
403
416
417 _action_info = {
418 STORE_CONTENT : ( 'STORE_CONTENT' , ( ) , _act_store_content , { } , ) ,
419 INDEX_EXACT : ( 'INDEX_EXACT' , ( ) , _act_index_exact , { 'prefix' : True } , ) ,
420 INDEX_FREETEXT : ( 'INDEX_FREETEXT' , ( 'weight' , 'language' , 'stop' , 'spell' , 'nopos' , 'allow_field_specific' , 'search_by_default' , ) ,
421 _act_index_freetext , { 'prefix' : True , } , ) ,
422 SORTABLE : ( 'SORTABLE' , ( 'type' , ) , None , { 'slot' : 'collsort' , } , ) ,
423 COLLAPSE : ( 'COLLAPSE' , ( ) , None , { 'slot' : 'collsort' , } , ) ,
424 TAG : ( 'TAG' , ( ) , _act_tag , { 'prefix' : True , } , ) ,
425 FACET : ( 'FACET' , ( 'type' , ) , _act_facet , { 'prefix' : True , 'slot' : 'facet' , } , ) ,
426
427 SORT_AND_COLLAPSE : ( 'SORT_AND_COLLAPSE' , ( 'type' , ) , _act_sort_and_collapse , { 'slot' : 'collsort' , } , ) ,
428 }
429
430 if __name__ == '__main__' :
431 import doctest , sys
432 doctest . testmod ( sys . modules [ __name__ ] )
433
xappy-0.5/docs/api/xappy.fieldactions.ActionContext-class.html 0000644 0001750 0001750 00000016724 11005555242 024421 0 ustar richard richard
xappy.fieldactions.ActionContext
Class ActionContext source code
object --+
|
ActionContext
The context in which an action is performed.
This is just used to pass term generators, word positions, and the like
around.
__init__ (self ,
index )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
xappy-0.5/docs/api/xappy.fieldactions.FieldActions-class.html 0000644 0001750 0001750 00000041616 11005555242 024201 0 ustar richard richard
xappy.fieldactions.FieldActions
Class FieldActions source code
object --+
|
FieldActions
An object describing the actions to be performed on a field.
The supported actions are:
STORE_CONTENT : store the unprocessed content of the field in the search
engine database. All fields which need to be displayed or used when
displaying the search results need to be given this action.
INDEX_EXACT : index the exact content of the field as a single search
term. Fields whose contents need to be searchable as an "exact match"
need to be given this action.
INDEX_FREETEXT : index the content of this field as text. The content
will be split into terms, allowing free text searching of the field. Four
optional parameters may be supplied:
'weight' is a multiplier to apply to the importance of the field. This
must be an integer, and the default value is 1.
'language' is the language to use when processing the field. This can
be expressed as an ISO 2-letter language code. The supported languages
are those supported by the xapian core in use.
'stop' is an iterable of stopwords to filter out of the generated
terms. Note that due to Xapian design, only non-positional terms are
affected, so this is of limited use.
'spell' is a boolean flag - if true, the contents of the field will be
used for spelling correction.
'nopos' is a boolean flag - if true, positional information is not
stored.
'allow_field_specific' is a boolean flag - if False, prevents terms with the field
prefix being generated. This means that searches specific to this
field will not work, and thus should only be used when only non-field
specific searches are desired. Defaults to True.
'search_by_default' is a boolean flag - if False, the field will not be
searched by non-field specific searches. If True, or omitted, the
field will be included in searches for non field-specific searches.
SORTABLE : index the content of the field such that it can be used to
sort result sets. It also allows result sets to be restricted to those
documents with a field values in a given range. One optional parameter
may be supplied:
'type' is a value indicating how to sort the field. It has several
possible values:
'string' - sort in lexicographic (ie, alphabetical) order.
This is the default, used if no type is set.
'float' - treat the values as (decimal representations of) floating
point numbers, and sort in numerical order. The values in the field
must be valid floating point numbers (according to Python's float()
function).
'date' - sort in date order. The values must be valid dates (either
Python datetime.date objects, or ISO 8601 format (ie, YYYYMMDD or
YYYY-MM-DD).
COLLAPSE : index the content of the field such that it can be used to
"collapse" result sets, such that only the highest result with each value
of the field will be returned.
TAG : the field contains tags; these are strings, which will be matched
in a case insensitive way, but otherwise must be exact matches. Tag
fields can be searched for by making an explict query (ie, using
query_field(), but not with query_parse()). A list of the most frequent
tags in a result set can also be accessed easily.
FACET : the field represents a classification facet; these are strings
which will be matched exactly, but a list of all the facets present in
the result set can also be accessed easily - in addition, a suitable
subset of the facets, and a selection of the facet values, present in the
result set can be calculated. One optional parameter may be supplied:
'type' is a value indicating the type of facet contained in the field:
'string' - the facet values are exact binary strings.
'float' - the facet values are floating point numbers.
__init__ (self ,
fieldname )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
add (self ,
field_mappings ,
action ,
**kwargs )
Add an action to perform on a field.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
STORE_CONTENT = 1
INDEX_EXACT = 2
INDEX_FREETEXT = 3
SORTABLE = 4
COLLAPSE = 5
TAG = 6
FACET = 7
SORT_AND_COLLAPSE = -1
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
Perform the actions on the field.
doc
is a ProcessedDocument to store the result of the actions in.
value
is a string holding the value of the field.
context
is an ActionContext object used to keep state in.
xappy-0.5/docs/api/xappy.fieldactions.SortableMarshaller-class.html 0000644 0001750 0001750 00000027323 11005555243 025423 0 ustar richard richard
xappy.fieldactions.SortableMarshaller
Class SortableMarshaller source code
object --+
|
SortableMarshaller
Implementation of marshalling for sortable values.
__init__ (self ,
indexing =True )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
marshall_float (self ,
fieldname ,
value )
Marshall a value for sorting as a floating point value.
source code
marshall_date (self ,
fieldname ,
value )
Marshall a value for sorting as a date.
source code
get_marshall_function (self ,
fieldname ,
sorttype )
Get a function used to marshall values of a given sorttype.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
indexing =True )
(Constructor)
source code
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
Marshall a value for sorting in lexicograpical order.
This returns the input as the output, since strings already sort in
lexicographical order.
xappy-0.5/docs/api/xappy.fieldmappings-module.html 0000644 0001750 0001750 00000010751 11005555242 022170 0 ustar richard richard
xappy.fieldmappings
Module fieldmappings source code
fieldmappings.py: Mappings from field names to term prefixes, etc.
FieldMappings
Mappings from field names to term prefixes, slot values, etc.
xappy-0.5/docs/api/xappy.fieldmappings-pysrc.html 0000644 0001750 0001750 00000107412 11005555243 022045 0 ustar richard richard
xappy.fieldmappings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""fieldmappings.py: Mappings from field names to term prefixes, etc.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import cPickle as _cPickle
24
26 """Mappings from field names to term prefixes, slot values, etc.
27
28 The following mappings are maintained:
29
30 - a mapping from field name to the string prefix to insert at the start of
31 terms.
32 - a mapping from field name to the slot numbers to store the field contents
33 in.
34
35 """
36 __slots__ = '_prefixes' , '_prefixcount' , '_slots' , '_slotcount' ,
37
39 """Create a new field mapping object, or unserialise a saved one.
40
41 """
42 if serialised is not None :
43 ( self . _prefixes , self . _prefixcount ,
44 self . _slots , self . _slotcount ) = _cPickle . loads ( serialised )
45 else :
46 self . _prefixes = { }
47 self . _prefixcount = 0
48 self . _slots = { }
49 self . _slotcount = 0
50
52 """Generate a previously unused prefix.
53
54 Prefixes are uppercase letters, and start with 'X' (this is a Xapian
55 convention, for compatibility with other Xapian tools: other starting
56 letters are reserved for special meanings):
57
58 >>> maps = FieldMappings()
59 >>> maps._genPrefix()
60 'XA'
61 >>> maps._genPrefix()
62 'XB'
63 >>> [maps._genPrefix() for i in xrange(60)]
64 ['XC', 'XD', 'XE', 'XF', 'XG', 'XH', 'XI', 'XJ', 'XK', 'XL', 'XM', 'XN', 'XO', 'XP', 'XQ', 'XR', 'XS', 'XT', 'XU', 'XV', 'XW', 'XX', 'XY', 'XZ', 'XAA', 'XBA', 'XCA', 'XDA', 'XEA', 'XFA', 'XGA', 'XHA', 'XIA', 'XJA', 'XKA', 'XLA', 'XMA', 'XNA', 'XOA', 'XPA', 'XQA', 'XRA', 'XSA', 'XTA', 'XUA', 'XVA', 'XWA', 'XXA', 'XYA', 'XZA', 'XAB', 'XBB', 'XCB', 'XDB', 'XEB', 'XFB', 'XGB', 'XHB', 'XIB', 'XJB']
65 >>> maps = FieldMappings()
66 >>> [maps._genPrefix() for i in xrange(27*26 + 5)][-10:]
67 ['XVZ', 'XWZ', 'XXZ', 'XYZ', 'XZZ', 'XAAA', 'XBAA', 'XCAA', 'XDAA', 'XEAA']
68 """
69 res = [ ]
70 self . _prefixcount += 1
71 num = self . _prefixcount
72 while num != 0 :
73 ch = ( num - 1 ) % 26
74 res . append ( chr ( ch + ord ( 'A' ) ) )
75 num -= ch
76 num = num // 26
77 return 'X' + '' . join ( res )
78
80 """Get a fieldname from a prefix.
81
82 If the prefix is not found, return None.
83
84 """
85 for key , val in self . _prefixes . iteritems ( ) :
86 if val == prefix :
87 return key
88 return None
89
91 """Get the prefix used for a given field name.
92
93 """
94 return self . _prefixes [ fieldname ]
95
97 """Get the slot number used for a given field name and purpose.
98
99 """
100 return self . _slots [ ( fieldname , purpose ) ]
101
103 """Allocate a prefix for the given field.
104
105 If a prefix is already allocated for this field, this has no effect.
106
107 """
108 if fieldname in self . _prefixes :
109 return
110 self . _prefixes [ fieldname ] = self . _genPrefix ( )
111
112 - def add_slot ( self , fieldname , purpose , slotnum = None ) :
113 """Allocate a slot number for the given field and purpose.
114
115 If a slot number is already allocated for this field and purpose, this
116 has no effect.
117
118 Returns the slot number allocated for the field and purpose (whether
119 newly allocated, or previously allocated).
120
121 If `slotnum` is supplied, the number contained in it is used to
122 allocate the new slot, instead of allocating a new number. No checks
123 will be made to ensure that the slot number doesn't collide with
124 existing (or later allocated) numbers: the main purpose of this
125 parameter is to share allocations - ie, to collide deliberately.
126
127 """
128 try :
129 return self . _slots [ ( fieldname , purpose ) ]
130 except KeyError :
131 pass
132
133 if slotnum is None :
134 self . _slots [ ( fieldname , purpose ) ] = self . _slotcount
135 self . _slotcount += 1
136 return self . _slotcount - 1
137 else :
138 self . _slots [ ( fieldname , purpose ) ] = slotnum
139 return slotnum
140
142 """Serialise the field mappings to a string.
143
144 This can be unserialised by passing the result of this method to the
145 constructor of a new FieldMappings object.
146
147 """
148 return _cPickle . dumps ( ( self . _prefixes ,
149 self . _prefixcount ,
150 self . _slots ,
151 self . _slotcount ,
152 ) , 2 )
153
xappy-0.5/docs/api/xappy.fieldmappings.FieldMappings-class.html 0000644 0001750 0001750 00000040162 11005555243 024531 0 ustar richard richard
xappy.fieldmappings.FieldMappings
Class FieldMappings source code
object --+
|
FieldMappings
Mappings from field names to term prefixes, slot values, etc.
The following mappings are maintained:
a mapping from field name to the string prefix to insert at the start of
terms.
a mapping from field name to the slot numbers to store the field contents
in.
__init__ (self ,
serialised =None )
Create a new field mapping object, or unserialise a saved one.
source code
get_prefix (self ,
fieldname )
Get the prefix used for a given field name.
source code
get_slot (self ,
fieldname ,
purpose )
Get the slot number used for a given field name and purpose.
source code
add_slot (self ,
fieldname ,
purpose ,
slotnum =None )
Allocate a slot number for the given field and purpose.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
serialised =None )
(Constructor)
source code
Create a new field mapping object, or unserialise a saved one.
Overrides:
object.__init__
Get a fieldname from a prefix.
If the prefix is not found, return None.
Allocate a prefix for the given field.
If a prefix is already allocated for this field, this has no effect.
add_slot (self ,
fieldname ,
purpose ,
slotnum =None )
source code
Allocate a slot number for the given field and purpose.
If a slot number is already allocated for this field and purpose, this
has no effect.
Returns the slot number allocated for the field and purpose (whether
newly allocated, or previously allocated).
If slotnum
is supplied, the number contained in it is used to
allocate the new slot, instead of allocating a new number. No checks
will be made to ensure that the slot number doesn't collide with
existing (or later allocated) numbers: the main purpose of this
parameter is to share allocations - ie, to collide deliberately.
Serialise the field mappings to a string.
This can be unserialised by passing the result of this method to the
constructor of a new FieldMappings object.
xappy-0.5/docs/api/xappy.highlight-module.html 0000644 0001750 0001750 00000016561 11005555242 021322 0 ustar richard richard
xappy.highlight
Module highlight source code
highlight.py: Highlight and summarise text.
Highlighter
Class for highlighting text and creating contextual summaries.
__test__ = {
'
apostrophes
'
:
'
\n\n >>> hl = Highlighter(\'en\
...
__test__
Value:
{
'
apostrophes
'
:
'''
>>> hl = Highlighter(\'en\')
>>> hl.makeSample("A boring start. Hello world\'s indeed. A bori
ng end.", [\'world\'], 40, (\'<\', \'>\'))
"A boring start. Hello <world\'s> indeed..."
'''
,
...
xappy-0.5/docs/api/xappy.highlight-pysrc.html 0000644 0001750 0001750 00000203125 11005555243 021170 0 ustar richard richard
xappy.highlight
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""highlight.py: Highlight and summarise text.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import re
24 import xapian
25
27 """Class for highlighting text and creating contextual summaries.
28
29 >>> hl = Highlighter("en")
30 >>> hl.makeSample('Hello world.', ['world'])
31 'Hello world.'
32 >>> hl.highlight('Hello world', ['world'], ('<', '>'))
33 'Hello <world>'
34
35 """
36
37
38 _split_re = re . compile ( r'<\w+[^>]*>|</\w+>|[\w\']+|\s+|[^\w\'\s<>/]+' )
39
40 - def __init__ ( self , language_code = 'en' , stemmer = None ) :
41 """Create a new highlighter for the specified language.
42
43 """
44 if stemmer is not None :
45 self . stem = stemmer
46 else :
47 self . stem = xapian . Stem ( language_code )
48
49 - def _split_text ( self , text , strip_tags = False ) :
50 """Split some text into words and non-words.
51
52 - `text` is the text to process. It may be a unicode object or a utf-8
53 encoded simple string.
54 - `strip_tags` is a flag - False to keep tags, True to strip all tags
55 from the output.
56
57 Returns a list of utf-8 encoded simple strings.
58
59 """
60 if isinstance ( text , unicode ) :
61 text = text . encode ( 'utf-8' )
62
63 words = self . _split_re . findall ( text )
64 if strip_tags :
65 return [ w for w in words if w [ 0 ] != '<' ]
66 else :
67 return words
68
70 """Strip the prefix off a term.
71
72 Prefixes are any initial capital letters, with the exception that R always
73 ends a prefix, even if followed by capital letters.
74
75 >>> hl = Highlighter("en")
76 >>> print hl._strip_prefix('hello')
77 hello
78 >>> print hl._strip_prefix('Rhello')
79 hello
80 >>> print hl._strip_prefix('XARHello')
81 Hello
82 >>> print hl._strip_prefix('XAhello')
83 hello
84 >>> print hl._strip_prefix('XAh')
85 h
86 >>> print hl._strip_prefix('XA')
87 <BLANKLINE>
88
89 """
90 for p in xrange ( len ( term ) ) :
91 if term [ p ] . islower ( ) :
92 return term [ p : ]
93 elif term [ p ] == 'R' :
94 return term [ p + 1 : ]
95 return ''
96
98 """Convert a query to a list of stemmed words.
99
100 - `query` is the query to parse: it may be xapian.Query object, or a
101 sequence of terms.
102
103 """
104 if isinstance ( query , xapian . Query ) :
105 return [ self . _strip_prefix ( t ) for t in query ]
106 else :
107 return [ self . stem ( q . lower ( ) ) for q in query ]
108
109
110 - def makeSample ( self , text , query , maxlen = 600 , hl = None ) :
111 """Make a contextual summary from the supplied text.
112
113 This basically works by splitting the text into phrases, counting the query
114 terms in each, and keeping those with the most.
115
116 Any markup tags in the text will be stripped.
117
118 `text` is the source text to summarise.
119 `query` is either a Xapian query object or a list of (unstemmed) term strings.
120 `maxlen` is the maximum length of the generated summary.
121 `hl` is a pair of strings to insert around highlighted terms, e.g. ('<b>', '</b>')
122
123 """
124
125
126 maxlen = int ( maxlen )
127
128 words = self . _split_text ( text , True )
129 terms = self . _query_to_stemmed_words ( query )
130
131
132
133 blocks = [ ]
134 start = end = count = blockchars = 0
135
136 while end < len ( words ) :
137 blockchars += len ( words [ end ] )
138 if words [ end ] . isalnum ( ) :
139 if self . stem ( words [ end ] . lower ( ) ) in terms :
140 count += 1
141 end += 1
142 elif words [ end ] in ',.;:?!\n' :
143 end += 1
144 blocks . append ( [ start , end , blockchars , count , False ] )
145 start = end
146 blockchars = 0
147 count = 0
148 else :
149 end += 1
150 if start != end :
151 blocks . append ( [ start , end , blockchars , count , False ] )
152 if len ( blocks ) == 0 :
153 return ''
154
155
156 chars = 0
157 for count in xrange ( 3 , - 1 , - 1 ) :
158 for b in blocks :
159 if b [ 3 ] >= count :
160 b [ 4 ] = True
161 chars += b [ 2 ]
162 if chars >= maxlen : break
163 if chars >= maxlen : break
164
165
166 words2 = [ ]
167 lastblock = - 1
168 for i , b in enumerate ( blocks ) :
169 if b [ 4 ] :
170 if i != lastblock + 1 :
171 words2 . append ( '..' )
172 words2 . extend ( words [ b [ 0 ] : b [ 1 ] ] )
173 lastblock = i
174
175 if not blocks [ - 1 ] [ 4 ] :
176 words2 . append ( '..' )
177
178
179 l = 0
180 for i in xrange ( len ( words2 ) ) :
181 l += len ( words2 [ i ] )
182 if l >= maxlen :
183 words2 [ i : ] = [ '..' ]
184 break
185
186 if hl is None :
187 return '' . join ( words2 )
188 else :
189 return self . _hl ( words2 , terms , hl )
190
191 - def highlight ( self , text , query , hl , strip_tags = False ) :
192 """Add highlights (string prefix/postfix) to a string.
193
194 `text` is the source to highlight.
195 `query` is either a Xapian query object or a list of (unstemmed) term strings.
196 `hl` is a pair of highlight strings, e.g. ('<i>', '</i>')
197 `strip_tags` strips HTML markout iff True
198
199 >>> hl = Highlighter()
200 >>> qp = xapian.QueryParser()
201 >>> q = qp.parse_query('cat dog')
202 >>> tags = ('[[', ']]')
203 >>> hl.highlight('The cat went Dogging; but was <i>dog tired</i>.', q, tags)
204 'The [[cat]] went [[Dogging]]; but was <i>[[dog]] tired</i>.'
205
206 """
207 words = self . _split_text ( text , strip_tags )
208 terms = self . _query_to_stemmed_words ( query )
209 return self . _hl ( words , terms , hl )
210
211 - def _hl ( self , words , terms , hl ) :
212 """Add highlights to a list of words.
213
214 `words` is the list of words and non-words to be highlighted..
215 `terms` is the list of stemmed words to look for.
216
217 """
218 for i , w in enumerate ( words ) :
219
220 wl = w . lower ( )
221 if wl in terms or self . stem ( wl ) in terms :
222 words [ i ] = '' . join ( ( hl [ 0 ] , w , hl [ 1 ] ) )
223
224 return '' . join ( words )
225
226
227 __test__ = {
228 'no_punc' : r'''
229
230 Test the highlighter's behaviour when there is no punctuation in the sample
231 text (regression test - used to return no output):
232 >>> hl = Highlighter("en")
233 >>> hl.makeSample('Hello world', ['world'])
234 'Hello world'
235
236 ''' ,
237
238 'stem_levels' : r'''
239
240 Test highlighting of words, and how it works with stemming:
241 >>> hl = Highlighter("en")
242
243 # "word" and "wording" stem to "word", so the following 4 calls all return
244 # the same thing
245 >>> hl.makeSample('Hello. word. wording. wordinging.', ['word'], hl='<>')
246 'Hello. <word>. <wording>. wordinging.'
247 >>> hl.highlight('Hello. word. wording. wordinging.', ['word'], '<>')
248 'Hello. <word>. <wording>. wordinging.'
249 >>> hl.makeSample('Hello. word. wording. wordinging.', ['wording'], hl='<>')
250 'Hello. <word>. <wording>. wordinging.'
251 >>> hl.highlight('Hello. word. wording. wordinging.', ['wording'], '<>')
252 'Hello. <word>. <wording>. wordinging.'
253
254 # "wordinging" stems to "wording", so only the last two words are
255 # highlighted for this one.
256 >>> hl.makeSample('Hello. word. wording. wordinging.', ['wordinging'], hl='<>')
257 'Hello. word. <wording>. <wordinging>.'
258 >>> hl.highlight('Hello. word. wording. wordinging.', ['wordinging'], '<>')
259 'Hello. word. <wording>. <wordinging>.'
260 ''' ,
261
262 'supplied_stemmer' : r'''
263
264 Test behaviour if we pass in our own stemmer:
265 >>> stem = xapian.Stem('en')
266 >>> hl = Highlighter(stemmer=stem)
267 >>> hl.highlight('Hello. word. wording. wordinging.', ['word'], '<>')
268 'Hello. <word>. <wording>. wordinging.'
269
270 ''' ,
271
272 'unicode' : r'''
273
274 Test behaviour if we pass in unicode input:
275 >>> hl = Highlighter('en')
276 >>> hl.highlight(u'Hello\xf3. word. wording. wordinging.', ['word'], '<>')
277 'Hello\xc3\xb3. <word>. <wording>. wordinging.'
278
279 ''' ,
280
281 'no_sample' : r'''
282
283 Test behaviour if we pass in unicode input:
284 >>> hl = Highlighter('en')
285 >>> hl.makeSample(u'', ['word'])
286 ''
287
288 ''' ,
289
290 'short_samples' : r'''
291
292 >>> hl = Highlighter('en')
293 >>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['hello'], 20, ('<', '>'))
294 '.. <Hello> world ..'
295 >>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['hello'], 40, ('<', '>'))
296 'A boring start. <Hello> world indeed...'
297 >>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['boring'], 40, ('<', '>'))
298 'A <boring> start... A <boring> end.'
299
300 ''' ,
301
302 'apostrophes' : r'''
303
304 >>> hl = Highlighter('en')
305 >>> hl.makeSample("A boring start. Hello world's indeed. A boring end.", ['world'], 40, ('<', '>'))
306 "A boring start. Hello <world's> indeed..."
307
308 ''' ,
309
310 }
311
312 if __name__ == '__main__' :
313 import doctest , sys
314 doctest . testmod ( sys . modules [ __name__ ] )
315
xappy-0.5/docs/api/xappy.highlight.Highlighter-class.html 0000644 0001750 0001750 00000033134 11005555243 023373 0 ustar richard richard
xappy.highlight.Highlighter
Class Highlighter source code
object --+
|
Highlighter
Class for highlighting text and creating contextual summaries.
>>> hl = Highlighter("en" )
>>> hl.makeSample('Hello world.' , ['world' ])
'Hello world.'
>>> hl.highlight('Hello world' , ['world' ], ('<' , '>' ))
'Hello <world>'
__init__ (self ,
language_code ='
en
'
,
stemmer =None )
Create a new highlighter for the specified language.
source code
makeSample (self ,
text ,
query ,
maxlen =600 ,
hl =None )
Make a contextual summary from the supplied text.
source code
highlight (self ,
text ,
query ,
hl ,
strip_tags =False )
Add highlights (string prefix/postfix) to a string.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
language_code ='
en
'
,
stemmer =None )
(Constructor)
source code
Create a new highlighter for the specified language.
Overrides:
object.__init__
makeSample (self ,
text ,
query ,
maxlen =600 ,
hl =None )
source code
Make a contextual summary from the supplied text.
This basically works by splitting the text into phrases, counting the query
terms in each, and keeping those with the most.
Any markup tags in the text will be stripped.
text
is the source text to summarise.
query
is either a Xapian query object or a list of (unstemmed) term strings.
maxlen
is the maximum length of the generated summary.
hl
is a pair of strings to insert around highlighted terms, e.g. ('<b>', '</b>')
highlight (self ,
text ,
query ,
hl ,
strip_tags =False )
source code
Add highlights (string prefix/postfix) to a string.
text
is the source to highlight.
query
is either a Xapian query object or a list of (unstemmed) term strings.
hl
is a pair of highlight strings, e.g. ('<i>', '</i>')
strip_tags
strips HTML markout iff True
>>> hl = Highlighter()
>>> qp = xapian.QueryParser()
>>> q = qp.parse_query('cat dog' )
>>> tags = ('[[' , ']]' )
>>> hl.highlight('The cat went Dogging; but was <i>dog tired</i>.' , q, tags)
'The [[cat]] went [[Dogging]]; but was <i>[[dog]] tired</i>.'
xappy-0.5/docs/api/xappy.indexerconnection-module.html 0000644 0001750 0001750 00000012760 11005555242 023066 0 ustar richard richard
xappy.indexerconnection
Module indexerconnection source code
indexerconnection.py: A connection to the search engine for indexing.
xappy-0.5/docs/api/xappy.indexerconnection-pysrc.html 0000644 0001750 0001750 00000707565 11005555243 022760 0 ustar richard richard
xappy.indexerconnection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""indexerconnection.py: A connection to the search engine for indexing.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import _checkxapian
24 import cPickle
25 import xapian
26
27 from datastructures import *
28 import errors
29 from fieldactions import *
30 import fieldmappings
31 import memutils
32 from replaylog import log
33
35 """A connection to the search engine for indexing.
36
37 """
38
40 """Create a new connection to the index.
41
42 There may only be one indexer connection for a particular database open
43 at a given time. Therefore, if a connection to the database is already
44 open, this will raise a xapian.DatabaseLockError.
45
46 If the database doesn't already exist, it will be created.
47
48 """
49 self . _index = log ( xapian . WritableDatabase , indexpath , xapian . DB_CREATE_OR_OPEN )
50 self . _indexpath = indexpath
51
52
53 self . _field_actions = { }
54 self . _field_mappings = fieldmappings . FieldMappings ( )
55 self . _facet_hierarchy = { }
56 self . _facet_query_table = { }
57 self . _next_docid = 0
58 self . _config_modified = False
59 self . _load_config ( )
60
61
62
63 self . _mem_buffered = 0
64 self . set_max_mem_use ( )
65
67 """Set the maximum memory to use.
68
69 This call allows the amount of memory to use to buffer changes to be
70 set. This will affect the speed of indexing, but should not result in
71 other changes to the indexing.
72
73 Note: this is an approximate measure - the actual amount of memory used
74 max exceed the specified amount. Also, note that future versions of
75 xapian are likely to implement this differently, so this setting may be
76 entirely ignored.
77
78 The absolute amount of memory to use (in bytes) may be set by setting
79 max_mem. Alternatively, the proportion of the available memory may be
80 set by setting max_mem_proportion (this should be a value between 0 and
81 1).
82
83 Setting too low a value will result in excessive flushing, and very
84 slow indexing. Setting too high a value will result in excessive
85 buffering, leading to swapping, and very slow indexing.
86
87 A reasonable default for max_mem_proportion for a system which is
88 dedicated to indexing is probably 0.5: if other tasks are also being
89 performed on the system, the value should be lowered.
90
91 """
92 if self . _index is None :
93 raise errors . IndexerError ( "IndexerConnection has been closed" )
94 if max_mem is not None and max_mem_proportion is not None :
95 raise errors . IndexerError ( "Only one of max_mem and "
96 "max_mem_proportion may be specified" )
97
98 if max_mem is None and max_mem_proportion is None :
99 self . _max_mem = None
100
101 if max_mem_proportion is not None :
102 physmem = memutils . get_physical_memory ( )
103 if physmem is not None :
104 max_mem = int ( physmem * max_mem_proportion )
105
106 self . _max_mem = max_mem
107
109 """Store the configuration for the database.
110
111 Currently, this stores the configuration in a file in the database
112 directory, so changes to it are not protected by transactions. When
113 support is available in xapian for storing metadata associated with
114 databases. this will be used instead of a file.
115
116 """
117 assert self . _index is not None
118
119 config_str = cPickle . dumps ( (
120 self . _field_actions ,
121 self . _field_mappings . serialise ( ) ,
122 self . _facet_hierarchy ,
123 self . _facet_query_table ,
124 self . _next_docid ,
125 ) , 2 )
126 log ( self . _index . set_metadata , '_xappy_config' , config_str )
127
128 self . _config_modified = False
129
131 """Load the configuration for the database.
132
133 """
134 assert self . _index is not None
135
136 config_str = log ( self . _index . get_metadata , '_xappy_config' )
137 if len ( config_str ) == 0 :
138 return
139
140 try :
141 ( self . _field_actions , mappings , self . _facet_hierarchy , self . _facet_query_table , self . _next_docid ) = cPickle . loads ( config_str )
142 except ValueError :
143
144 ( self . _field_actions , mappings , self . _next_docid ) = cPickle . loads ( config_str )
145 self . _facet_hierarchy = { }
146 self . _facet_query_table = { }
147 self . _field_mappings = fieldmappings . FieldMappings ( mappings )
148
149 self . _config_modified = False
150
152 """Allocate a new ID.
153
154 """
155 while True :
156 idstr = "%x" % self . _next_docid
157 self . _next_docid += 1
158 if not self . _index . term_exists ( 'Q' + idstr ) :
159 break
160 self . _config_modified = True
161 return idstr
162
164 """Add an action to be performed on a field.
165
166 Note that this change to the configuration will not be preserved on
167 disk until the next call to flush().
168
169 """
170 if self . _index is None :
171 raise errors . IndexerError ( "IndexerConnection has been closed" )
172 if fieldname in self . _field_actions :
173 actions = self . _field_actions [ fieldname ]
174 else :
175 actions = FieldActions ( fieldname )
176 self . _field_actions [ fieldname ] = actions
177 actions . add ( self . _field_mappings , fieldtype , ** kwargs )
178 self . _config_modified = True
179
181 """Clear all actions for the specified field.
182
183 This does not report an error if there are already no actions for the
184 specified field.
185
186 Note that this change to the configuration will not be preserved on
187 disk until the next call to flush().
188
189 """
190 if self . _index is None :
191 raise errors . IndexerError ( "IndexerConnection has been closed" )
192 if fieldname in self . _field_actions :
193 del self . _field_actions [ fieldname ]
194 self . _config_modified = True
195
197 """Get a list of field names which have actions defined.
198
199 """
200 if self . _index is None :
201 raise errors . IndexerError ( "IndexerConnection has been closed" )
202 return self . _field_actions . keys ( )
203
205 """Process an UnprocessedDocument with the settings in this database.
206
207 The resulting ProcessedDocument is returned.
208
209 Note that this processing will be automatically performed if an
210 UnprocessedDocument is supplied to the add() or replace() methods of
211 IndexerConnection. This method is exposed to allow the processing to
212 be performed separately, which may be desirable if you wish to manually
213 modify the processed document before adding it to the database, or if
214 you want to split processing of documents from adding documents to the
215 database for performance reasons.
216
217 """
218 if self . _index is None :
219 raise errors . IndexerError ( "IndexerConnection has been closed" )
220 result = ProcessedDocument ( self . _field_mappings )
221 result . id = document . id
222 context = ActionContext ( self . _index )
223
224 for field in document . fields :
225 try :
226 actions = self . _field_actions [ field . name ]
227 except KeyError :
228
229 continue
230 actions . perform ( result , field . value , context )
231
232 return result
233
235 """Get an estimate of the bytes used by the terms in a document.
236
237 (This is a very rough estimate.)
238
239 """
240 count = 0
241 for item in xapdoc . termlist ( ) :
242
243
244 count += len ( item . term ) * 2
245
246
247
248 count += 8
249
250
251
252 return count * 5
253
254 - def add ( self , document ) :
255 """Add a new document to the search engine index.
256
257 If the document has a id set, and the id already exists in
258 the database, an exception will be raised. Use the replace() method
259 instead if you wish to overwrite documents.
260
261 Returns the id of the newly added document (making up a new
262 unique ID if no id was set).
263
264 The supplied document may be an instance of UnprocessedDocument, or an
265 instance of ProcessedDocument.
266
267 """
268 if self . _index is None :
269 raise errors . IndexerError ( "IndexerConnection has been closed" )
270 if not hasattr ( document , '_doc' ) :
271
272 document = self . process ( document )
273
274
275 orig_id = document . id
276 if orig_id is None :
277 id = self . _allocate_id ( )
278 document . id = id
279 else :
280 id = orig_id
281 if self . _index . term_exists ( 'Q' + id ) :
282 raise errors . IndexerError ( "Document ID of document supplied to add() is not unique." )
283
284
285 xapdoc = document . prepare ( )
286 self . _index . add_document ( xapdoc )
287
288 if self . _max_mem is not None :
289 self . _mem_buffered += self . _get_bytes_used_by_doc_terms ( xapdoc )
290 if self . _mem_buffered > self . _max_mem :
291 self . flush ( )
292
293 if id is not orig_id :
294 document . id = orig_id
295 return id
296
298 """Replace a document in the search engine index.
299
300 If the document does not have a id set, an exception will be
301 raised.
302
303 If the document has a id set, and the id does not already
304 exist in the database, this method will have the same effect as add().
305
306 """
307 if self . _index is None :
308 raise errors . IndexerError ( "IndexerConnection has been closed" )
309 if not hasattr ( document , '_doc' ) :
310
311 document = self . process ( document )
312
313
314 id = document . id
315 if id is None :
316 raise errors . IndexerError ( "No document ID set for document supplied to replace()." )
317
318 xapdoc = document . prepare ( )
319 self . _index . replace_document ( 'Q' + id , xapdoc )
320
321 if self . _max_mem is not None :
322 self . _mem_buffered += self . _get_bytes_used_by_doc_terms ( xapdoc )
323 if self . _mem_buffered > self . _max_mem :
324 self . flush ( )
325
327 """Make a synonym key (ie, the term or group of terms to store in
328 xapian).
329
330 """
331 if field is not None :
332 prefix = self . _field_mappings . get_prefix ( field )
333 else :
334 prefix = ''
335 original = original . lower ( )
336
337 return ' ' . join ( ( prefix + word for word in original . split ( ' ' ) ) )
338
339 - def add_synonym ( self , original , synonym , field = None ,
340 original_field = None , synonym_field = None ) :
341 """Add a synonym to the index.
342
343 - `original` is the word or words which will be synonym expanded in
344 searches (if multiple words are specified, each word should be
345 separated by a single space).
346 - `synonym` is a synonym for `original`.
347 - `field` is the field which the synonym is specific to. If no field
348 is specified, the synonym will be used for searches which are not
349 specific to any particular field.
350
351 """
352 if self . _index is None :
353 raise errors . IndexerError ( "IndexerConnection has been closed" )
354 if original_field is None :
355 original_field = field
356 if synonym_field is None :
357 synonym_field = field
358 key = self . _make_synonym_key ( original , original_field )
359
360
361 value = self . _make_synonym_key ( synonym , synonym_field )
362 self . _index . add_synonym ( key , value )
363
365 """Remove a synonym from the index.
366
367 - `original` is the word or words which will be synonym expanded in
368 searches (if multiple words are specified, each word should be
369 separated by a single space).
370 - `synonym` is a synonym for `original`.
371 - `field` is the field which this synonym is specific to. If no field
372 is specified, the synonym will be used for searches which are not
373 specific to any particular field.
374
375 """
376 if self . _index is None :
377 raise errors . IndexerError ( "IndexerConnection has been closed" )
378 key = self . _make_synonym_key ( original , field )
379 self . _index . remove_synonym ( key , synonym . lower ( ) )
380
382 """Remove all synonyms for a word (or phrase).
383
384 - `field` is the field which this synonym is specific to. If no field
385 is specified, the synonym will be used for searches which are not
386 specific to any particular field.
387
388 """
389 if self . _index is None :
390 raise errors . IndexerError ( "IndexerConnection has been closed" )
391 key = self . _make_synonym_key ( original , field )
392 self . _index . clear_synonyms ( key )
393
395 """Raise an error if facet is not a declared facet field.
396
397 """
398 for action in self . _field_actions [ facet ] . _actions :
399 if action == FieldActions . FACET :
400 return
401 raise errors . IndexerError ( "Field %r is not indexed as a facet" % facet )
402
404 """Add a subfacet-facet relationship to the facet hierarchy.
405
406 Any existing relationship for that subfacet is replaced.
407
408 Raises a KeyError if either facet or subfacet is not a field,
409 and an IndexerError if either facet or subfacet is not a facet field.
410 """
411 if self . _index is None :
412 raise errors . IndexerError ( "IndexerConnection has been closed" )
413 self . _assert_facet ( facet )
414 self . _assert_facet ( subfacet )
415 self . _facet_hierarchy [ subfacet ] = facet
416 self . _config_modified = True
417
419 """Remove any existing facet hierarchy relationship for a subfacet.
420
421 """
422 if self . _index is None :
423 raise errors . IndexerError ( "IndexerConnection has been closed" )
424 if subfacet in self . _facet_hierarchy :
425 del self . _facet_hierarchy [ subfacet ]
426 self . _config_modified = True
427
429 """Get a list of subfacets of a facet.
430
431 """
432 if self . _index is None :
433 raise errors . IndexerError ( "IndexerConnection has been closed" )
434 return [ k for k , v in self . _facet_hierarchy . iteritems ( ) if v == facet ]
435
436 FacetQueryType_Preferred = 1 ;
437 FacetQueryType_Never = 2 ;
439 """Set the association between a query type and a facet.
440
441 The value of `association` must be one of
442 IndexerConnection.FacetQueryType_Preferred,
443 IndexerConnection.FacetQueryType_Never or None. A value of None removes
444 any previously set association.
445
446 """
447 if self . _index is None :
448 raise errors . IndexerError ( "IndexerConnection has been closed" )
449 if query_type is None :
450 raise errors . IndexerError ( "Cannot set query type information for None" )
451 self . _assert_facet ( facet )
452 if query_type not in self . _facet_query_table :
453 self . _facet_query_table [ query_type ] = { }
454 if association is None :
455 if facet in self . _facet_query_table [ query_type ] :
456 del self . _facet_query_table [ query_type ] [ facet ]
457 else :
458 self . _facet_query_table [ query_type ] [ facet ] = association ;
459 if self . _facet_query_table [ query_type ] == { } :
460 del self . _facet_query_table [ query_type ]
461 self . _config_modified = True
462
464 """Get the set of facets associated with a query type.
465
466 Only those facets associated with the query type in the specified
467 manner are returned; `association` must be one of
468 IndexerConnection.FacetQueryType_Preferred or
469 IndexerConnection.FacetQueryType_Never.
470
471 If the query type has no facets associated with it, None is returned.
472
473 """
474 if self . _index is None :
475 raise errors . IndexerError ( "IndexerConnection has been closed" )
476 if query_type not in self . _facet_query_table :
477 return None
478 facet_dict = self . _facet_query_table [ query_type ]
479 return set ( [ facet for facet , assoc in facet_dict . iteritems ( ) if assoc == association ] )
480
505
519
521 """Delete a document from the search engine index.
522
523 If the id does not already exist in the database, this method
524 will have no effect (and will not report an error).
525
526 """
527 if self . _index is None :
528 raise errors . IndexerError ( "IndexerConnection has been closed" )
529 self . _index . delete_document ( 'Q' + id )
530
532 """Apply recent changes to the database.
533
534 If an exception occurs, any changes since the last call to flush() may
535 be lost.
536
537 """
538 if self . _index is None :
539 raise errors . IndexerError ( "IndexerConnection has been closed" )
540 if self . _config_modified :
541 self . _store_config ( )
542 self . _index . flush ( )
543 self . _mem_buffered = 0
544
546 """Close the connection to the database.
547
548 It is important to call this method before allowing the class to be
549 garbage collected, because it will ensure that any un-flushed changes
550 will be flushed. It also ensures that the connection is cleaned up
551 promptly.
552
553 No other methods may be called on the connection after this has been
554 called. (It is permissible to call close() multiple times, but
555 only the first call will have any effect.)
556
557 If an exception occurs, the database will be closed, but changes since
558 the last call to flush may be lost.
559
560 """
561 if self . _index is None :
562 return
563 try :
564 self . flush ( )
565 finally :
566
567
568
569
570
571
572
573 self . _index = None
574 self . _indexpath = None
575 self . _field_actions = None
576 self . _config_modified = False
577
579 """Count the number of documents in the database.
580
581 This count will include documents which have been added or removed but
582 not yet flushed().
583
584 """
585 if self . _index is None :
586 raise errors . IndexerError ( "IndexerConnection has been closed" )
587 return self . _index . get_doccount ( )
588
590 """Get an iterator which returns all the ids in the database.
591
592 The unqiue_ids are currently returned in binary lexicographical sort
593 order, but this should not be relied on.
594
595 """
596 if self . _index is None :
597 raise errors . IndexerError ( "IndexerConnection has been closed" )
598 return PrefixedTermIter ( 'Q' , self . _index . allterms ( ) )
599
601 """Get the document with the specified unique ID.
602
603 Raises a KeyError if there is no such document. Otherwise, it returns
604 a ProcessedDocument.
605
606 """
607 if self . _index is None :
608 raise errors . IndexerError ( "IndexerConnection has been closed" )
609 postlist = self . _index . postlist ( 'Q' + id )
610 try :
611 plitem = postlist . next ( )
612 except StopIteration :
613
614 raise KeyError ( 'Unique ID %r not found' % id )
615 try :
616 postlist . next ( )
617 raise errors . IndexerError ( "Multiple documents "
618 "found with same unique ID" )
619 except StopIteration :
620
621 pass
622
623 result = ProcessedDocument ( self . _field_mappings )
624 result . id = id
625 result . _doc = self . _index . get_document ( plitem . docid )
626 return result
627
629 """Get an iterator over the synonyms.
630
631 - `prefix`: if specified, only synonym keys with this prefix will be
632 returned.
633
634 The iterator returns 2-tuples, in which the first item is the key (ie,
635 a 2-tuple holding the term or terms which will be synonym expanded,
636 followed by the fieldname specified (or None if no fieldname)), and the
637 second item is a tuple of strings holding the synonyms for the first
638 item.
639
640 These return values are suitable for the dict() builtin, so you can
641 write things like:
642
643 >>> conn = IndexerConnection('foo')
644 >>> conn.add_synonym('foo', 'bar')
645 >>> conn.add_synonym('foo bar', 'baz')
646 >>> conn.add_synonym('foo bar', 'foo baz')
647 >>> dict(conn.iter_synonyms())
648 {('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
649
650 """
651 if self . _index is None :
652 raise errors . IndexerError ( "IndexerConnection has been closed" )
653 return SynonymIter ( self . _index , self . _field_mappings , prefix )
654
656 """Get an iterator over the facet hierarchy.
657
658 The iterator returns 2-tuples, in which the first item is the
659 subfacet and the second item is its parent facet.
660
661 The return values are suitable for the dict() builtin, for example:
662
663 >>> conn = IndexerConnection('db')
664 >>> conn.add_field_action('foo', FieldActions.FACET)
665 >>> conn.add_field_action('bar', FieldActions.FACET)
666 >>> conn.add_field_action('baz', FieldActions.FACET)
667 >>> conn.add_subfacet('foo', 'bar')
668 >>> conn.add_subfacet('baz', 'bar')
669 >>> dict(conn.iter_subfacets())
670 {'foo': 'bar', 'baz': 'bar'}
671
672 """
673 if self . _index is None :
674 raise errors . IndexerError ( "IndexerConnection has been closed" )
675 if 'facets' in _checkxapian . missing_features :
676 raise errors . IndexerError ( "Facets unsupported with this release of xapian" )
677 return self . _facet_hierarchy . iteritems ( )
678
680 """Get an iterator over query types and their associated facets.
681
682 Only facets associated with the query types in the specified manner
683 are returned; `association` must be one of IndexerConnection.FacetQueryType_Preferred
684 or IndexerConnection.FacetQueryType_Never.
685
686 The iterator returns 2-tuples, in which the first item is the query
687 type and the second item is the associated set of facets.
688
689 The return values are suitable for the dict() builtin, for example:
690
691 >>> conn = IndexerConnection('db')
692 >>> conn.add_field_action('foo', FieldActions.FACET)
693 >>> conn.add_field_action('bar', FieldActions.FACET)
694 >>> conn.add_field_action('baz', FieldActions.FACET)
695 >>> conn.set_facet_for_query_type('type1', 'foo', conn.FacetQueryType_Preferred)
696 >>> conn.set_facet_for_query_type('type1', 'bar', conn.FacetQueryType_Never)
697 >>> conn.set_facet_for_query_type('type1', 'baz', conn.FacetQueryType_Never)
698 >>> conn.set_facet_for_query_type('type2', 'bar', conn.FacetQueryType_Preferred)
699 >>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Preferred))
700 {'type1': set(['foo']), 'type2': set(['bar'])}
701 >>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Never))
702 {'type1': set(['bar', 'baz'])}
703
704 """
705 if self . _index is None :
706 raise errors . IndexerError ( "IndexerConnection has been closed" )
707 if 'facets' in _checkxapian . missing_features :
708 raise errors . IndexerError ( "Facets unsupported with this release of xapian" )
709 return FacetQueryTypeIter ( self . _facet_query_table , association )
710
712 """Iterate through all the terms with a given prefix.
713
714 """
716 """Initialise the prefixed term iterator.
717
718 - `prefix` is the prefix to return terms for.
719 - `termiter` is a xapian TermIterator, which should be at its start.
720
721 """
722
723
724
725
726
727
728
729
730 assert ( len ( prefix ) == 1 )
731
732 self . _started = False
733 self . _prefix = prefix
734 self . _prefixlen = len ( prefix )
735 self . _termiter = termiter
736
739
741 """Get the next term with the specified prefix.
742
743 """
744 if not self . _started :
745 term = self . _termiter . skip_to ( self . _prefix ) . term
746 self . _started = True
747 else :
748 term = self . _termiter . next ( ) . term
749 if len ( term ) < self . _prefixlen or term [ : self . _prefixlen ] != self . _prefix :
750 raise StopIteration
751 return term [ self . _prefixlen : ]
752
753
755 """Iterate through a list of synonyms.
756
757 """
758 - def __init__ ( self , index , field_mappings , prefix ) :
759 """Initialise the synonym iterator.
760
761 - `index` is the index to get the synonyms from.
762 - `field_mappings` is the FieldMappings object for the iterator.
763 - `prefix` is the prefix to restrict the returned synonyms to.
764
765 """
766 self . _index = index
767 self . _field_mappings = field_mappings
768 self . _syniter = self . _index . synonym_keys ( prefix )
769
772
774 """Get the next synonym.
775
776 """
777 synkey = self . _syniter . next ( )
778 pos = 0
779 for char in synkey :
780 if char . isupper ( ) : pos += 1
781 else : break
782 if pos == 0 :
783 fieldname = None
784 terms = synkey
785 else :
786 prefix = synkey [ : pos ]
787 fieldname = self . _field_mappings . get_fieldname_from_prefix ( prefix )
788 terms = ' ' . join ( ( term [ pos : ] for term in synkey . split ( ' ' ) ) )
789 synval = tuple ( self . _index . synonyms ( synkey ) )
790 return ( ( terms , fieldname ) , synval )
791
793 """Iterate through all the query types and their associated facets.
794
795 """
796 - def __init__ ( self , facet_query_table , association ) :
797 """Initialise the query type facet iterator.
798
799 Only facets associated with each query type in the specified
800 manner are returned (`association` must be one of
801 IndexerConnection.FacetQueryType_Preferred or
802 IndexerConnection.FacetQueryType_Never).
803
804 """
805 self . _table_iter = facet_query_table . iteritems ( )
806 self . _association = association
807
810
812 """Get the next (query type, facet set) 2-tuple.
813
814 """
815 query_type , facet_dict = self . _table_iter . next ( )
816 facet_list = [ facet for facet , association in facet_dict . iteritems ( ) if association == self . _association ]
817 if len ( facet_list ) == 0 :
818 return self . next ( )
819 return ( query_type , set ( facet_list ) )
820
821 if __name__ == '__main__' :
822 import doctest , sys
823 doctest . testmod ( sys . modules [ __name__ ] )
824
xappy-0.5/docs/api/xappy.indexerconnection.FacetQueryTypeIter-class.html 0000644 0001750 0001750 00000022032 11005555243 026435 0 ustar richard richard
xappy.indexerconnection.FacetQueryTypeIter
Class FacetQueryTypeIter source code
object --+
|
FacetQueryTypeIter
Iterate through all the query types and their associated facets.
__init__ (self ,
facet_query_table ,
association )
Initialise the query type facet iterator.
source code
next (self )
Get the next (query type, facet set) 2-tuple.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
facet_query_table ,
association )
(Constructor)
source code
Initialise the query type facet iterator.
Only facets associated with each query type in the specified
manner are returned (association
must be one of
IndexerConnection.FacetQueryType_Preferred or
IndexerConnection.FacetQueryType_Never).
Overrides:
object.__init__
xappy-0.5/docs/api/xappy.indexerconnection.IndexerConnection-class.html 0000644 0001750 0001750 00000164015 11005555243 026325 0 ustar richard richard
xappy.indexerconnection.IndexerConnection
Class IndexerConnection source code
object --+
|
IndexerConnection
A connection to the search engine for indexing.
get_fields_with_actions (self )
Get a list of field names which have actions defined.
source code
process (self ,
document )
Process an UnprocessedDocument with the settings in this database.
source code
add (self ,
document )
Add a new document to the search engine index.
source code
add_synonym (self ,
original ,
synonym ,
field =None ,
original_field =None ,
synonym_field =None )
Add a synonym to the index.
source code
remove_subfacet (self ,
subfacet )
Remove any existing facet hierarchy relationship for a subfacet.
source code
get_subfacets (self ,
facet )
Get a list of subfacets of a facet.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
FacetQueryType_Preferred = 1
FacetQueryType_Never = 2
Inherited from object
:
__class__
Create a new connection to the index.
There may only be one indexer connection for a particular database open
at a given time. Therefore, if a connection to the database is already
open, this will raise a xapian.DatabaseLockError.
If the database doesn't already exist, it will be created.
Overrides:
object.__init__
set_max_mem_use (self ,
max_mem =None ,
max_mem_proportion =None )
source code
Set the maximum memory to use.
This call allows the amount of memory to use to buffer changes to be
set. This will affect the speed of indexing, but should not result in
other changes to the indexing.
Note: this is an approximate measure - the actual amount of memory used
max exceed the specified amount. Also, note that future versions of
xapian are likely to implement this differently, so this setting may be
entirely ignored.
The absolute amount of memory to use (in bytes) may be set by setting
max_mem. Alternatively, the proportion of the available memory may be
set by setting max_mem_proportion (this should be a value between 0 and
1).
Setting too low a value will result in excessive flushing, and very
slow indexing. Setting too high a value will result in excessive
buffering, leading to swapping, and very slow indexing.
A reasonable default for max_mem_proportion for a system which is
dedicated to indexing is probably 0.5: if other tasks are also being
performed on the system, the value should be lowered.
add_field_action (self ,
fieldname ,
fieldtype ,
**kwargs )
source code
Add an action to be performed on a field.
Note that this change to the configuration will not be preserved on
disk until the next call to flush().
Clear all actions for the specified field.
This does not report an error if there are already no actions for the
specified field.
Note that this change to the configuration will not be preserved on
disk until the next call to flush().
Process an UnprocessedDocument with the settings in this database.
The resulting ProcessedDocument is returned.
Note that this processing will be automatically performed if an
UnprocessedDocument is supplied to the add() or replace() methods of
IndexerConnection. This method is exposed to allow the processing to
be performed separately, which may be desirable if you wish to manually
modify the processed document before adding it to the database, or if
you want to split processing of documents from adding documents to the
database for performance reasons.
Add a new document to the search engine index.
If the document has a id set, and the id already exists in
the database, an exception will be raised. Use the replace() method
instead if you wish to overwrite documents.
Returns the id of the newly added document (making up a new
unique ID if no id was set).
The supplied document may be an instance of UnprocessedDocument, or an
instance of ProcessedDocument.
Replace a document in the search engine index.
If the document does not have a id set, an exception will be
raised.
If the document has a id set, and the id does not already
exist in the database, this method will have the same effect as add().
add_synonym (self ,
original ,
synonym ,
field =None ,
original_field =None ,
synonym_field =None )
source code
Add a synonym to the index.
original
is the word or words which will be synonym expanded in
searches (if multiple words are specified, each word should be
separated by a single space).
synonym
is a synonym for original
.
field
is the field which the synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
remove_synonym (self ,
original ,
synonym ,
field =None )
source code
Remove a synonym from the index.
original
is the word or words which will be synonym expanded in
searches (if multiple words are specified, each word should be
separated by a single space).
synonym
is a synonym for original
.
field
is the field which this synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
Remove all synonyms for a word (or phrase).
field
is the field which this synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
Add a subfacet-facet relationship to the facet hierarchy.
Any existing relationship for that subfacet is replaced.
Raises a KeyError if either facet or subfacet is not a field,
and an IndexerError if either facet or subfacet is not a facet field.
set_facet_for_query_type (self ,
query_type ,
facet ,
association )
source code
Set the association between a query type and a facet.
The value of association
must be one of
IndexerConnection.FacetQueryType_Preferred,
IndexerConnection.FacetQueryType_Never or None. A value of None removes
any previously set association.
get_facets_for_query_type (self ,
query_type ,
association )
source code
Get the set of facets associated with a query type.
Only those facets associated with the query type in the specified
manner are returned; association
must be one of
IndexerConnection.FacetQueryType_Preferred or
IndexerConnection.FacetQueryType_Never.
If the query type has no facets associated with it, None is returned.
Set an item of metadata stored in the connection.
The value supplied will be returned by subsequent calls to
get_metadata() which use the same key.
Keys with a leading underscore are reserved for internal use - you
should not use such keys unless you really know what you are doing.
This will store the value supplied in the database. It will not be
visible to readers (ie, search connections) until after the next flush.
The key is limited to about 200 characters (the same length as a term
is limited to). The value can be several megabytes in size.
To remove an item of metadata, simply call this with a value
parameter containing an empty string.
Get an item of metadata stored in the connection.
This returns a value stored by a previous call to set_metadata.
If the value is not found, this will return the empty string.
Delete a document from the search engine index.
If the id does not already exist in the database, this method
will have no effect (and will not report an error).
Apply recent changes to the database.
If an exception occurs, any changes since the last call to flush() may
be lost.
Close the connection to the database.
It is important to call this method before allowing the class to be
garbage collected, because it will ensure that any un-flushed changes
will be flushed. It also ensures that the connection is cleaned up
promptly.
No other methods may be called on the connection after this has been
called. (It is permissible to call close() multiple times, but
only the first call will have any effect.)
If an exception occurs, the database will be closed, but changes since
the last call to flush may be lost.
Count the number of documents in the database.
This count will include documents which have been added or removed but
not yet flushed().
Get an iterator which returns all the ids in the database.
The unqiue_ids are currently returned in binary lexicographical sort
order, but this should not be relied on.
Get the document with the specified unique ID.
Raises a KeyError if there is no such document. Otherwise, it returns
a ProcessedDocument.
Get an iterator over the synonyms.
prefix
: if specified, only synonym keys with this prefix will be
returned.
The iterator returns 2-tuples, in which the first item is the key (ie,
a 2-tuple holding the term or terms which will be synonym expanded,
followed by the fieldname specified (or None if no fieldname)), and the
second item is a tuple of strings holding the synonyms for the first
item.
These return values are suitable for the dict() builtin, so you can
write things like:
>>> conn = IndexerConnection('foo' )
>>> conn.add_synonym('foo' , 'bar' )
>>> conn.add_synonym('foo bar' , 'baz' )
>>> conn.add_synonym('foo bar' , 'foo baz' )
>>> dict(conn.iter_synonyms())
{('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
Get an iterator over the facet hierarchy.
The iterator returns 2-tuples, in which the first item is the
subfacet and the second item is its parent facet.
The return values are suitable for the dict() builtin, for example:
>>> conn = IndexerConnection('db' )
>>> conn.add_field_action('foo' , FieldActions.FACET)
>>> conn.add_field_action('bar' , FieldActions.FACET)
>>> conn.add_field_action('baz' , FieldActions.FACET)
>>> conn.add_subfacet('foo' , 'bar' )
>>> conn.add_subfacet('baz' , 'bar' )
>>> dict(conn.iter_subfacets())
{'foo': 'bar', 'baz': 'bar'}
Get an iterator over query types and their associated facets.
Only facets associated with the query types in the specified manner
are returned; association
must be one of IndexerConnection.FacetQueryType_Preferred
or IndexerConnection.FacetQueryType_Never.
The iterator returns 2-tuples, in which the first item is the query
type and the second item is the associated set of facets.
The return values are suitable for the dict() builtin, for example:
>>> conn = IndexerConnection('db' )
>>> conn.add_field_action('foo' , FieldActions.FACET)
>>> conn.add_field_action('bar' , FieldActions.FACET)
>>> conn.add_field_action('baz' , FieldActions.FACET)
>>> conn.set_facet_for_query_type('type1' , 'foo' , conn.FacetQueryType_Preferred)
>>> conn.set_facet_for_query_type('type1' , 'bar' , conn.FacetQueryType_Never)
>>> conn.set_facet_for_query_type('type1' , 'baz' , conn.FacetQueryType_Never)
>>> conn.set_facet_for_query_type('type2' , 'bar' , conn.FacetQueryType_Preferred)
>>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Preferred))
{'type1': set(['foo']), 'type2': set(['bar'])}
>>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Never))
{'type1': set(['bar', 'baz'])}
xappy-0.5/docs/api/xappy.indexerconnection.PrefixedTermIter-class.html 0000644 0001750 0001750 00000021675 11005555243 026135 0 ustar richard richard
xappy.indexerconnection.PrefixedTermIter
Class PrefixedTermIter source code
object --+
|
PrefixedTermIter
Iterate through all the terms with a given prefix.
next (self )
Get the next term with the specified prefix.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
prefix ,
termiter )
(Constructor)
source code
Initialise the prefixed term iterator.
prefix
is the prefix to return terms for.
termiter
is a xapian TermIterator, which should be at its start.
Overrides:
object.__init__
xappy-0.5/docs/api/xappy.indexerconnection.SynonymIter-class.html 0000644 0001750 0001750 00000022035 11005555243 025202 0 ustar richard richard
xappy.indexerconnection.SynonymIter
Class SynonymIter source code
object --+
|
SynonymIter
Iterate through a list of synonyms.
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
index ,
field_mappings ,
prefix )
(Constructor)
source code
Initialise the synonym iterator.
index
is the index to get the synonyms from.
field_mappings
is the FieldMappings object for the iterator.
prefix
is the prefix to restrict the returned synonyms to.
Overrides:
object.__init__
xappy-0.5/docs/api/xappy.marshall-module.html 0000644 0001750 0001750 00000013045 11005555242 021150 0 ustar richard richard
xappy.marshall
Module marshall source code
marshall.py: Marshal values into strings
float_to_string (value )
Marshall a floating point number to a string which sorts in the
appropriate manner.
source code
date_to_string (date )
Marshall a date to a string which sorts in the appropriate manner.
source code
xappy-0.5/docs/api/xappy.marshall-pysrc.html 0000644 0001750 0001750 00000027031 11005555243 021024 0 ustar richard richard
xappy.marshall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""marshall.py: Marshal values into strings
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import math
24 import xapian
25 from replaylog import log as _log
26
28 """Marshall a floating point number to a string which sorts in the
29 appropriate manner.
30
31 """
32 return _log ( xapian . sortable_serialise , value )
33
35 """Marshall a date to a string which sorts in the appropriate manner.
36
37 """
38 return '%04d%02d%02d' % ( date . year , date . month , date . day )
39
xappy-0.5/docs/api/xappy.memutils-module.html 0000644 0001750 0001750 00000013551 11005555242 021206 0 ustar richard richard
xappy.memutils
Module memutils source code
memutils.py: Memory handling utilities.
Get the amount of physical memory in the system, in bytes.
If this can't be obtained, returns None.
xappy-0.5/docs/api/xappy.memutils-pysrc.html 0000644 0001750 0001750 00000051443 11005555243 021064 0 ustar richard richard
xappy.memutils
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""memutils.py: Memory handling utilities.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import os
24
26 """Try getting a value for the physical memory using os.sysconf().
27
28 Returns None if no value can be obtained - otherwise, returns a value in
29 bytes.
30
31 """
32 if getattr ( os , 'sysconf' , None ) is None :
33 return None
34
35 try :
36 pagesize = os . sysconf ( 'SC_PAGESIZE' )
37 except ValueError :
38 try :
39 pagesize = os . sysconf ( 'SC_PAGE_SIZE' )
40 except ValueError :
41 return None
42
43 try :
44 pagecount = os . sysconf ( 'SC_PHYS_PAGES' )
45 except ValueError :
46 return None
47
48 return pagesize * pagecount
49
51 """Try getting a value for the physical memory using GlobalMemoryStatus.
52
53 This is a windows specific method. Returns None if no value can be
54 obtained (eg, not running on windows) - otherwise, returns a value in
55 bytes.
56
57 """
58 try :
59 import ctypes
60 import ctypes . wintypes as wintypes
61 except ValueError :
62 return None
63
64 class MEMORYSTATUS ( wintypes . Structure ) :
65 _fields_ = [
66 ( 'dwLength' , wintypes . DWORD ) ,
67 ( 'dwMemoryLoad' , wintypes . DWORD ) ,
68 ( 'dwTotalPhys' , wintypes . DWORD ) ,
69 ( 'dwAvailPhys' , wintypes . DWORD ) ,
70 ( 'dwTotalPageFile' , wintypes . DWORD ) ,
71 ( 'dwAvailPageFile' , wintypes . DWORD ) ,
72 ( 'dwTotalVirtual' , wintypes . DWORD ) ,
73 ( 'dwAvailVirtual' , wintypes . DWORD ) ,
74 ]
75
76 m = MEMORYSTATUS ( )
77 wintypes . windll . kernel32 . GlobalMemoryStatus ( wintypes . byref ( m ) )
78 return m . dwTotalPhys
79
81 """Get the amount of physical memory in the system, in bytes.
82
83 If this can't be obtained, returns None.
84
85 """
86 result = _get_physical_mem_sysconf ( )
87 if result is not None :
88 return result
89 return _get_physical_mem_win32 ( )
90
xappy-0.5/docs/api/xappy.parsedate-module.html 0000644 0001750 0001750 00000026170 11005555242 021320 0 ustar richard richard
xappy.parsedate
Module parsedate source code
parsedate.py: Parse date strings.
yyyymmdd_re = re.compile(r'(?P<
year
>
[
0-
9]
{4}
)
(?P<
month
>
[
0-
9]
{2
...
yyyy_mm_dd_re = re.compile(r'(?P<
year
>
[
0-
9]
{4}
)
(
[
-/\.]
)
(?P<
mon
...
Parse a string into a date.
If the value supplied is already a date-like object (ie, has 'year',
'month' and 'day' attributes), it is returned without processing.
Supported date formats are:
YYYYMMDD
YYYY-MM-DD
YYYY/MM/DD
YYYY.MM.DD
yyyymmdd_re
Value:
re.compile(r'(?P<
year
>
[
0-
9]
{4}
)
(?P<
month
>
[
0-
9]
{2}
)
(?P<
day
>
[
0-
9]
{2}
)
$')
yyyy_mm_dd_re
Value:
re.compile(r'(?P<
year
>
[
0-
9]
{4}
)
(
[
-/\.]
)
(?P<
month
>
[
0-
9]
{2}
)
\2
(?P<
day
>
[
0
-
9]
{2}
)
$')
xappy-0.5/docs/api/xappy.parsedate-pysrc.html 0000644 0001750 0001750 00000040044 11005555243 021170 0 ustar richard richard
xappy.parsedate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""parsedate.py: Parse date strings.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import datetime
24 import re
25
26 yyyymmdd_re = re . compile ( r'(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})$' )
27 yyyy_mm_dd_re = re . compile ( r'(?P<year>[0-9]{4})([-/.])(?P<month>[0-9]{2})\2(?P<day>[0-9]{2})$' )
28
30 """Parse a string into a date.
31
32 If the value supplied is already a date-like object (ie, has 'year',
33 'month' and 'day' attributes), it is returned without processing.
34
35 Supported date formats are:
36
37 - YYYYMMDD
38 - YYYY-MM-DD
39 - YYYY/MM/DD
40 - YYYY.MM.DD
41
42 """
43 if ( hasattr ( value , 'year' )
44 and hasattr ( value , 'month' )
45 and hasattr ( value , 'day' ) ) :
46 return value
47
48 mg = yyyymmdd_re . match ( value )
49 if mg is None :
50 mg = yyyy_mm_dd_re . match ( value )
51
52 if mg is not None :
53 year , month , day = ( int ( i ) for i in mg . group ( 'year' , 'month' , 'day' ) )
54 return datetime . date ( year , month , day )
55
56 raise ValueError ( 'Unrecognised date format' )
57
xappy-0.5/docs/api/xappy.replaylog-module.html 0000644 0001750 0001750 00000016275 11005555242 021353 0 ustar richard richard
xappy.replaylog
Module replaylog source code
replaylog.py: Log all xapian calls to a file, so that they can be replayed.
NotifyingDeleteObject
An wrapping for an object which calls a callback when its deleted.
ReplayLog
Log of xapian calls, to be replayed.
LoggedProxy
A proxy for a xapian object, which logs all calls made on the object.
LoggedProxyMethod
A proxy for a xapian method, which logs all calls made on the method.
set_replay_path (logpath )
Set the path for the replay log.
source code
log (call ,
*args )
Make a call to xapian, and log it.
source code
xappy-0.5/docs/api/xappy.replaylog-pysrc.html 0000644 0001750 0001750 00000336213 11005555243 021224 0 ustar richard richard
xappy.replaylog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""replaylog.py: Log all xapian calls to a file, so that they can be replayed.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import datetime
24 import sys
25 import thread
26 import threading
27 import time
28 import traceback
29 import types
30 import weakref
31 import xapian
32
33 from pprint import pprint
34
35
36 _replay_log = None
37
38
39 _had_replay_log = False
40
42 """An wrapping for an object which calls a callback when its deleted.
43
44 Note that the callback will be called from a __del__ method, so shouldn't
45 raise any exceptions, and probably shouldn't make new references to the
46 object supplied to it.
47
48 """
50 self . obj = obj
51 self . callback = callback
52
54 self . callback ( self . obj )
55
57 """Log of xapian calls, to be replayed.
58
59 """
60
62 """Create a new replay log.
63
64 """
65
66 self . _fd_mutex = threading . Lock ( )
67 self . _fd = file ( logpath , 'wb' )
68
69
70 self . _mutex = threading . Lock ( )
71 self . _next_call = 1
72
73 self . _next_thread = 0
74 self . _thread_ids = { }
75
76 self . _objs = weakref . WeakKeyDictionary ( )
77 self . _next_num = 1
78
79 self . _xapian_classes = { }
80 self . _xapian_functions = { }
81 self . _xapian_methods = { }
82 for name in dir ( xapian ) :
83 item = getattr ( xapian , name )
84 has_members = False
85 for membername in dir ( item ) :
86 member = getattr ( item , membername )
87 if isinstance ( member , types . MethodType ) :
88 self . _xapian_methods [ member . im_func ] = ( name , membername )
89 has_members = True
90 if has_members :
91 self . _xapian_classes [ item ] = name
92 if isinstance ( item , types . BuiltinFunctionType ) :
93 self . _xapian_functions [ item ] = name
94
96 """Get the number associated with an object.
97
98 If maybe_new is False, a value of 0 will be supplied if the object
99 hasn't already been seen. Otherwise, a new (and previously unused)
100 value will be allocated to the object.
101
102 The mutex should be held when this is called.
103
104 """
105 try :
106 num = self . _objs [ obj ]
107 return num . obj
108 except KeyError :
109 pass
110
111 if not maybe_new :
112 return 0
113
114 self . _objs [ obj ] = NotifyingDeleteObject ( self . _next_num , self . _obj_gone )
115 self . _next_num += 1
116 return self . _next_num - 1
117
119 """Return True iff an object is an instance of a xapian object.
120
121 (Also returns true if the object is an instance of a subclass of a
122 xapian object.)
123
124 The mutex should be held when this is called.
125
126 """
127
128 classname = self . _xapian_classes . get ( type ( obj ) , None )
129 if classname is not None :
130 return True
131
132 for classobj , classname in self . _xapian_classes . iteritems ( ) :
133 if isinstance ( obj , classobj ) :
134 return True
135
136 return False
137
139 """Get the name of a xapian class or method.
140
141 The mutex should be held when this is called.
142
143 """
144
145 if isinstance ( obj , types . TypeType ) :
146 classname = self . _xapian_classes . get ( obj , None )
147 if classname is not None :
148 return classname
149
150 for classobj , classname in self . _xapian_classes . iteritems ( ) :
151 if issubclass ( obj , classobj ) :
152 return "subclassof_%s" % ( classname , )
153
154 return None
155
156
157 if isinstance ( obj , types . BuiltinFunctionType ) :
158 funcname = self . _xapian_functions . get ( obj , None )
159 if funcname is not None :
160 return funcname
161
162
163 if isinstance ( obj , LoggedProxy ) :
164 classname = self . _xapian_classes . get ( obj . __class__ , None )
165 if classname is not None :
166 objnum = self . _get_obj_num ( obj , maybe_new = maybe_new )
167 return "%s#%d" % ( classname , objnum )
168
169
170 if isinstance ( obj , LoggedProxyMethod ) :
171 classname , methodname = self . _xapian_methods [ obj . real . im_func ]
172 objnum = self . _get_obj_num ( obj . proxyobj , maybe_new = maybe_new )
173 return "%s#%d.%s" % ( classname , objnum , methodname )
174
175
176
177
178 for classobj , classname in self . _xapian_classes . iteritems ( ) :
179 if isinstance ( obj , classobj ) :
180 objnum = self . _get_obj_num ( obj , maybe_new = maybe_new )
181 return "subclassof_%s#%d" % ( classname , objnum )
182
183 return None
184
185 - def _log ( self , msg ) :
186 self . _fd_mutex . acquire ( )
187 try :
188
189
190
191
192 self . _fd . write ( msg )
193 self . _fd . flush ( )
194 finally :
195 self . _fd_mutex . release ( )
196
198 """Return a representation of an argument.
199
200 The mutex should be held when this is called.
201
202 """
203
204 xapargname = self . _get_xap_name ( arg )
205 if xapargname is not None :
206 return xapargname
207
208 if isinstance ( arg , basestring ) :
209 if isinstance ( arg , unicode ) :
210 arg = arg . encode ( 'utf-8' )
211 return 'str(%d,%s)' % ( len ( arg ) , arg )
212
213 if isinstance ( arg , long ) :
214 try :
215 arg = int ( arg )
216 except OverFlowError :
217 pass
218
219 if isinstance ( arg , long ) :
220 return 'long(%d)' % arg
221
222 if isinstance ( arg , int ) :
223 return 'int(%d)' % arg
224
225 if isinstance ( arg , float ) :
226 return 'float(%f)' % arg
227
228 if arg is None :
229 return 'None'
230
231 if hasattr ( arg , '__iter__' ) :
232 seq = [ ]
233 for item in arg :
234 seq . append ( self . _repr_arg ( item ) )
235 return 'list(%s)' % ',' . join ( seq )
236
237 return 'UNKNOWN:' + str ( arg )
238
240 """Return a representation of a list of arguments.
241
242 The mutex should be held when this is called.
243
244 """
245 logargs = [ ]
246 for arg in args :
247 logargs . append ( self . _repr_arg ( arg ) )
248 return ',' . join ( logargs )
249
251 """Get an ID string for a call.
252
253 The mutex should be held when this is called.
254
255 """
256 call_num = self . _next_call
257 self . _next_call += 1
258
259 thread_id = thread . get_ident ( )
260 try :
261 thread_num = self . _thread_ids [ thread_id ]
262 except KeyError :
263 thread_num = self . _next_thread
264 self . _thread_ids [ thread_id ] = thread_num
265 self . _next_thread += 1
266
267 if thread_num is 0 :
268 return "%s" % call_num
269 return "%dT%d" % ( call_num , thread_num )
270
272 """Add a log message about a call.
273
274 Returns a number for the call, so it can be tied to a particular
275 result.
276
277 """
278 self . _mutex . acquire ( )
279 try :
280 logargs = self . _repr_args ( args )
281 xapobjname = self . _get_xap_name ( call )
282 call_id = self . _get_call_id ( )
283 finally :
284 self . _mutex . release ( )
285
286 if xapobjname is not None :
287 self . _log ( "CALL%s:%s(%s)\n" % ( call_id , xapobjname , logargs ) )
288 else :
289 self . _log ( "CALL%s:UNKNOWN:%r(%s)\n" % ( call_id , call , logargs ) )
290 return call_id
291
292 - def log_except ( self , ( etype , value , tb ) , call_id ) :
293 """Log an exception which has occurred.
294
295 """
296
297 exc = traceback . format_exception_only ( etype , value )
298 self . _log ( "EXCEPT%s:%s\n" % ( call_id , '' . join ( exc ) . strip ( ) ) )
299
301 """Log a return value.
302
303 """
304 if ret is None :
305 self . _log ( "RET%s:None\n" % call_id )
306 return
307
308 self . _mutex . acquire ( )
309 try :
310
311 if self . _is_xap_obj ( ret ) :
312 ret = LoggedProxy ( ret )
313 xapobjname = self . _get_xap_name ( ret , maybe_new = True )
314 msg = "RET%s:%s\n" % ( call_id , self . _repr_arg ( ret ) )
315 finally :
316 self . _mutex . release ( )
317
318
319 self . _log ( msg )
320 return ret
321
323 """Log that an object has been deleted.
324
325 """
326 self . _log ( 'DEL:#%d\n' % num )
327
329 """A proxy for a xapian object, which logs all calls made on the object.
330
331 """
334
336 obj = object . __getattribute__ ( self , '_LoggedProxy__obj' )
337 if name == '__obj' :
338 return obj
339 real = getattr ( obj , name )
340 if not isinstance ( real , types . MethodType ) :
341 return real
342 return LoggedProxyMethod ( real , self )
343
347
351
355
359
361 """A proxy for a xapian method, which logs all calls made on the method.
362
363 """
365 """Make a proxy for the method.
366
367 """
368 self . real = real
369 self . proxyobj = proxyobj
370
372 """Call the proxied method, logging the call.
373
374 """
375 return log ( self , * args )
376
388
390 """Convert a call and list of arguments to unproxied form.
391
392 """
393 if isinstance ( call , LoggedProxyMethod ) :
394 realcall = call . real
395 else :
396 realcall = call
397
398 realargs = [ ]
399 for arg in args :
400 if isinstance ( arg , LoggedProxy ) :
401 arg = arg . __obj
402 realargs . append ( arg )
403
404 return realcall , realargs
405
406 - def log ( call , * args ) :
407 """Make a call to xapian, and log it.
408
409 """
410
411 global _had_replay_log
412 if not _had_replay_log :
413 return call ( * args )
414
415
416 realcall , realargs = _unproxy_call_and_args ( call , args )
417
418
419 global _replay_log
420 replay_log = _replay_log
421 if replay_log is None :
422 return realcall ( * realargs )
423
424
425 call_id = replay_log . log_call ( call , * args )
426 try :
427 ret = realcall ( * realargs )
428 except :
429 replay_log . log_except ( sys . exc_info ( ) , call_id )
430 raise
431 return replay_log . log_retval ( ret , call_id )
432
433
434
xappy-0.5/docs/api/xappy.replaylog.LoggedProxy-class.html 0000644 0001750 0001750 00000031734 11005555243 023433 0 ustar richard richard
xappy.replaylog.LoggedProxy
Class LoggedProxy source code
object --+
|
LoggedProxy
A proxy for a xapian object, which logs all calls made on the object.
__init__ (self ,
obj )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
x.__getattribute__('name') <==> x.name
Overrides:
object.__getattribute__
(inherited documentation)
repr(x)
Overrides:
object.__repr__
(inherited documentation)
__str__ (self )
(Informal representation operator)
source code
str(x)
Overrides:
object.__str__
(inherited documentation)
xappy-0.5/docs/api/xappy.replaylog.LoggedProxyMethod-class.html 0000644 0001750 0001750 00000020125 11005555243 024564 0 ustar richard richard
xappy.replaylog.LoggedProxyMethod
Class LoggedProxyMethod source code
object --+
|
LoggedProxyMethod
A proxy for a xapian method, which logs all calls made on the method.
__call__ (self ,
*args )
Call the proxied method, logging the call.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
real ,
proxyobj )
(Constructor)
source code
Make a proxy for the method.
Overrides:
object.__init__
xappy-0.5/docs/api/xappy.replaylog.NotifyingDeleteObject-class.html 0000644 0001750 0001750 00000020534 11005555243 025404 0 ustar richard richard
xappy.replaylog.NotifyingDeleteObject
Class NotifyingDeleteObject source code
object --+
|
NotifyingDeleteObject
An wrapping for an object which calls a callback when its deleted.
Note that the callback will be called from a __del__ method, so shouldn't
raise any exceptions, and probably shouldn't make new references to the
object supplied to it.
__init__ (self ,
obj ,
callback )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
obj ,
callback )
(Constructor)
source code
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
xappy-0.5/docs/api/xappy.replaylog.ReplayLog-class.html 0000644 0001750 0001750 00000024430 11005555243 023061 0 ustar richard richard
xappy.replaylog.ReplayLog
Class ReplayLog source code
object --+
|
ReplayLog
Log of xapian calls, to be replayed.
log_except (self ,
(etype, value, tb) ,
call_id )
Log an exception which has occurred.
source code
log_retval (self ,
ret ,
call_id )
Log a return value.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
Create a new replay log.
Overrides:
object.__init__
Add a log message about a call.
Returns a number for the call, so it can be tied to a particular
result.
xappy-0.5/docs/api/xappy.schema-module.html 0000644 0001750 0001750 00000010542 11005555242 020604 0 ustar richard richard
xappy.schema
Module schema source code
schema.py: xdefinitions and implementations of field actions.
xappy-0.5/docs/api/xappy.schema-pysrc.html 0000644 0001750 0001750 00000025614 11005555243 020466 0 ustar richard richard
xappy.schema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""schema.py: xdefinitions and implementations of field actions.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import errors as _errors
24 from replaylog import log as _log
25 import parsedate as _parsedate
26
30
31 if __name__ == '__main__' :
32 import doctest , sys
33 doctest . testmod ( sys . modules [ __name__ ] )
34
xappy-0.5/docs/api/xappy.schema.Schema-class.html 0000644 0001750 0001750 00000016155 11005555243 021632 0 ustar richard richard
xappy.schema.Schema
Class Schema source code
object --+
|
Schema
__init__ (self )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
xappy-0.5/docs/api/xappy.searchconnection-module.html 0000644 0001750 0001750 00000012655 11005555242 022700 0 ustar richard richard
xappy.searchconnection
Module searchconnection source code
searchconnection.py: A connection to the search engine for searching.
xappy-0.5/docs/api/xappy.searchconnection-pysrc.html 0000644 0001750 0001750 00001753676 11005555243 022574 0 ustar richard richard
xappy.searchconnection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 r"""searchconnection.py: A connection to the search engine for searching.
19
20 """
21 __docformat__ = "restructuredtext en"
22
23 import _checkxapian
24 import os as _os
25 import cPickle as _cPickle
26 import math
27
28 import xapian as _xapian
29 from datastructures import *
30 from fieldactions import *
31 import fieldmappings as _fieldmappings
32 import highlight as _highlight
33 import errors as _errors
34 import indexerconnection as _indexerconnection
35 import re as _re
36 from replaylog import log as _log
37
39 """A result from a search.
40
41 As well as being a ProcessedDocument representing the document in the
42 database, the result has several members which may be used to get
43 information about how well the document matches the search:
44
45 - `rank`: The rank of the document in the search results, starting at 0
46 (ie, 0 is the "top" result, 1 is the second result, etc).
47
48 - `weight`: A floating point number indicating the weight of the result
49 document. The value is only meaningful relative to other results for a
50 given search - a different search, or the same search with a different
51 database, may give an entirely different scale to the weights. This
52 should not usually be displayed to users, but may be useful if trying to
53 perform advanced reweighting operations on search results.
54
55 - `percent`: A percentage value for the weight of a document. This is
56 just a rescaled form of the `weight` member. It doesn't represent any
57 kind of probability value; the only real meaning of the numbers is that,
58 within a single set of results, a document with a higher percentage
59 corresponds to a better match. Because the percentage doesn't really
60 represent a probability, or a confidence value, it is probably unhelpful
61 to display it to most users, since they tend to place an over emphasis
62 on its meaning. However, it is included because it may be useful
63 occasionally.
64
65 """
67 ProcessedDocument . __init__ ( self , results . _fieldmappings , msetitem . document )
68 self . rank = msetitem . rank
69 self . weight = msetitem . weight
70 self . percent = msetitem . percent
71 self . _results = results
72
74 """Get the language that should be used for a given field.
75
76 Raises a KeyError if the field is not known.
77
78 """
79 actions = self . _results . _conn . _field_actions [ field ] . _actions
80 for action , kwargslist in actions . iteritems ( ) :
81 if action == FieldActions . INDEX_FREETEXT :
82 for kwargs in kwargslist :
83 try :
84 return kwargs [ 'language' ]
85 except KeyError :
86 pass
87 return 'none'
88
89 - def summarise ( self , field , maxlen = 600 , hl = ( '<b>' , '</b>' ) , query = None ) :
90 """Return a summarised version of the field specified.
91
92 This will return a summary of the contents of the field stored in the
93 search result, with words which match the query highlighted.
94
95 The maximum length of the summary (in characters) may be set using the
96 maxlen parameter.
97
98 The return value will be a string holding the summary, with
99 highlighting applied. If there are multiple instances of the field in
100 the document, the instances will be joined with a newline character.
101
102 To turn off highlighting, set hl to None. Each highlight will consist
103 of the first entry in the `hl` list being placed before the word, and
104 the second entry in the `hl` list being placed after the word.
105
106 Any XML or HTML style markup tags in the field will be stripped before
107 the summarisation algorithm is applied.
108
109 If `query` is supplied, it should contain a Query object, as returned
110 from SearchConnection.query_parse() or related methods, which will be
111 used as the basis of the summarisation and highlighting rather than the
112 query which was used for the search.
113
114 Raises KeyError if the field is not known.
115
116 """
117 highlighter = _highlight . Highlighter ( language_code = self . _get_language ( field ) )
118 field = self . data [ field ]
119 results = [ ]
120 text = '\n' . join ( field )
121 if query is None :
122 query = self . _results . _query
123 return highlighter . makeSample ( text , query , maxlen , hl )
124
125 - def highlight ( self , field , hl = ( '<b>' , '</b>' ) , strip_tags = False , query = None ) :
126 """Return a highlighted version of the field specified.
127
128 This will return all the contents of the field stored in the search
129 result, with words which match the query highlighted.
130
131 The return value will be a list of strings (corresponding to the list
132 of strings which is the raw field data).
133
134 Each highlight will consist of the first entry in the `hl` list being
135 placed before the word, and the second entry in the `hl` list being
136 placed after the word.
137
138 If `strip_tags` is True, any XML or HTML style markup tags in the field
139 will be stripped before highlighting is applied.
140
141 If `query` is supplied, it should contain a Query object, as returned
142 from SearchConnection.query_parse() or related methods, which will be
143 used as the basis of the summarisation and highlighting rather than the
144 query which was used for the search.
145
146 Raises KeyError if the field is not known.
147
148 """
149 highlighter = _highlight . Highlighter ( language_code = self . _get_language ( field ) )
150 field = self . data [ field ]
151 results = [ ]
152 if query is None :
153 query = self . _results . _query
154 for text in field :
155 results . append ( highlighter . highlight ( text , query , hl , strip_tags ) )
156 return results
157
159 return ( '<SearchResult(rank=%d, id=%r, data=%r)>' %
160 ( self . rank , self . id , self . data ) )
161
162
164 """An iterator over a set of results from a search.
165
166 """
168 self . _results = results
169 self . _order = order
170 if self . _order is None :
171 self . _iter = iter ( results . _mset )
172 else :
173 self . _iter = iter ( self . _order )
174
176 if self . _order is None :
177 msetitem = self . _iter . next ( )
178 else :
179 index = self . _iter . next ( )
180 msetitem = self . _results . _mset . get_hit ( index )
181 return SearchResult ( msetitem , self . _results )
182
183
185 """Get the significant digits of value which are constrained by the
186 (inclusive) lower and upper bounds.
187
188 If there are no significant digits which are definitely within the
189 bounds, exactly one significant digit will be returned in the result.
190
191 >>> _get_significant_digits(15,15,15)
192 15
193 >>> _get_significant_digits(15,15,17)
194 20
195 >>> _get_significant_digits(4777,208,6000)
196 5000
197 >>> _get_significant_digits(4777,4755,4790)
198 4800
199 >>> _get_significant_digits(4707,4695,4710)
200 4700
201 >>> _get_significant_digits(4719,4717,4727)
202 4720
203 >>> _get_significant_digits(0,0,0)
204 0
205 >>> _get_significant_digits(9,9,10)
206 9
207 >>> _get_significant_digits(9,9,100)
208 9
209
210 """
211 assert ( lower <= value )
212 assert ( value <= upper )
213 diff = upper - lower
214
215
216
217 if diff == 0 :
218 pos_pow_10 = 1
219 else :
220 pos_pow_10 = int ( 10 ** math . ceil ( math . log10 ( diff ) ) )
221
222
223
224 if pos_pow_10 > value :
225 if value == 0 :
226 pos_pow_10 = 1
227 else :
228 pos_pow_10 = int ( 10 ** math . floor ( math . log10 ( value ) ) )
229
230
231 return ( ( value + pos_pow_10 // 2 ) // pos_pow_10 ) * pos_pow_10
232
234 """A set of results of a search.
235
236 """
237 - def __init__ ( self , conn , enq , query , mset , fieldmappings , tagspy ,
238 tagfields , facetspy , facetfields , facethierarchy ,
239 facetassocs ) :
240 self . _conn = conn
241 self . _enq = enq
242 self . _query = query
243 self . _mset = mset
244 self . _mset_order = None
245 self . _fieldmappings = fieldmappings
246 self . _tagspy = tagspy
247 if tagfields is None :
248 self . _tagfields = None
249 else :
250 self . _tagfields = set ( tagfields )
251 self . _facetspy = facetspy
252 self . _facetfields = facetfields
253 self . _facethierarchy = facethierarchy
254 self . _facetassocs = facetassocs
255 self . _numeric_ranges_built = { }
256
257 - def _cluster ( self , num_clusters , maxdocs , fields = None ) :
258 """Cluster results based on similarity.
259
260 Note: this method is experimental, and will probably disappear or
261 change in the future.
262
263 The number of clusters is specified by num_clusters: unless there are
264 too few results, there will be exaclty this number of clusters in the
265 result.
266
267 """
268 clusterer = _xapian . ClusterSingleLink ( )
269 xapclusters = _xapian . ClusterAssignments ( )
270 docsim = _xapian . DocSimCosine ( )
271 source = _xapian . MSetDocumentSource ( self . _mset , maxdocs )
272
273 if fields is None :
274 clusterer . cluster ( self . _conn . _index , xapclusters , docsim , source , num_clusters )
275 else :
276 decider = self . _make_expand_decider ( fields )
277 clusterer . cluster ( self . _conn . _index , xapclusters , docsim , source , decider , num_clusters )
278
279 newid = 0
280 idmap = { }
281 clusters = { }
282 for item in self . _mset :
283 docid = item . docid
284 clusterid = xapclusters . cluster ( docid )
285 if clusterid not in idmap :
286 idmap [ clusterid ] = newid
287 newid += 1
288 clusterid = idmap [ clusterid ]
289 if clusterid not in clusters :
290 clusters [ clusterid ] = [ ]
291 clusters [ clusterid ] . append ( item . rank )
292 return clusters
293
295 """Reorder the mset based on some clusters.
296
297 """
298 if self . startrank != 0 :
299 raise _errors . SearchError ( "startrank must be zero to reorder by clusters" )
300 reordered = False
301 tophits = [ ]
302 nottophits = [ ]
303
304 clusterstarts = dict ( ( ( c [ 0 ] , None ) for c in clusters . itervalues ( ) ) )
305 for i in xrange ( self . endrank ) :
306 if i in clusterstarts :
307 tophits . append ( i )
308 else :
309 nottophits . append ( i )
310 self . _mset_order = tophits
311 self . _mset_order . extend ( nottophits )
312
314 """Make an expand decider which accepts only terms in the specified
315 field.
316
317 """
318 prefixes = { }
319 if isinstance ( fields , basestring ) :
320 fields = [ fields ]
321 for field in fields :
322 try :
323 actions = self . _conn . _field_actions [ field ] . _actions
324 except KeyError :
325 continue
326 for action , kwargslist in actions . iteritems ( ) :
327 if action == FieldActions . INDEX_FREETEXT :
328 prefix = self . _conn . _field_mappings . get_prefix ( field )
329 prefixes [ prefix ] = None
330 prefixes [ 'Z' + prefix ] = None
331 if action in ( FieldActions . INDEX_EXACT ,
332 FieldActions . TAG ,
333 FieldActions . FACET , ) :
334 prefix = self . _conn . _field_mappings . get_prefix ( field )
335 prefixes [ prefix ] = None
336 prefix_re = _re . compile ( '|' . join ( [ _re . escape ( x ) + '[^A-Z]' for x in prefixes . keys ( ) ] ) )
337 class decider ( _xapian . ExpandDecider ) :
338 def __call__ ( self , term ) :
339 return prefix_re . match ( term ) is not None
340 return decider ( )
341
344 """Reorder results based on similarity.
345
346 The top `count` documents will be chosen such that they are relatively
347 dissimilar. `maxcount` documents will be considered for moving around,
348 and `max_similarity` is a value between 0 and 1 indicating the maximum
349 similarity to the previous document before a document is moved down the
350 result set.
351
352 Note: this method is experimental, and will probably disappear or
353 change in the future.
354
355 """
356 if self . startrank != 0 :
357 raise _errors . SearchError ( "startrank must be zero to reorder by similiarity" )
358 ds = _xapian . DocSimCosine ( )
359 ds . set_termfreqsource ( _xapian . DatabaseTermFreqSource ( self . _conn . _index ) )
360
361 if fields is not None :
362 ds . set_expand_decider ( self . _make_expand_decider ( fields ) )
363
364 tophits = [ ]
365 nottophits = [ ]
366 full = False
367 reordered = False
368
369 sim_count = 0
370 new_order = [ ]
371 end = min ( self . endrank , maxcount )
372 for i in xrange ( end ) :
373 if full :
374 new_order . append ( i )
375 continue
376 hit = self . _mset . get_hit ( i )
377 if len ( tophits ) == 0 :
378 tophits . append ( hit )
379 continue
380
381
382 maxsim = 0.0
383 for tophit in tophits [ - 1 : ] :
384 sim_count += 1
385 sim = ds . similarity ( hit . document , tophit . document )
386 if sim > maxsim :
387 maxsim = sim
388
389
390 if maxsim < max_similarity :
391 tophits . append ( hit )
392 else :
393 nottophits . append ( hit )
394 reordered = True
395
396
397 if len ( tophits ) >= count :
398 for hit in tophits :
399 new_order . append ( hit . rank )
400 for hit in nottophits :
401 new_order . append ( hit . rank )
402 full = True
403 if not full :
404 for hit in tophits :
405 new_order . append ( hit . rank )
406 for hit in nottophits :
407 new_order . append ( hit . rank )
408 if end != self . endrank :
409 new_order . extend ( range ( end , self . endrank ) )
410 assert len ( new_order ) == self . endrank
411 if reordered :
412 self . _mset_order = new_order
413 else :
414 assert new_order == range ( self . endrank )
415
417 return ( "<SearchResults(startrank=%d, "
418 "endrank=%d, "
419 "more_matches=%s, "
420 "matches_lower_bound=%d, "
421 "matches_upper_bound=%d, "
422 "matches_estimated=%d, "
423 "estimate_is_exact=%s)>" %
424 (
425 self . startrank ,
426 self . endrank ,
427 self . more_matches ,
428 self . matches_lower_bound ,
429 self . matches_upper_bound ,
430 self . matches_estimated ,
431 self . estimate_is_exact ,
432 ) )
433
438 more_matches = property ( _get_more_matches , doc =
439 """Check whether there are further matches after those in this result set.
440
441 """ )
442
444 return self . _mset . get_firstitem ( )
445 startrank = property ( _get_startrank , doc =
446 """Get the rank of the first item in the search results.
447
448 This corresponds to the "startrank" parameter passed to the search() method.
449
450 """ )
451
453 return self . _mset . get_firstitem ( ) + len ( self . _mset )
454 endrank = property ( _get_endrank , doc =
455 """Get the rank of the item after the end of the search results.
456
457 If there are sufficient results in the index, this corresponds to the
458 "endrank" parameter passed to the search() method.
459
460 """ )
461
463 return self . _mset . get_matches_lower_bound ( )
464 matches_lower_bound = property ( _get_lower_bound , doc =
465 """Get a lower bound on the total number of matching documents.
466
467 """ )
468
470 return self . _mset . get_matches_upper_bound ( )
471 matches_upper_bound = property ( _get_upper_bound , doc =
472 """Get an upper bound on the total number of matching documents.
473
474 """ )
475
477 lower = self . _mset . get_matches_lower_bound ( )
478 upper = self . _mset . get_matches_upper_bound ( )
479 est = self . _mset . get_matches_estimated ( )
480 return _get_significant_digits ( est , lower , upper )
481 matches_human_readable_estimate = property ( _get_human_readable_estimate ,
482 doc =
483 """Get a human readable estimate of the number of matching documents.
484
485 This consists of the value returned by the "matches_estimated" property,
486 rounded to an appropriate number of significant digits (as determined by
487 the values of the "matches_lower_bound" and "matches_upper_bound"
488 properties).
489
490 """ )
491
493 return self . _mset . get_matches_estimated ( )
494 matches_estimated = property ( _get_estimated , doc =
495 """Get an estimate for the total number of matching documents.
496
497 """ )
498
500 return self . _mset . get_matches_lower_bound ( ) == \
501 self . _mset . get_matches_upper_bound ( )
502 estimate_is_exact = property ( _estimate_is_exact , doc =
503 """Check whether the estimated number of matching documents is exact.
504
505 If this returns true, the estimate given by the `matches_estimated`
506 property is guaranteed to be correct.
507
508 If this returns false, it is possible that the actual number of matching
509 documents is different from the number given by the `matches_estimated`
510 property.
511
512 """ )
513
515 """Get the hit with a given index.
516
517 """
518 if self . _mset_order is None :
519 msetitem = self . _mset . get_hit ( index )
520 else :
521 msetitem = self . _mset . get_hit ( self . _mset_order [ index ] )
522 return SearchResult ( msetitem , self )
523 __getitem__ = get_hit
524
526 """Get an iterator over the hits in the search result.
527
528 The iterator returns the results in increasing order of rank.
529
530 """
531 return SearchResultIter ( self , self . _mset_order )
532
534 """Get the number of hits in the search result.
535
536 Note that this is not (usually) the number of matching documents for
537 the search. If startrank is non-zero, it's not even the rank of the
538 last document in the search result. It's simply the number of hits
539 stored in the search result.
540
541 It is, however, the number of items returned by the iterator produced
542 by calling iter() on this SearchResults object.
543
544 """
545 return len ( self . _mset )
546
565
566 - def get_suggested_facets ( self , maxfacets = 5 , desired_num_of_categories = 7 ,
567 required_facets = None ) :
568 """Get a suggested set of facets, to present to the user.
569
570 This returns a list, in descending order of the usefulness of the
571 facet, in which each item is a tuple holding:
572
573 - fieldname of facet.
574 - sequence of 2-tuples holding the suggested values or ranges for that
575 field:
576
577 For facets of type 'string', the first item in the 2-tuple will
578 simply be the string supplied when the facet value was added to its
579 document. For facets of type 'float', it will be a 2-tuple, holding
580 floats giving the start and end of the suggested value range.
581
582 The second item in the 2-tuple will be the frequency of the facet
583 value or range in the result set.
584
585 If required_facets is not None, it must be a field name, or a sequence
586 of field names. Any field names mentioned in required_facets will be
587 returned if there are any facet values at all in the search results for
588 that field. The facet will only be omitted if there are no facet
589 values at all for the field.
590
591 The value of maxfacets will be respected as far as possible; the
592 exception is that if there are too many fields listed in
593 required_facets with at least one value in the search results, extra
594 facets will be returned (ie, obeying the required_facets parameter is
595 considered more important than the maxfacets parameter).
596
597 If facet_hierarchy was indicated when search() was called, and the
598 query included facets, then only subfacets of those query facets and
599 top-level facets will be included in the returned list. Furthermore
600 top-level facets will only be returned if there are remaining places
601 in the list after it has been filled with subfacets. Note that
602 required_facets is still respected regardless of the facet hierarchy.
603
604 If a query type was specified when search() was called, and the query
605 included facets, then facets with an association of Never to the
606 query type are never returned, even if mentioned in required_facets.
607 Facets with an association of Preferred are listed before others in
608 the returned list.
609
610 """
611 if 'facets' in _checkxapian . missing_features :
612 raise errors . SearchError ( "Facets unsupported with this release of xapian" )
613 if self . _facetspy is None :
614 raise _errors . SearchError ( "Facet selection wasn't enabled when the search was run" )
615 if isinstance ( required_facets , basestring ) :
616 required_facets = [ required_facets ]
617 scores = [ ]
618 facettypes = { }
619 for field , slot , kwargslist in self . _facetfields :
620 type = None
621 for kwargs in kwargslist :
622 type = kwargs . get ( 'type' , None )
623 if type is not None : break
624 if type is None : type = 'string'
625
626 if type == 'float' :
627 if field not in self . _numeric_ranges_built :
628 self . _facetspy . build_numeric_ranges ( slot , desired_num_of_categories )
629 self . _numeric_ranges_built [ field ] = None
630 facettypes [ field ] = type
631 score = self . _facetspy . score_categorisation ( slot , desired_num_of_categories )
632 scores . append ( ( score , field , slot ) )
633
634
635
636 if self . _facethierarchy :
637
638 scores = [ ( tuple [ - 2 ] not in self . _facethierarchy , ) + tuple for tuple in scores ]
639 if self . _facetassocs :
640 preferred = _indexerconnection . IndexerConnection . FacetQueryType_Preferred
641 scores = [ ( self . _facetassocs . get ( tuple [ - 2 ] ) != preferred , ) + tuple for tuple in scores ]
642 scores . sort ( )
643 if self . _facethierarchy :
644 index = 1
645 else :
646 index = 0
647 if self . _facetassocs :
648 index += 1
649 if index > 0 :
650 scores = [ tuple [ index : ] for tuple in scores ]
651
652 results = [ ]
653 required_results = [ ]
654 for score , field , slot in scores :
655
656 required = False
657 if required_facets is not None :
658 required = field in required_facets
659
660
661 if not required and len ( results ) + len ( required_results ) >= maxfacets :
662 continue
663
664
665 values = self . _facetspy . get_values_as_dict ( slot )
666 if field in self . _numeric_ranges_built :
667 if '' in values :
668 del values [ '' ]
669
670
671
672 if required :
673 if len ( values ) < 1 :
674 continue
675 else :
676 if len ( values ) <= 1 :
677 continue
678
679 newvalues = [ ]
680 if facettypes [ field ] == 'float' :
681
682
683 for value , frequency in values . iteritems ( ) :
684 if len ( value ) <= 9 :
685 value1 = _log ( _xapian . sortable_unserialise , value )
686 value2 = value1
687 else :
688 value1 = _log ( _xapian . sortable_unserialise , value [ : 9 ] )
689 value2 = _log ( _xapian . sortable_unserialise , value [ 9 : ] )
690 newvalues . append ( ( ( value1 , value2 ) , frequency ) )
691 else :
692 for value , frequency in values . iteritems ( ) :
693 newvalues . append ( ( value , frequency ) )
694
695 newvalues . sort ( )
696 if required :
697 required_results . append ( ( score , field , newvalues ) )
698 else :
699 results . append ( ( score , field , newvalues ) )
700
701
702
703 maxfacets = maxfacets - len ( required_results )
704 if maxfacets <= 0 :
705 results = required_results
706 else :
707 results = results [ : maxfacets ]
708 results . extend ( required_results )
709 results . sort ( )
710
711
712
713 results = [ ( field , newvalues ) for ( score , field , newvalues ) in results ]
714 return results
715
716
718 """A connection to the search engine for searching.
719
720 The connection will access a view of the database.
721
722 """
723 _qp_flags_base = _xapian . QueryParser . FLAG_LOVEHATE
724 _qp_flags_phrase = _xapian . QueryParser . FLAG_PHRASE
725 _qp_flags_synonym = ( _xapian . QueryParser . FLAG_AUTO_SYNONYMS |
726 _xapian . QueryParser . FLAG_AUTO_MULTIWORD_SYNONYMS )
727 _qp_flags_bool = _xapian . QueryParser . FLAG_BOOLEAN
728
729 _index = None
730
732 """Create a new connection to the index for searching.
733
734 There may only an arbitrary number of search connections for a
735 particular database open at a given time (regardless of whether there
736 is a connection for indexing open as well).
737
738 If the database doesn't exist, an exception will be raised.
739
740 """
741 self . _index = _log ( _xapian . Database , indexpath )
742 self . _indexpath = indexpath
743
744
745 self . _load_config ( )
746
747 self . _close_handlers = [ ]
748
751
753 """Append a callback to the list of close handlers.
754
755 These will be called when the SearchConnection is closed. This happens
756 when the close() method is called, or when the SearchConnection object
757 is deleted. The callback will be passed two arguments: the path to the
758 SearchConnection object, and the userdata supplied to this method.
759
760 The handlers will be called in the order in which they were added.
761
762 The handlers will be called after the connection has been closed, so
763 cannot prevent it closing: their return value will be ignored. In
764 addition, they should not raise any exceptions.
765
766 """
767 self . _close_handlers . append ( ( handler , userdata ) )
768
770 """Get the sort type that should be used for a given field.
771
772 """
773 try :
774 actions = self . _field_actions [ field ] . _actions
775 except KeyError :
776 actions = { }
777 for action , kwargslist in actions . iteritems ( ) :
778 if action == FieldActions . SORT_AND_COLLAPSE :
779 for kwargs in kwargslist :
780 return kwargs [ 'type' ]
781
783 """Load the configuration for the database.
784
785 """
786
787
788 assert self . _index is not None
789
790 config_str = _log ( self . _index . get_metadata , '_xappy_config' )
791 if len ( config_str ) == 0 :
792 self . _field_actions = { }
793 self . _field_mappings = _fieldmappings . FieldMappings ( )
794 self . _facet_hierarchy = { }
795 self . _facet_query_table = { }
796 return
797
798 try :
799 ( self . _field_actions , mappings , self . _facet_hierarchy , self . _facet_query_table , self . _next_docid ) = _cPickle . loads ( config_str )
800 except ValueError :
801
802 ( self . _field_actions , mappings , self . _next_docid ) = _cPickle . loads ( config_str )
803 self . _facet_hierarchy = { }
804 self . _facet_query_table = { }
805 self . _field_mappings = _fieldmappings . FieldMappings ( mappings )
806
808 """Reopen the connection.
809
810 This updates the revision of the index which the connection references
811 to the latest flushed revision.
812
813 """
814 if self . _index is None :
815 raise _errors . SearchError ( "SearchConnection has been closed" )
816 self . _index . reopen ( )
817
818 self . _load_config ( )
819
821 """Close the connection to the database.
822
823 It is important to call this method before allowing the class to be
824 garbage collected to ensure that the connection is cleaned up promptly.
825
826 No other methods may be called on the connection after this has been
827 called. (It is permissible to call close() multiple times, but
828 only the first call will have any effect.)
829
830 If an exception occurs, the database will be closed, but changes since
831 the last call to flush may be lost.
832
833 """
834 if self . _index is None :
835 return
836
837
838 indexpath = self . _indexpath
839
840
841
842
843
844
845
846
847 self . _index = None
848 self . _indexpath = None
849 self . _field_actions = None
850 self . _field_mappings = None
851
852
853 for handler , userdata in self . _close_handlers :
854 try :
855 handler ( indexpath , userdata )
856 except Exception , e :
857 import sys , traceback
858 print >> sys . stderr , "WARNING: unhandled exception in handler called by SearchConnection.close(): %s" % traceback . format_exception_only ( type ( e ) , e )
859
861 """Count the number of documents in the database.
862
863 This count will include documents which have been added or removed but
864 not yet flushed().
865
866 """
867 if self . _index is None :
868 raise _errors . SearchError ( "SearchConnection has been closed" )
869 return self . _index . get_doccount ( )
870
871 OP_AND = _xapian . Query . OP_AND
872 OP_OR = _xapian . Query . OP_OR
874 """Build a composite query from a list of queries.
875
876 The queries are combined with the supplied operator, which is either
877 SearchConnection.OP_AND or SearchConnection.OP_OR.
878
879 """
880 if self . _index is None :
881 raise _errors . SearchError ( "SearchConnection has been closed" )
882 return _log ( _xapian . Query , operator , list ( queries ) )
883
885 """Build a query which modifies the weights of a subquery.
886
887 This produces a query which returns the same documents as the subquery,
888 and in the same order, but with the weights assigned to each document
889 multiplied by the value of "multiplier". "multiplier" may be any floating
890 point value, but negative values will be clipped to 0, since Xapian
891 doesn't support negative weights.
892
893 This can be useful when producing queries to be combined with
894 query_composite, because it allows the relative importance of parts of
895 the query to be adjusted.
896
897 """
898 return _log ( _xapian . Query , _xapian . Query . OP_SCALE_WEIGHT , query , multiplier )
899
901 """Filter a query with another query.
902
903 If exclude is False (or not specified), documents will only match the
904 resulting query if they match the both the first and second query: the
905 results of the first query are "filtered" to only include those which
906 also match the second query.
907
908 If exclude is True, documents will only match the resulting query if
909 they match the first query, but not the second query: the results of
910 the first query are "filtered" to only include those which do not match
911 the second query.
912
913 Documents will always be weighted according to only the first query.
914
915 - `query`: The query to filter.
916 - `filter`: The filter to apply to the query.
917 - `exclude`: If True, the sense of the filter is reversed - only
918 documents which do not match the second query will be returned.
919
920 """
921 if self . _index is None :
922 raise _errors . SearchError ( "SearchConnection has been closed" )
923 if not isinstance ( filter , _xapian . Query ) :
924 raise _errors . SearchError ( "Filter must be a Xapian Query object" )
925 if exclude :
926 return _log ( _xapian . Query , _xapian . Query . OP_AND_NOT , query , filter )
927 else :
928 return _log ( _xapian . Query , _xapian . Query . OP_FILTER , query , filter )
929
931 """Adjust the weights of one query with a secondary query.
932
933 Documents will be returned from the resulting query if and only if they
934 match the primary query (specified by the "primary" parameter).
935 However, the weights (and hence, the relevance rankings) of the
936 documents will be adjusted by adding weights from the secondary query
937 (specified by the "secondary" parameter).
938
939 """
940 if self . _index is None :
941 raise _errors . SearchError ( "SearchConnection has been closed" )
942 return _log ( _xapian . Query , _xapian . Query . OP_AND_MAYBE , primary , secondary )
943
945 """Create a query for a range search.
946
947 This creates a query which matches only those documents which have a
948 field value in the specified range.
949
950 Begin and end must be appropriate values for the field, according to
951 the 'type' parameter supplied to the SORTABLE action for the field.
952
953 The begin and end values are both inclusive - any documents with a
954 value equal to begin or end will be returned (unless end is less than
955 begin, in which case no documents will be returned).
956
957 Begin or end may be set to None in order to create an open-ended
958 range. (They may also both be set to None, which will generate a query
959 which matches all documents containing any value for the field.)
960
961 """
962 if self . _index is None :
963 raise _errors . SearchError ( "SearchConnection has been closed" )
964
965 if begin is None and end is None :
966
967 return _log ( _xapian . Query , '' )
968
969 try :
970 slot = self . _field_mappings . get_slot ( field , 'collsort' )
971 except KeyError :
972
973 return _log ( _xapian . Query )
974
975 sorttype = self . _get_sort_type ( field )
976 marshaller = SortableMarshaller ( False )
977 fn = marshaller . get_marshall_function ( field , sorttype )
978
979 if begin is not None :
980 begin = fn ( field , begin )
981 if end is not None :
982 end = fn ( field , end )
983
984 if begin is None :
985 return _log ( _xapian . Query , _xapian . Query . OP_VALUE_LE , slot , end )
986
987 if end is None :
988 return _log ( _xapian . Query , _xapian . Query . OP_VALUE_GE , slot , begin )
989
990 return _log ( _xapian . Query , _xapian . Query . OP_VALUE_RANGE , slot , begin , end )
991
993 """Create a query for a facet value.
994
995 This creates a query which matches only those documents which have a
996 facet value in the specified range.
997
998 For a numeric range facet, val should be a tuple holding the start and
999 end of the range, or a comma separated string holding two floating
1000 point values. For other facets, val should be the value to look
1001 for.
1002
1003 The start and end values are both inclusive - any documents with a
1004 value equal to start or end will be returned (unless end is less than
1005 start, in which case no documents will be returned).
1006
1007 """
1008 if self . _index is None :
1009 raise _errors . SearchError ( "SearchConnection has been closed" )
1010 if 'facets' in _checkxapian . missing_features :
1011 raise errors . SearchError ( "Facets unsupported with this release of xapian" )
1012
1013 try :
1014 actions = self . _field_actions [ field ] . _actions
1015 except KeyError :
1016 actions = { }
1017 facettype = None
1018 for action , kwargslist in actions . iteritems ( ) :
1019 if action == FieldActions . FACET :
1020 for kwargs in kwargslist :
1021 facettype = kwargs . get ( 'type' , None )
1022 if facettype is not None :
1023 break
1024 if facettype is not None :
1025 break
1026
1027 if facettype == 'float' :
1028 if isinstance ( val , basestring ) :
1029 val = [ float ( v ) for v in val . split ( ',' , 2 ) ]
1030 assert ( len ( val ) == 2 )
1031 try :
1032 slot = self . _field_mappings . get_slot ( field , 'facet' )
1033 except KeyError :
1034 return _log ( _xapian . Query )
1035
1036 sorttype = 'float'
1037 marshaller = SortableMarshaller ( False )
1038 fn = marshaller . get_marshall_function ( field , sorttype )
1039 begin = fn ( field , val [ 0 ] )
1040 end = fn ( field , val [ 1 ] )
1041 return _log ( _xapian . Query , _xapian . Query . OP_VALUE_RANGE , slot , begin , end )
1042 else :
1043 assert ( facettype == 'string' or facettype is None )
1044 prefix = self . _field_mappings . get_prefix ( field )
1045 return _log ( _xapian . Query , prefix + val . lower ( ) )
1046
1047
1050 """Prepare (and return) a query parser using the specified fields and
1051 operator.
1052
1053 """
1054 if self . _index is None :
1055 raise _errors . SearchError ( "SearchConnection has been closed" )
1056
1057 if isinstance ( allow , basestring ) :
1058 allow = ( allow , )
1059 if isinstance ( deny , basestring ) :
1060 deny = ( deny , )
1061 if allow is not None and len ( allow ) == 0 :
1062 allow = None
1063 if deny is not None and len ( deny ) == 0 :
1064 deny = None
1065 if allow is not None and deny is not None :
1066 raise _errors . SearchError ( "Cannot specify both `allow` and `deny` "
1067 "(got %r and %r)" % ( allow , deny ) )
1068
1069 if isinstance ( default_allow , basestring ) :
1070 default_allow = ( default_allow , )
1071 if isinstance ( default_deny , basestring ) :
1072 default_deny = ( default_deny , )
1073 if default_allow is not None and len ( default_allow ) == 0 :
1074 default_allow = None
1075 if default_deny is not None and len ( default_deny ) == 0 :
1076 default_deny = None
1077 if default_allow is not None and default_deny is not None :
1078 raise _errors . SearchError ( "Cannot specify both `default_allow` and `default_deny` "
1079 "(got %r and %r)" % ( default_allow , default_deny ) )
1080
1081 qp = _log ( _xapian . QueryParser )
1082 qp . set_database ( self . _index )
1083 qp . set_default_op ( default_op )
1084
1085 if allow is None :
1086 allow = [ key for key in self . _field_actions ]
1087 if deny is not None :
1088 allow = [ key for key in allow if key not in deny ]
1089
1090 for field in allow :
1091 try :
1092 actions = self . _field_actions [ field ] . _actions
1093 except KeyError :
1094 actions = { }
1095 for action , kwargslist in actions . iteritems ( ) :
1096 if action == FieldActions . INDEX_EXACT :
1097
1098
1099 qp . add_prefix ( field , self . _field_mappings . get_prefix ( field ) )
1100 if action == FieldActions . INDEX_FREETEXT :
1101 allow_field_specific = True
1102 for kwargs in kwargslist :
1103 allow_field_specific = allow_field_specific or kwargs . get ( 'allow_field_specific' , True )
1104 if not allow_field_specific :
1105 continue
1106 qp . add_prefix ( field , self . _field_mappings . get_prefix ( field ) )
1107 for kwargs in kwargslist :
1108 try :
1109 lang = kwargs [ 'language' ]
1110 my_stemmer = _log ( _xapian . Stem , lang )
1111 qp . my_stemmer = my_stemmer
1112 qp . set_stemmer ( my_stemmer )
1113 qp . set_stemming_strategy ( qp . STEM_SOME )
1114 except KeyError :
1115 pass
1116
1117 if default_allow is not None or default_deny is not None :
1118 if default_allow is None :
1119 default_allow = [ key for key in self . _field_actions ]
1120 if default_deny is not None :
1121 default_allow = [ key for key in default_allow if key not in default_deny ]
1122 for field in default_allow :
1123 try :
1124 actions = self . _field_actions [ field ] . _actions
1125 except KeyError :
1126 actions = { }
1127 for action , kwargslist in actions . iteritems ( ) :
1128 if action == FieldActions . INDEX_FREETEXT :
1129 qp . add_prefix ( '' , self . _field_mappings . get_prefix ( field ) )
1130
1131
1132 return qp
1133
1135 """Parse a query, with an optional prefix.
1136
1137 """
1138 if prefix is None :
1139 return qp . parse_query ( string , flags )
1140 else :
1141 return qp . parse_query ( string , flags , prefix )
1142
1144 """Parse a query with various flags.
1145
1146 If the initial boolean pass fails, fall back to not using boolean
1147 operators.
1148
1149 """
1150 try :
1151 q1 = self . _query_parse_with_prefix ( qp , string ,
1152 self . _qp_flags_base |
1153 self . _qp_flags_phrase |
1154 self . _qp_flags_synonym |
1155 self . _qp_flags_bool ,
1156 prefix )
1157 except _xapian . QueryParserError , e :
1158
1159
1160 q1 = self . _query_parse_with_prefix ( qp , string ,
1161 self . _qp_flags_base |
1162 self . _qp_flags_phrase |
1163 self . _qp_flags_synonym ,
1164 prefix )
1165
1166 qp . set_stemming_strategy ( qp . STEM_NONE )
1167 try :
1168 q2 = self . _query_parse_with_prefix ( qp , string ,
1169 self . _qp_flags_base |
1170 self . _qp_flags_bool ,
1171 prefix )
1172 except _xapian . QueryParserError , e :
1173
1174
1175 q2 = self . _query_parse_with_prefix ( qp , string ,
1176 self . _qp_flags_base ,
1177 prefix )
1178
1179 return _log ( _xapian . Query , _xapian . Query . OP_AND_MAYBE , q1 , q2 )
1180
1181 - def query_parse ( self , string , allow = None , deny = None , default_op = OP_AND ,
1182 default_allow = None , default_deny = None ) :
1183 """Parse a query string.
1184
1185 This is intended for parsing queries entered by a user. If you wish to
1186 combine structured queries, it is generally better to use the other
1187 query building methods, such as `query_composite` (though you may wish
1188 to create parts of the query to combine with such methods with this
1189 method).
1190
1191 The string passed to this method can have various operators in it. In
1192 particular, it may contain field specifiers (ie, field names, followed
1193 by a colon, followed by some text to search for in that field). For
1194 example, if "author" is a field in the database, the search string
1195 could contain "author:richard", and this would be interpreted as
1196 "search for richard in the author field". By default, any fields in
1197 the database which are indexed with INDEX_EXACT or INDEX_FREETEXT will
1198 be available for field specific searching in this way - however, this
1199 can be modified using the "allow" or "deny" parameters, and also by the
1200 allow_field_specific tag on INDEX_FREETEXT fields.
1201
1202 Any text which isn't prefixed by a field specifier is used to search
1203 the "default set" of fields. By default, this is the full set of
1204 fields in the database which are indexed with INDEX_FREETEXT and for
1205 which the search_by_default flag set (ie, if the text is found in any
1206 of those fields, the query will match). However, this may be modified
1207 with the "default_allow" and "default_deny" parameters. (Note that
1208 fields which are indexed with INDEX_EXACT aren't allowed to be used in
1209 the default list of fields.)
1210
1211 - `string`: The string to parse.
1212 - `allow`: A list of fields to allow in the query.
1213 - `deny`: A list of fields not to allow in the query.
1214 - `default_op`: The default operator to combine query terms with.
1215 - `default_allow`: A list of fields to search for by default.
1216 - `default_deny`: A list of fields not to search for by default.
1217
1218 Only one of `allow` and `deny` may be specified.
1219
1220 Only one of `default_allow` and `default_deny` may be specified.
1221
1222 If any of the entries in `allow` are not present in the configuration
1223 for the database, or are not specified for indexing (either as
1224 INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
1225 entries in `deny` are not present in the configuration for the
1226 database, they will be ignored.
1227
1228 Returns a Query object, which may be passed to the search() method, or
1229 combined with other queries.
1230
1231 """
1232 qp = self . _prepare_queryparser ( allow , deny , default_op , default_allow ,
1233 default_deny )
1234 return self . _query_parse_with_fallback ( qp , string )
1235
1237 """A query for a single field.
1238
1239 """
1240 if self . _index is None :
1241 raise _errors . SearchError ( "SearchConnection has been closed" )
1242 try :
1243 actions = self . _field_actions [ field ] . _actions
1244 except KeyError :
1245 actions = { }
1246
1247
1248 for action , kwargslist in actions . iteritems ( ) :
1249 if action in ( FieldActions . INDEX_EXACT ,
1250 FieldActions . TAG ,
1251 FieldActions . FACET , ) :
1252 prefix = self . _field_mappings . get_prefix ( field )
1253 if len ( value ) > 0 :
1254 chval = ord ( value [ 0 ] )
1255 if chval >= ord ( 'A' ) and chval <= ord ( 'Z' ) :
1256 prefix = prefix + ':'
1257 return _log ( _xapian . Query , prefix + value )
1258 if action == FieldActions . INDEX_FREETEXT :
1259 qp = _log ( _xapian . QueryParser )
1260 qp . set_default_op ( default_op )
1261 prefix = self . _field_mappings . get_prefix ( field )
1262 for kwargs in kwargslist :
1263 try :
1264 lang = kwargs [ 'language' ]
1265 qp . set_stemmer ( _log ( _xapian . Stem , lang ) )
1266 qp . set_stemming_strategy ( qp . STEM_SOME )
1267 except KeyError :
1268 pass
1269 return self . _query_parse_with_fallback ( qp , value , prefix )
1270
1271 return _log ( _xapian . Query )
1272
1273 - def query_similar ( self , ids , allow = None , deny = None , simterms = 10 ) :
1274 """Get a query which returns documents which are similar to others.
1275
1276 The list of document IDs to base the similarity search on is given in
1277 `ids`. This should be an iterable, holding a list of strings. If
1278 any of the supplied IDs cannot be found in the database, they will be
1279 ignored. (If no IDs can be found in the database, the resulting query
1280 will not match any documents.)
1281
1282 By default, all fields which have been indexed for freetext searching
1283 will be used for the similarity calculation. The list of fields used
1284 for this can be customised using the `allow` and `deny` parameters
1285 (only one of which may be specified):
1286
1287 - `allow`: A list of fields to base the similarity calculation on.
1288 - `deny`: A list of fields not to base the similarity calculation on.
1289 - `simterms`: Number of terms to use for the similarity calculation.
1290
1291 For convenience, any of `ids`, `allow`, or `deny` may be strings, which
1292 will be treated the same as a list of length 1.
1293
1294 Regardless of the setting of `allow` and `deny`, only fields which have
1295 been indexed for freetext searching will be used for the similarity
1296 measure - all other fields will always be ignored for this purpose.
1297
1298 """
1299 eterms , prefixes = self . _get_eterms ( ids , allow , deny , simterms )
1300
1301
1302
1303 q = _log ( _xapian . Query , _xapian . Query . OP_ELITE_SET , eterms , simterms )
1304 return q
1305
1307 """Get a set of "significant" terms for a document, or documents.
1308
1309 This has a similar interface to query_similar(): it takes a list of
1310 ids, and an optional specification of a set of fields to consider.
1311 Instead of returning a query, it returns a list of terms from the
1312 document (or documents), which appear "significant". Roughly,
1313 in this situation significant means that the terms occur more
1314 frequently in the specified document than in the rest of the corpus.
1315
1316 The list is in decreasing order of "significance".
1317
1318 By default, all terms related to fields which have been indexed for
1319 freetext searching will be considered for the list of significant
1320 terms. The list of fields used for this can be customised using the
1321 `allow` and `deny` parameters (only one of which may be specified):
1322
1323 - `allow`: A list of fields to consider.
1324 - `deny`: A list of fields not to consider.
1325
1326 For convenience, any of `ids`, `allow`, or `deny` may be strings, which
1327 will be treated the same as a list of length 1.
1328
1329 Regardless of the setting of `allow` and `deny`, only fields which have
1330 been indexed for freetext searching will be considered - all other
1331 fields will always be ignored for this purpose.
1332
1333 The maximum number of terms to return may be specified by the maxterms
1334 parameter.
1335
1336 """
1337 eterms , prefixes = self . _get_eterms ( ids , allow , deny , maxterms )
1338 terms = [ ]
1339 for term in eterms :
1340 pos = 0
1341 for char in term :
1342 if not char . isupper ( ) :
1343 break
1344 pos += 1
1345 field = prefixes [ term [ : pos ] ]
1346 value = term [ pos : ]
1347 terms . append ( ( field , value ) )
1348 return terms
1349
1351 """Get a set of terms for an expand
1352
1353 """
1354 if self . _index is None :
1355 raise _errors . SearchError ( "SearchConnection has been closed" )
1356 if allow is not None and deny is not None :
1357 raise _errors . SearchError ( "Cannot specify both `allow` and `deny`" )
1358
1359 if isinstance ( ids , basestring ) :
1360 ids = ( ids , )
1361 if isinstance ( allow , basestring ) :
1362 allow = ( allow , )
1363 if isinstance ( deny , basestring ) :
1364 deny = ( deny , )
1365
1366
1367 if allow is None :
1368 allow = [ key for key in self . _field_actions ]
1369 if deny is not None :
1370 allow = [ key for key in allow if key not in deny ]
1371
1372
1373 prefixes = { }
1374 for field in allow :
1375 try :
1376 actions = self . _field_actions [ field ] . _actions
1377 except KeyError :
1378 actions = { }
1379 for action , kwargslist in actions . iteritems ( ) :
1380 if action == FieldActions . INDEX_FREETEXT :
1381 prefixes [ self . _field_mappings . get_prefix ( field ) ] = field
1382
1383
1384 while True :
1385 try :
1386 eterms = self . _perform_expand ( ids , prefixes , simterms )
1387 break ;
1388 except _xapian . DatabaseModifiedError , e :
1389 self . reopen ( )
1390 return eterms , prefixes
1391
1396
1398 pos = 0
1399 for char in term :
1400 if not char . isupper ( ) :
1401 break
1402 pos += 1
1403 if term [ : pos ] in self . _prefixes :
1404 return True
1405 return False
1406
1431
1433 """A query which matches all the documents in the database.
1434
1435 """
1436 return _log ( _xapian . Query , '' )
1437
1439 """A query which matches no documents in the database.
1440
1441 This may be useful as a placeholder in various situations.
1442
1443 """
1444 return _log ( _xapian . Query )
1445
1446 - def spell_correct ( self , querystr , allow = None , deny = None , default_op = OP_AND ,
1447 default_allow = None , default_deny = None ) :
1448 """Correct a query spelling.
1449
1450 This returns a version of the query string with any misspelt words
1451 corrected.
1452
1453 - `allow`: A list of fields to allow in the query.
1454 - `deny`: A list of fields not to allow in the query.
1455 - `default_op`: The default operator to combine query terms with.
1456 - `default_allow`: A list of fields to search for by default.
1457 - `default_deny`: A list of fields not to search for by default.
1458
1459 Only one of `allow` and `deny` may be specified.
1460
1461 Only one of `default_allow` and `default_deny` may be specified.
1462
1463 If any of the entries in `allow` are not present in the configuration
1464 for the database, or are not specified for indexing (either as
1465 INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
1466 entries in `deny` are not present in the configuration for the
1467 database, they will be ignored.
1468
1469 Note that it is possible that the resulting spell-corrected query will
1470 still match no documents - the user should usually check that some
1471 documents are matched by the corrected query before suggesting it to
1472 users.
1473
1474 """
1475 qp = self . _prepare_queryparser ( allow , deny , default_op , default_allow ,
1476 default_deny )
1477 try :
1478 qp . parse_query ( querystr ,
1479 self . _qp_flags_base |
1480 self . _qp_flags_phrase |
1481 self . _qp_flags_synonym |
1482 self . _qp_flags_bool |
1483 qp . FLAG_SPELLING_CORRECTION )
1484 except _xapian . QueryParserError :
1485 qp . parse_query ( querystr ,
1486 self . _qp_flags_base |
1487 self . _qp_flags_phrase |
1488 self . _qp_flags_synonym |
1489 qp . FLAG_SPELLING_CORRECTION )
1490 corrected = qp . get_corrected_query_string ( )
1491 if len ( corrected ) == 0 :
1492 if isinstance ( querystr , unicode ) :
1493
1494
1495 return querystr . encode ( 'utf-8' )
1496 return querystr
1497 return corrected
1498
1500 """Check if this database supports collapsing on a specified field.
1501
1502 """
1503 if self . _index is None :
1504 raise _errors . SearchError ( "SearchConnection has been closed" )
1505 try :
1506 self . _field_mappings . get_slot ( field , 'collsort' )
1507 except KeyError :
1508 return False
1509 return True
1510
1512 """Check if this database supports sorting on a specified field.
1513
1514 """
1515 if self . _index is None :
1516 raise _errors . SearchError ( "SearchConnection has been closed" )
1517 try :
1518 self . _field_mappings . get_slot ( field , 'collsort' )
1519 except KeyError :
1520 return False
1521 return True
1522
1524 """Get the prefix of a term.
1525
1526 Prefixes are any initial capital letters, with the exception that R always
1527 ends a prefix, even if followed by capital letters.
1528
1529 """
1530 for p in xrange ( len ( term ) ) :
1531 if term [ p ] . islower ( ) :
1532 return term [ : p ]
1533 elif term [ p ] == 'R' :
1534 return term [ : p + 1 ]
1535 return term
1536
1538 """Check if a facet must never be returned by a particular query type.
1539
1540 Returns True if the facet must never be returned.
1541
1542 Returns False if the facet may be returned - either becuase there is no
1543 entry for the query type, or because the entry is not
1544 FacetQueryType_Never.
1545
1546 """
1547 if query_type is None :
1548 return False
1549 if query_type not in self . _facet_query_table :
1550 return False
1551 if facet not in self . _facet_query_table [ query_type ] :
1552 return False
1553 return self . _facet_query_table [ query_type ] [ facet ] == _indexerconnection . IndexerConnection . FacetQueryType_Never
1554
1555 - def search ( self , query , startrank , endrank ,
1556 checkatleast = 0 , sortby = None , collapse = None ,
1557 gettags = None ,
1558 getfacets = None , allowfacets = None , denyfacets = None , usesubfacets = None ,
1559 percentcutoff = None , weightcutoff = None ,
1560 query_type = None ) :
1561 """Perform a search, for documents matching a query.
1562
1563 - `query` is the query to perform.
1564 - `startrank` is the rank of the start of the range of matching
1565 documents to return (ie, the result with this rank will be returned).
1566 ranks start at 0, which represents the "best" matching document.
1567 - `endrank` is the rank at the end of the range of matching documents
1568 to return. This is exclusive, so the result with this rank will not
1569 be returned.
1570 - `checkatleast` is the minimum number of results to check for: the
1571 estimate of the total number of matches will always be exact if
1572 the number of matches is less than `checkatleast`. A value of ``-1``
1573 can be specified for the checkatleast parameter - this has the
1574 special meaning of "check all matches", and is equivalent to passing
1575 the result of get_doccount().
1576 - `sortby` is the name of a field to sort by. It may be preceded by a
1577 '+' or a '-' to indicate ascending or descending order
1578 (respectively). If the first character is neither '+' or '-', the
1579 sort will be in ascending order.
1580 - `collapse` is the name of a field to collapse the result documents
1581 on. If this is specified, there will be at most one result in the
1582 result set for each value of the field.
1583 - `gettags` is the name of a field to count tag occurrences in, or a
1584 list of fields to do so.
1585 - `getfacets` is a boolean - if True, the matching documents will be
1586 examined to build up a list of the facet values contained in them.
1587 - `allowfacets` is a list of the fieldnames of facets to consider.
1588 - `denyfacets` is a list of fieldnames of facets which will not be
1589 considered.
1590 - `usesubfacets` is a boolean - if True, only top-level facets and
1591 subfacets of facets appearing in the query are considered (taking
1592 precedence over `allowfacets` and `denyfacets`).
1593 - `percentcutoff` is the minimum percentage a result must have to be
1594 returned.
1595 - `weightcutoff` is the minimum weight a result must have to be
1596 returned.
1597 - `query_type` is a value indicating the type of query being
1598 performed. If not None, the value is used to influence which facets
1599 are be returned by the get_suggested_facets() function. If the
1600 value of `getfacets` is False, it has no effect.
1601
1602 If neither 'allowfacets' or 'denyfacets' is specified, all fields
1603 holding facets will be considered (but see 'usesubfacets').
1604
1605 """
1606 if self . _index is None :
1607 raise _errors . SearchError ( "SearchConnection has been closed" )
1608 if 'facets' in _checkxapian . missing_features :
1609 if getfacets is not None or \
1610 allowfacets is not None or \
1611 denyfacets is not None or \
1612 usesubfacets is not None or \
1613 query_type is not None :
1614 raise errors . SearchError ( "Facets unsupported with this release of xapian" )
1615 if 'tags' in _checkxapian . missing_features :
1616 if gettags is not None :
1617 raise errors . SearchError ( "Tags unsupported with this release of xapian" )
1618 if checkatleast == - 1 :
1619 checkatleast = self . _index . get_doccount ( )
1620
1621 enq = _log ( _xapian . Enquire , self . _index )
1622 enq . set_query ( query )
1623
1624 if sortby is not None :
1625 asc = True
1626 if sortby [ 0 ] == '-' :
1627 asc = False
1628 sortby = sortby [ 1 : ]
1629 elif sortby [ 0 ] == '+' :
1630 sortby = sortby [ 1 : ]
1631
1632 try :
1633 slotnum = self . _field_mappings . get_slot ( sortby , 'collsort' )
1634 except KeyError :
1635 raise _errors . SearchError ( "Field %r was not indexed for sorting" % sortby )
1636
1637
1638
1639
1640
1641 enq . set_sort_by_value_then_relevance ( slotnum , not asc )
1642
1643 if collapse is not None :
1644 try :
1645 slotnum = self . _field_mappings . get_slot ( collapse , 'collsort' )
1646 except KeyError :
1647 raise _errors . SearchError ( "Field %r was not indexed for collapsing" % collapse )
1648 enq . set_collapse_key ( slotnum )
1649
1650 maxitems = max ( endrank - startrank , 0 )
1651
1652
1653 checkatleast = max ( checkatleast , endrank + 1 )
1654
1655
1656 matchspies = [ ]
1657
1658
1659 if isinstance ( gettags , basestring ) :
1660 if len ( gettags ) != 0 :
1661 gettags = [ gettags ]
1662 tagspy = None
1663 if gettags is not None and len ( gettags ) != 0 :
1664 tagspy = _log ( _xapian . TermCountMatchSpy )
1665 for field in gettags :
1666 try :
1667 prefix = self . _field_mappings . get_prefix ( field )
1668 tagspy . add_prefix ( prefix )
1669 except KeyError :
1670 raise _errors . SearchError ( "Field %r was not indexed for tagging" % field )
1671 matchspies . append ( tagspy )
1672
1673
1674
1675 facetspy = None
1676 facetfields = [ ]
1677 if getfacets :
1678 if allowfacets is not None and denyfacets is not None :
1679 raise _errors . SearchError ( "Cannot specify both `allowfacets` and `denyfacets`" )
1680 if allowfacets is None :
1681 allowfacets = [ key for key in self . _field_actions ]
1682 if denyfacets is not None :
1683 allowfacets = [ key for key in allowfacets if key not in denyfacets ]
1684
1685
1686
1687
1688 queryfacets = set ( [ None ] )
1689 if usesubfacets :
1690
1691 termsiter = query . get_terms_begin ( )
1692 termsend = query . get_terms_end ( )
1693 while termsiter != termsend :
1694 prefix = self . _get_prefix_from_term ( termsiter . get_term ( ) )
1695 field = self . _field_mappings . get_fieldname_from_prefix ( prefix )
1696 if field and FieldActions . FACET in self . _field_actions [ field ] . _actions :
1697 queryfacets . add ( field )
1698 termsiter . next ( )
1699
1700 for field in allowfacets :
1701 try :
1702 actions = self . _field_actions [ field ] . _actions
1703 except KeyError :
1704 actions = { }
1705 for action , kwargslist in actions . iteritems ( ) :
1706 if action == FieldActions . FACET :
1707
1708
1709 if usesubfacets and self . _facet_hierarchy . get ( field ) not in queryfacets :
1710 continue
1711
1712 if self . _facet_query_never ( field , query_type ) :
1713 continue
1714 slot = self . _field_mappings . get_slot ( field , 'facet' )
1715 if facetspy is None :
1716 facetspy = _log ( _xapian . CategorySelectMatchSpy )
1717 facettype = None
1718 for kwargs in kwargslist :
1719 facettype = kwargs . get ( 'type' , None )
1720 if facettype is not None :
1721 break
1722 if facettype is None or facettype == 'string' :
1723 facetspy . add_slot ( slot , True )
1724 else :
1725 facetspy . add_slot ( slot )
1726 facetfields . append ( ( field , slot , kwargslist ) )
1727
1728 if facetspy is None :
1729
1730
1731
1732
1733 facetspy = False
1734 else :
1735 matchspies . append ( facetspy )
1736
1737
1738
1739 if len ( matchspies ) == 0 :
1740 matchspy = None
1741 elif len ( matchspies ) == 1 :
1742 matchspy = matchspies [ 0 ]
1743 else :
1744 matchspy = _log ( _xapian . MultipleMatchDecider )
1745 for spy in matchspies :
1746 matchspy . append ( spy )
1747
1748 enq . set_docid_order ( enq . DONT_CARE )
1749
1750
1751 if percentcutoff is not None or weightcutoff is not None :
1752 if percentcutoff is None :
1753 percentcutoff = 0
1754 if weightcutoff is None :
1755 weightcutoff = 0
1756 enq . set_cutoff ( percentcutoff , weightcutoff )
1757
1758
1759 while True :
1760 try :
1761 if matchspy is None :
1762 mset = enq . get_mset ( startrank , maxitems , checkatleast )
1763 else :
1764 mset = enq . get_mset ( startrank , maxitems , checkatleast ,
1765 None , None , matchspy )
1766 break
1767 except _xapian . DatabaseModifiedError , e :
1768 self . reopen ( )
1769 facet_hierarchy = None
1770 if usesubfacets :
1771 facet_hierarchy = self . _facet_hierarchy
1772
1773 return SearchResults ( self , enq , query , mset , self . _field_mappings ,
1774 tagspy , gettags , facetspy , facetfields ,
1775 facet_hierarchy ,
1776 self . _facet_query_table . get ( query_type ) )
1777
1779 """Get an iterator which returns all the ids in the database.
1780
1781 The unqiue_ids are currently returned in binary lexicographical sort
1782 order, but this should not be relied on.
1783
1784 Note that the iterator returned by this method may raise a
1785 xapian.DatabaseModifiedError exception if modifications are committed
1786 to the database while the iteration is in progress. If this happens,
1787 the search connection must be reopened (by calling reopen) and the
1788 iteration restarted.
1789
1790 """
1791 if self . _index is None :
1792 raise _errors . SearchError ( "SearchConnection has been closed" )
1793 return _indexerconnection . PrefixedTermIter ( 'Q' , self . _index . allterms ( ) )
1794
1796 """Get the document with the specified unique ID.
1797
1798 Raises a KeyError if there is no such document. Otherwise, it returns
1799 a ProcessedDocument.
1800
1801 """
1802 if self . _index is None :
1803 raise _errors . SearchError ( "SearchConnection has been closed" )
1804 while True :
1805 try :
1806 postlist = self . _index . postlist ( 'Q' + id )
1807 try :
1808 plitem = postlist . next ( )
1809 except StopIteration :
1810
1811 raise KeyError ( 'Unique ID %r not found' % id )
1812 try :
1813 postlist . next ( )
1814 raise _errors . IndexerError ( "Multiple documents "
1815 "found with same unique ID" )
1816 except StopIteration :
1817
1818 pass
1819
1820 result = ProcessedDocument ( self . _field_mappings )
1821 result . id = id
1822 result . _doc = self . _index . get_document ( plitem . docid )
1823 return result
1824 except _xapian . DatabaseModifiedError , e :
1825 self . reopen ( )
1826
1828 """Get an iterator over the synonyms.
1829
1830 - `prefix`: if specified, only synonym keys with this prefix will be
1831 returned.
1832
1833 The iterator returns 2-tuples, in which the first item is the key (ie,
1834 a 2-tuple holding the term or terms which will be synonym expanded,
1835 followed by the fieldname specified (or None if no fieldname)), and the
1836 second item is a tuple of strings holding the synonyms for the first
1837 item.
1838
1839 These return values are suitable for the dict() builtin, so you can
1840 write things like:
1841
1842 >>> conn = _indexerconnection.IndexerConnection('foo')
1843 >>> conn.add_synonym('foo', 'bar')
1844 >>> conn.add_synonym('foo bar', 'baz')
1845 >>> conn.add_synonym('foo bar', 'foo baz')
1846 >>> conn.flush()
1847 >>> conn = SearchConnection('foo')
1848 >>> dict(conn.iter_synonyms())
1849 {('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
1850
1851 """
1852 if self . _index is None :
1853 raise _errors . SearchError ( "SearchConnection has been closed" )
1854 return _indexerconnection . SynonymIter ( self . _index , self . _field_mappings , prefix )
1855
1870
1871 if __name__ == '__main__' :
1872 import doctest , sys
1873 doctest . testmod ( sys . modules [ __name__ ] )
1874
xappy-0.5/docs/api/xappy.searchconnection.SearchConnection-class.html 0000644 0001750 0001750 00000201756 11005555243 025747 0 ustar richard richard
xappy.searchconnection.SearchConnection
Class SearchConnection source code
object --+
|
SearchConnection
A connection to the search engine for searching.
The connection will access a view of the database.
query_parse (self ,
string ,
allow =None ,
deny =None ,
default_op =0 ,
default_allow =None ,
default_deny =None )
Parse a query string.
source code
query_field (self ,
field ,
value ,
default_op =0 )
A query for a single field.
source code
query_similar (self ,
ids ,
allow =None ,
deny =None ,
simterms =10 )
Get a query which returns documents which are similar to others.
source code
query_all (self )
A query which matches all the documents in the database.
source code
spell_correct (self ,
querystr ,
allow =None ,
deny =None ,
default_op =0 ,
default_allow =None ,
default_deny =None )
Correct a query spelling.
source code
can_collapse_on (self ,
field )
Check if this database supports collapsing on a specified field.
source code
can_sort_on (self ,
field )
Check if this database supports sorting on a specified field.
source code
search (self ,
query ,
startrank ,
endrank ,
checkatleast =0 ,
sortby =None ,
collapse =None ,
gettags =None ,
getfacets =None ,
allowfacets =None ,
denyfacets =None ,
usesubfacets =None ,
percentcutoff =None ,
weightcutoff =None ,
query_type =None )
Perform a search, for documents matching a query.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
Create a new connection to the index for searching.
There may only an arbitrary number of search connections for a
particular database open at a given time (regardless of whether there
is a connection for indexing open as well).
If the database doesn't exist, an exception will be raised.
Overrides:
object.__init__
append_close_handler (self ,
handler ,
userdata =None )
source code
Append a callback to the list of close handlers.
These will be called when the SearchConnection is closed. This happens
when the close() method is called, or when the SearchConnection object
is deleted. The callback will be passed two arguments: the path to the
SearchConnection object, and the userdata supplied to this method.
The handlers will be called in the order in which they were added.
The handlers will be called after the connection has been closed, so
cannot prevent it closing: their return value will be ignored. In
addition, they should not raise any exceptions.
Reopen the connection.
This updates the revision of the index which the connection references
to the latest flushed revision.
Close the connection to the database.
It is important to call this method before allowing the class to be
garbage collected to ensure that the connection is cleaned up promptly.
No other methods may be called on the connection after this has been
called. (It is permissible to call close() multiple times, but
only the first call will have any effect.)
If an exception occurs, the database will be closed, but changes since
the last call to flush may be lost.
Count the number of documents in the database.
This count will include documents which have been added or removed but
not yet flushed().
Build a composite query from a list of queries.
The queries are combined with the supplied operator, which is either
SearchConnection.OP_AND or SearchConnection.OP_OR.
Build a query which modifies the weights of a subquery.
This produces a query which returns the same documents as the subquery,
and in the same order, but with the weights assigned to each document
multiplied by the value of "multiplier". "multiplier" may be any floating
point value, but negative values will be clipped to 0, since Xapian
doesn't support negative weights.
This can be useful when producing queries to be combined with
query_composite, because it allows the relative importance of parts of
the query to be adjusted.
query_filter (self ,
query ,
filter ,
exclude =False )
source code
Filter a query with another query.
If exclude is False (or not specified), documents will only match the
resulting query if they match the both the first and second query: the
results of the first query are "filtered" to only include those which
also match the second query.
If exclude is True, documents will only match the resulting query if
they match the first query, but not the second query: the results of
the first query are "filtered" to only include those which do not match
the second query.
Documents will always be weighted according to only the first query.
query
: The query to filter.
filter
: The filter to apply to the query.
exclude
: If True, the sense of the filter is reversed - only
documents which do not match the second query will be returned.
Adjust the weights of one query with a secondary query.
Documents will be returned from the resulting query if and only if they
match the primary query (specified by the "primary" parameter).
However, the weights (and hence, the relevance rankings) of the
documents will be adjusted by adding weights from the secondary query
(specified by the "secondary" parameter).
Create a query for a range search.
This creates a query which matches only those documents which have a
field value in the specified range.
Begin and end must be appropriate values for the field, according to
the 'type' parameter supplied to the SORTABLE action for the field.
The begin and end values are both inclusive - any documents with a
value equal to begin or end will be returned (unless end is less than
begin, in which case no documents will be returned).
Begin or end may be set to None in order to create an open-ended
range. (They may also both be set to None, which will generate a query
which matches all documents containing any value for the field.)
Create a query for a facet value.
This creates a query which matches only those documents which have a
facet value in the specified range.
For a numeric range facet, val should be a tuple holding the start and
end of the range, or a comma separated string holding two floating
point values. For other facets, val should be the value to look
for.
The start and end values are both inclusive - any documents with a
value equal to start or end will be returned (unless end is less than
start, in which case no documents will be returned).
query_parse (self ,
string ,
allow =None ,
deny =None ,
default_op =0 ,
default_allow =None ,
default_deny =None )
source code
Parse a query string.
This is intended for parsing queries entered by a user. If you wish to
combine structured queries, it is generally better to use the other
query building methods, such as query_composite (though you may wish
to create parts of the query to combine with such methods with this
method).
The string passed to this method can have various operators in it. In
particular, it may contain field specifiers (ie, field names, followed
by a colon, followed by some text to search for in that field). For
example, if "author" is a field in the database, the search string
could contain "author:richard", and this would be interpreted as
"search for richard in the author field". By default, any fields in
the database which are indexed with INDEX_EXACT or INDEX_FREETEXT will
be available for field specific searching in this way - however, this
can be modified using the "allow" or "deny" parameters, and also by the
allow_field_specific tag on INDEX_FREETEXT fields.
Any text which isn't prefixed by a field specifier is used to search
the "default set" of fields. By default, this is the full set of
fields in the database which are indexed with INDEX_FREETEXT and for
which the search_by_default flag set (ie, if the text is found in any
of those fields, the query will match). However, this may be modified
with the "default_allow" and "default_deny" parameters. (Note that
fields which are indexed with INDEX_EXACT aren't allowed to be used in
the default list of fields.)
string
: The string to parse.
allow
: A list of fields to allow in the query.
deny
: A list of fields not to allow in the query.
default_op
: The default operator to combine query terms with.
default_allow
: A list of fields to search for by default.
default_deny
: A list of fields not to search for by default.
Only one of allow
and deny
may be specified.
Only one of default_allow
and default_deny
may be specified.
If any of the entries in allow
are not present in the configuration
for the database, or are not specified for indexing (either as
INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
entries in deny
are not present in the configuration for the
database, they will be ignored.
Returns a Query object, which may be passed to the search() method, or
combined with other queries.
query_similar (self ,
ids ,
allow =None ,
deny =None ,
simterms =10 )
source code
Get a query which returns documents which are similar to others.
The list of document IDs to base the similarity search on is given in
ids
. This should be an iterable, holding a list of strings. If
any of the supplied IDs cannot be found in the database, they will be
ignored. (If no IDs can be found in the database, the resulting query
will not match any documents.)
By default, all fields which have been indexed for freetext searching
will be used for the similarity calculation. The list of fields used
for this can be customised using the allow
and deny
parameters
(only one of which may be specified):
allow
: A list of fields to base the similarity calculation on.
deny
: A list of fields not to base the similarity calculation on.
simterms
: Number of terms to use for the similarity calculation.
For convenience, any of ids
, allow
, or deny
may be strings, which
will be treated the same as a list of length 1.
Regardless of the setting of allow
and deny
, only fields which have
been indexed for freetext searching will be used for the similarity
measure - all other fields will always be ignored for this purpose.
significant_terms (self ,
ids ,
maxterms =10 ,
allow =None ,
deny =None )
source code
Get a set of "significant" terms for a document, or documents.
This has a similar interface to query_similar(): it takes a list of
ids, and an optional specification of a set of fields to consider.
Instead of returning a query, it returns a list of terms from the
document (or documents), which appear "significant". Roughly,
in this situation significant means that the terms occur more
frequently in the specified document than in the rest of the corpus.
The list is in decreasing order of "significance".
By default, all terms related to fields which have been indexed for
freetext searching will be considered for the list of significant
terms. The list of fields used for this can be customised using the
allow
and deny
parameters (only one of which may be specified):
allow
: A list of fields to consider.
deny
: A list of fields not to consider.
For convenience, any of ids
, allow
, or deny
may be strings, which
will be treated the same as a list of length 1.
Regardless of the setting of allow
and deny
, only fields which have
been indexed for freetext searching will be considered - all other
fields will always be ignored for this purpose.
The maximum number of terms to return may be specified by the maxterms
parameter.
A query which matches no documents in the database.
This may be useful as a placeholder in various situations.
spell_correct (self ,
querystr ,
allow =None ,
deny =None ,
default_op =0 ,
default_allow =None ,
default_deny =None )
source code
Correct a query spelling.
This returns a version of the query string with any misspelt words
corrected.
allow
: A list of fields to allow in the query.
deny
: A list of fields not to allow in the query.
default_op
: The default operator to combine query terms with.
default_allow
: A list of fields to search for by default.
default_deny
: A list of fields not to search for by default.
Only one of allow
and deny
may be specified.
Only one of default_allow
and default_deny
may be specified.
If any of the entries in allow
are not present in the configuration
for the database, or are not specified for indexing (either as
INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
entries in deny
are not present in the configuration for the
database, they will be ignored.
Note that it is possible that the resulting spell-corrected query will
still match no documents - the user should usually check that some
documents are matched by the corrected query before suggesting it to
users.
search (self ,
query ,
startrank ,
endrank ,
checkatleast =0 ,
sortby =None ,
collapse =None ,
gettags =None ,
getfacets =None ,
allowfacets =None ,
denyfacets =None ,
usesubfacets =None ,
percentcutoff =None ,
weightcutoff =None ,
query_type =None )
source code
Perform a search, for documents matching a query.
query
is the query to perform.
startrank
is the rank of the start of the range of matching
documents to return (ie, the result with this rank will be returned).
ranks start at 0, which represents the "best" matching document.
endrank
is the rank at the end of the range of matching documents
to return. This is exclusive, so the result with this rank will not
be returned.
checkatleast
is the minimum number of results to check for: the
estimate of the total number of matches will always be exact if
the number of matches is less than checkatleast
. A value of -1
can be specified for the checkatleast parameter - this has the
special meaning of "check all matches", and is equivalent to passing
the result of get_doccount().
sortby
is the name of a field to sort by. It may be preceded by a
'+' or a '-' to indicate ascending or descending order
(respectively). If the first character is neither '+' or '-', the
sort will be in ascending order.
collapse
is the name of a field to collapse the result documents
on. If this is specified, there will be at most one result in the
result set for each value of the field.
gettags
is the name of a field to count tag occurrences in, or a
list of fields to do so.
getfacets
is a boolean - if True, the matching documents will be
examined to build up a list of the facet values contained in them.
allowfacets
is a list of the fieldnames of facets to consider.
denyfacets
is a list of fieldnames of facets which will not be
considered.
usesubfacets
is a boolean - if True, only top-level facets and
subfacets of facets appearing in the query are considered (taking
precedence over allowfacets
and denyfacets
).
percentcutoff
is the minimum percentage a result must have to be
returned.
weightcutoff
is the minimum weight a result must have to be
returned.
query_type
is a value indicating the type of query being
performed. If not None, the value is used to influence which facets
are be returned by the get_suggested_facets() function. If the
value of getfacets
is False, it has no effect.
If neither 'allowfacets' or 'denyfacets' is specified, all fields
holding facets will be considered (but see 'usesubfacets').
Get an iterator which returns all the ids in the database.
The unqiue_ids are currently returned in binary lexicographical sort
order, but this should not be relied on.
Note that the iterator returned by this method may raise a
xapian.DatabaseModifiedError exception if modifications are committed
to the database while the iteration is in progress. If this happens,
the search connection must be reopened (by calling reopen) and the
iteration restarted.
Get the document with the specified unique ID.
Raises a KeyError if there is no such document. Otherwise, it returns
a ProcessedDocument.
Get an iterator over the synonyms.
prefix
: if specified, only synonym keys with this prefix will be
returned.
The iterator returns 2-tuples, in which the first item is the key (ie,
a 2-tuple holding the term or terms which will be synonym expanded,
followed by the fieldname specified (or None if no fieldname)), and the
second item is a tuple of strings holding the synonyms for the first
item.
These return values are suitable for the dict() builtin, so you can
write things like:
>>> conn = _indexerconnection.IndexerConnection('foo' )
>>> conn.add_synonym('foo' , 'bar' )
>>> conn.add_synonym('foo bar' , 'baz' )
>>> conn.add_synonym('foo bar' , 'foo baz' )
>>> conn.flush()
>>> conn = SearchConnection('foo' )
>>> dict(conn.iter_synonyms())
{('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
Get an item of metadata stored in the connection.
This returns a value stored by a previous call to
IndexerConnection.set_metadata.
If the value is not found, this will return the empty string.
xappy-0.5/docs/api/xappy.searchconnection.SearchConnection.ExpandDecider-class.html 0000644 0001750 0001750 00000022651 11005555243 030440 0 ustar richard richard
xappy.searchconnection.SearchConnection.ExpandDecider
Class ExpandDecider source code
object --+
|
xapian.ExpandDecider --+
|
SearchConnection.ExpandDecider
__init__ (self ,
prefixes )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from xapian.ExpandDecider
:
__disown__
,
__repr__
,
__swig_destroy__
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
Inherited from xapian.ExpandDecider
:
thisown
Inherited from object
:
__class__
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
xapian.ExpandDecider.__init__
Overrides:
xapian.ExpandDecider.__call__
xappy-0.5/docs/api/xappy.searchconnection.SearchResult-class.html 0000644 0001750 0001750 00000046502 11005555243 025122 0 ustar richard richard
xappy.searchconnection.SearchResult
Class SearchResult source code
object --+
|
datastructures.ProcessedDocument --+
|
SearchResult
A result from a search.
As well as being a ProcessedDocument representing the document in the
database, the result has several members which may be used to get
information about how well the document matches the search:
rank
: The rank of the document in the search results, starting at 0
(ie, 0 is the "top" result, 1 is the second result, etc).
weight
: A floating point number indicating the weight of the result
document. The value is only meaningful relative to other results for a
given search - a different search, or the same search with a different
database, may give an entirely different scale to the weights. This
should not usually be displayed to users, but may be useful if trying to
perform advanced reweighting operations on search results.
percent
: A percentage value for the weight of a document. This is
just a rescaled form of the weight
member. It doesn't represent any
kind of probability value; the only real meaning of the numbers is that,
within a single set of results, a document with a higher percentage
corresponds to a better match. Because the percentage doesn't really
represent a probability, or a confidence value, it is probably unhelpful
to display it to most users, since they tend to place an over emphasis
on its meaning. However, it is included because it may be useful
occasionally.
summarise (self ,
field ,
maxlen =600 ,
hl =(
'
<b>
'
,
'
</b>
'
)
,
query =None )
Return a summarised version of the field specified.
source code
highlight (self ,
field ,
hl =(
'
<b>
'
,
'
</b>
'
)
,
strip_tags =False ,
query =None )
Return a highlighted version of the field specified.
source code
Inherited from datastructures.ProcessedDocument
:
add_term
,
add_value
,
get_value
,
prepare
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
__init__ (self ,
msetitem ,
results )
(Constructor)
source code
Create a ProcessedDocument.
fieldmappings is the configuration from a database connection used lookup
the configuration to use to store each field.
If supplied, xapdoc
is a Xapian document to store in the processed
document. Otherwise, a new Xapian document is created.
Overrides:
datastructures.ProcessedDocument.__init__
(inherited documentation)
summarise (self ,
field ,
maxlen =600 ,
hl =(
'
<b>
'
,
'
</b>
'
)
,
query =None )
source code
Return a summarised version of the field specified.
This will return a summary of the contents of the field stored in the
search result, with words which match the query highlighted.
The maximum length of the summary (in characters) may be set using the
maxlen parameter.
The return value will be a string holding the summary, with
highlighting applied. If there are multiple instances of the field in
the document, the instances will be joined with a newline character.
To turn off highlighting, set hl to None. Each highlight will consist
of the first entry in the hl
list being placed before the word, and
the second entry in the hl
list being placed after the word.
Any XML or HTML style markup tags in the field will be stripped before
the summarisation algorithm is applied.
If query
is supplied, it should contain a Query object, as returned
from SearchConnection.query_parse() or related methods, which will be
used as the basis of the summarisation and highlighting rather than the
query which was used for the search.
Raises KeyError if the field is not known.
highlight (self ,
field ,
hl =(
'
<b>
'
,
'
</b>
'
)
,
strip_tags =False ,
query =None )
source code
Return a highlighted version of the field specified.
This will return all the contents of the field stored in the search
result, with words which match the query highlighted.
The return value will be a list of strings (corresponding to the list
of strings which is the raw field data).
Each highlight will consist of the first entry in the hl
list being
placed before the word, and the second entry in the hl
list being
placed after the word.
If strip_tags
is True, any XML or HTML style markup tags in the field
will be stripped before highlighting is applied.
If query
is supplied, it should contain a Query object, as returned
from SearchConnection.query_parse() or related methods, which will be
used as the basis of the summarisation and highlighting rather than the
query which was used for the search.
Raises KeyError if the field is not known.
xappy-0.5/docs/api/xappy.searchconnection.SearchResultIter-class.html 0000644 0001750 0001750 00000020231 11005555243 025735 0 ustar richard richard
xappy.searchconnection.SearchResultIter
Class SearchResultIter source code
object --+
|
SearchResultIter
An iterator over a set of results from a search.
__init__ (self ,
results ,
order )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__repr__
,
__setattr__
,
__str__
Inherited from object
:
__class__
__init__ (self ,
results ,
order )
(Constructor)
source code
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
xappy-0.5/docs/api/xappy.searchconnection.SearchResults-class.html 0000644 0001750 0001750 00000073022 11005555243 025302 0 ustar richard richard
xappy.searchconnection.SearchResults
Class SearchResults source code
object --+
|
SearchResults
A set of results of a search.
__init__ (self ,
conn ,
enq ,
query ,
mset ,
fieldmappings ,
tagspy ,
tagfields ,
facetspy ,
facetfields ,
facethierarchy ,
facetassocs )
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
source code
get_hit (self ,
index )
Get the hit with a given index.
source code
__getitem__ (self ,
index )
Get the hit with a given index.
source code
get_suggested_facets (self ,
maxfacets =5 ,
desired_num_of_categories =7 ,
required_facets =None )
Get a suggested set of facets, to present to the user.
source code
Inherited from object
:
__delattr__
,
__getattribute__
,
__hash__
,
__new__
,
__reduce__
,
__reduce_ex__
,
__setattr__
,
__str__
more_matches
Check whether there are further matches after those in this result set.
startrank
Get the rank of the first item in the search results.
endrank
Get the rank of the item after the end of the search results.
matches_lower_bound
Get a lower bound on the total number of matching documents.
matches_upper_bound
Get an upper bound on the total number of matching documents.
matches_human_readable_estimate
Get a human readable estimate of the number of matching documents.
matches_estimated
Get an estimate for the total number of matching documents.
estimate_is_exact
Check whether the estimated number of matching documents is exact.
Inherited from object
:
__class__
__init__ (self ,
conn ,
enq ,
query ,
mset ,
fieldmappings ,
tagspy ,
tagfields ,
facetspy ,
facetfields ,
facethierarchy ,
facetassocs )
(Constructor)
source code
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature
Overrides:
object.__init__
(inherited documentation)
repr(x)
Overrides:
object.__repr__
(inherited documentation)
Get an iterator over the hits in the search result.
The iterator returns the results in increasing order of rank.
Get the number of hits in the search result.
Note that this is not (usually) the number of matching documents for
the search. If startrank is non-zero, it's not even the rank of the
last document in the search result. It's simply the number of hits
stored in the search result.
It is, however, the number of items returned by the iterator produced
by calling iter() on this SearchResults object.
Get the most frequent tags in a given field.
field
- the field to get tags for. This must have been specified
in the "gettags" argument of the search() call.
maxtags
- the maximum number of tags to return.
Returns a sequence of 2-item tuples, in which the first item in the
tuple is the tag, and the second is the frequency of the tag in the
matches seen (as an integer).
get_suggested_facets (self ,
maxfacets =5 ,
desired_num_of_categories =7 ,
required_facets =None )
source code
Get a suggested set of facets, to present to the user.
This returns a list, in descending order of the usefulness of the
facet, in which each item is a tuple holding:
fieldname of facet.
sequence of 2-tuples holding the suggested values or ranges for that
field:
For facets of type 'string', the first item in the 2-tuple will
simply be the string supplied when the facet value was added to its
document. For facets of type 'float', it will be a 2-tuple, holding
floats giving the start and end of the suggested value range.
The second item in the 2-tuple will be the frequency of the facet
value or range in the result set.
If required_facets is not None, it must be a field name, or a sequence
of field names. Any field names mentioned in required_facets will be
returned if there are any facet values at all in the search results for
that field. The facet will only be omitted if there are no facet
values at all for the field.
The value of maxfacets will be respected as far as possible; the
exception is that if there are too many fields listed in
required_facets with at least one value in the search results, extra
facets will be returned (ie, obeying the required_facets parameter is
considered more important than the maxfacets parameter).
If facet_hierarchy was indicated when search() was called, and the
query included facets, then only subfacets of those query facets and
top-level facets will be included in the returned list. Furthermore
top-level facets will only be returned if there are remaining places
in the list after it has been filled with subfacets. Note that
required_facets is still respected regardless of the facet hierarchy.
If a query type was specified when search() was called, and the query
included facets, then facets with an association of Never to the
query type are never returned, even if mentioned in required_facets.
Facets with an association of Preferred are listed before others in
the returned list.
endrank
Get the rank of the item after the end of the search results.
If there are sufficient results in the index, this corresponds to the
"endrank" parameter passed to the search() method.
Get Method:
xappy.searchconnection.SearchResults._get_endrank (self )
matches_human_readable_estimate
Get a human readable estimate of the number of matching documents.
This consists of the value returned by the "matches_estimated" property,
rounded to an appropriate number of significant digits (as determined by
the values of the "matches_lower_bound" and "matches_upper_bound"
properties).
Get Method:
xappy.searchconnection.SearchResults._get_human_readable_estimate (self )
xappy-0.5/docs/introduction.html 0000644 0001750 0001750 00000134766 11005555237 016714 0 ustar richard richard
The "xappy" module is an easy-to-use interface to the Xapian search engine.
Xapian provides a low level interface, dealing with terms and documents, but
not really worrying about where terms come from, or how to build searches to
match the way in which data has been indexed. In contrast, Xappy allows you
to design a field structure, specifying what kind of information is held in
particular fields, and then uses this field structure to index data
appropriately, and to build and perform searches.
You will need an up-to-date version of Xapian (both the core library and the
corresponding Python bindings) to use Xappy. Unfortunately, the latest
release (1.0.3) doesn't support all the features needed by Xappy, so you will
either need a recent snapshot release, or to build from Xapian SVN HEAD. We
recommend using a snapshot unless you are actively developing Xapian itself.
We hope that release 1.0.4 will be suitable for use with Xappy.
There is not yet a distutils setup script for xappy, but other than Xapian it
has no dependencies or resources which need installing, so it may be installed
simply by copying the "xappy" directory to somewhere on your Python path.
Once Xapian and Xappy are installed, you should be able to start the python
interpreter and run:
>>> import xappy
To run the testsuite, simply run "./testsuite/runtests.py". This will
display any errors produced when running the testsuite, and then display a
coverage report for the modules tested.
The testsuite is composed of tests taken from three sources:
doctest tests in the code comments in the
additional doctest tests in text files with names of the form
'FOO_doctestN.txt', which test the module named "FOO" (and are run in a
context in which the modules public symbols have all been imported).
additional documentation files (such as this one) which contain doctest
formatted examples.
The list of core modules to test, and additional documentation files to check,
is maintained in the "testsuite/runtests.py" file.
The coverage report displayed after running the testsuite is statement based,
which is sadly one of the least precise methods of generating a coverage
report, and counts lines as having been executed even if they haven't been
tested in all possible code paths. On the plus side, its judgement is reliable
if it considers that a line of code hasn't been tested. For this reason, it is
reasonable to aim for 100% coverage by this metric, and the coverage report can
be helpful to keep track of sections of code which aren't tested at all.
For any released version of Xappy, the coverage report should indicate 100%
coverage for all modules. However, if you are using an SVN snapshot of Xappy,
you may find that some code is not covered. In addition, the coverage testing
currently contains a bug when run under Python 2.5 which causes some lines of
code to be incorectly marked as "not covered" when they actually are. When run
under Python 2.4, this bug doesn't manifest.
Before we process any documents, we need to create a database to hold the
documents. This is done simply by creating an "IndexerConnection" object, and
passing it the path we want to create the database at. If the database doesn't
already exist, this will create a new, empty, database:
>>> conn = xappy.IndexerConnection('db1')
Note
All connections may only be accessed from a single thread at a time,
and there may only be one IndexerConnection in existence at any given time.
Additionally, it generally gives a large performance gain to ensure that the
connection is kept open between modifications of the database, so that
modifications can be grouped together. Therefore, you must protect access to
the connection with a mutex if multiple threads might access it.
Once we've created an IndexerConnection, we can use it to specify the actions
which should be performed on fields with a given name. There are several
actions available, for different types of field content, and for different
types of searches. You need to decide what actions you need before adding
documents, because the database does not store enough information about
documents to get back to the unprocessed document. The connection will allow
you to change the field actions after documents have been added, but this
change will not be reflected in any documents which have already been added to
the database.
Fields which contain plain text should be added with the INDEX_FREETEXT
action. This action takes various optional parameters:
weight : if this is supplied, the frequency information for all terms in
the specified field will be multiplied by the given factor; this can be used
for fields which are often a better indication of the subject matter than
other fields (eg, title fields).
language : if this is supplied, it indicates the language that the
supplied text is written in: this is used to perform language specific term
normalising (to allow, for example, plural and singular forms to be
matched). The language may be specified as a 2 character ISO-639 language
code.
stop : if this is supplied, it must contain an sequence or other iterable
which returns a list of stopwords, which will be filtered out of the index.
This may reduce index size and improve search and indexing speed, but will
reduce the flexibility of the search. Note that some information on the
terms in the stoplist will still be stored, to allow phrase searches to be
performed.
spell : this is a boolean flag; if supplied, and true, the contents of
the field will be used for spelling correction.
nopos : this is a boolean flag; if supplied, and true, the positions of
words in the field will not be stored. These are used for performing phrase
and proximity searches, so this kind of search will not be possible on the
field. On the other hand, the amount of data indexed for the field will be
reduced, resulting in a lower database size, faster indexing, and
potentially faster searching.
allow_field_specific : this is a boolean flag - if False, prevents terms
with the field prefix being generated. This means that searches specific to
this field will not work, and thus should only be used when only non-field
specific searches are desired. Defaults to True.
search_by_default : this is a boolean flag - if False, the field will not
be searched by non-field specific searches. If True, or omitted, the field
will be included in searches for non field-specific searches.
All text passed to the interface is assumed to be UTF-8 encoded Unicode.
>>> conn.add_field_action('title', xappy.FieldActions.INDEX_FREETEXT, weight=5, language='en')
>>> conn.add_field_action('text', xappy.FieldActions.INDEX_FREETEXT, language='en', spell=True)
Any fields which contain exact values which we want to search for (such as a
category name, or an ID number should be given the INDEX_EXACT actions.
This doesn't perform any processing on the field value, so any symbols or
punctuation will be preserved in the database:
>>> conn.add_field_action('category', xappy.FieldActions.INDEX_EXACT)
If we want to be able to sort on a field, we need to give it the SORTABLE
action. By default, sorting is performed based on a lexicographical comparison
of string values, but it is possible to set the sort order to be by date, or by
floating point number. Fields which are given then SORTABLE action can
also be used to restrict the results to a given range - think of it as
declaring that there is a useful ordering for the field values.
Date values can be supplied as strings in the form YYYYMMDD or YYYY-MM-DD (or
using / or . as separators). Floating point numbers can be in any
representation which is understood by Python's float() function:
>>> conn.add_field_action('category', xappy.FieldActions.SORTABLE)
>>> conn.add_field_action('date', xappy.FieldActions.SORTABLE, type="date")
>>> conn.add_field_action('price', xappy.FieldActions.SORTABLE, type="float")
If we want to be able to be able to remove duplicates based on a field, we need
to give it the COLLAPSE action. This allows the result set to be
"collapsed" such that only the highest result with each value of a field will
be returned. For example, we might want to just display the highest ranked
document in each category (with a link to a list of the results in that
category):
>>> conn.add_field_action('category', xappy.FieldActions.COLLAPSE)
If we want to be able to retrieve data from the document when it is
the result of a search, we need to set the STORE_CONTENT action:
>>> conn.add_field_action('text', xappy.FieldActions.STORE_CONTENT)
>>> conn.add_field_action('title', xappy.FieldActions.STORE_CONTENT)
>>> conn.add_field_action('category', xappy.FieldActions.STORE_CONTENT)
If we want to use the contents of a field as "tags", which can be counted at
search time (possibly, in order to build a tag-cloud, or other such
visualisation), we need to set the TAG action:
>>> conn.add_field_action('tag', xappy.FieldActions.TAG)
Xappy also supports "faceted browsing": this means attaching "facets" to
documents, where a facet is a value representing one aspect of information
about a document: for example, the price of an object would be a facet of a
document representing that object. Xappy supports storing many facets about a
document, restricting the search results to only those documents which contain
a particular facet, and automatically selecting a set of facets which are
relevant to the set of results returned by a search (so that the facets can be
presented to the user to be used to refine their search).
If we want to use a field as a facet, we simply add the FACET action to it.
Facets can be of two types - "string" (which are just exact string matches), or
"float" (which will automatically be grouped into ranges when returning a
suggested list of facets). The default is "string":
>>> conn.add_field_action('price', xappy.FieldActions.FACET, type='float')
>>> conn.add_field_action('category', xappy.FieldActions.FACET, type='string')
To add data to the database, we first create UnprocessedDocument objects.
These contain a list of fields, which are processed in turn to create a
ProcessedDocument , which can be added to the database. The
ProcessedDocument can't be converted back into an UnprocessedDocument
because some information is generally lost in this processing process (but it
is possible to make alterations directly to the ProcessedDocument later.
We can access the list of fields in an UnprocessedDocument directly, using
the fields member:
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our first document"))
>>> doc.fields.append(xappy.Field("text", "This is a paragraph of text. It's quite short."))
>>> doc.fields.append(xappy.Field("text", "We can create another paragraph of text. "
... "We can have as many of these as we like."))
>>> doc.fields.append(xappy.Field("category", "Test documents"))
>>> doc.fields.append(xappy.Field("tag", "Tag1"))
>>> doc.fields.append(xappy.Field("tag", "Test document"))
>>> doc.fields.append(xappy.Field("tag", "Test document"))
>>> doc.fields.append(xappy.Field("price", "20.56"))
We can add the document directly to the database: if we do this, the connection
will process the document to generate a ProcessedDocument behind the
scenes, and then add this:
>>> conn.add(doc)
'0'
Note that the add method returned a value '0' . This is a unique
identifier for the document which was added, and may be used later to delete or
replace the document. If we have externally generated unique identifiers, we
can specify that the system should use them instead of generating its own, by
setting the id property on the processed or unprocessed document
before adding it to the database.
We can also ask the database to process a document explicitly before calling
the "add" method. We might do this if we want to change the processed document
in some way, but this isn't generally necessary:
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our second document"))
>>> doc.fields.append(xappy.Field("text", "In the beginning God created the heaven and the earth."))
>>> doc.fields.append(xappy.Field("category", "Bible"))
>>> doc.fields.append(xappy.Field("price", "12.20"))
>>> doc.id='Bible1'
>>> pdoc = conn.process(doc)
>>> conn.add(pdoc)
'Bible1'
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our third document"))
>>> doc.fields.append(xappy.Field("text", "And the earth was without form, and void; "
... "and darkness was upon the face of the deep. "
... "And the Spirit of God moved upon the face of the waters."))
>>> doc.fields.append(xappy.Field("category", "Bible"))
>>> doc.fields.append(xappy.Field("date", "17501225"))
>>> doc.fields.append(xappy.Field("price", "16.56"))
>>> doc.id='Bible2'
>>> pdoc = conn.process(doc)
>>> conn.add(pdoc)
'Bible2'
Once we have finished indexing, we should flush the changes to disk. Any
changes which are unflushed may not be preserved if the processes exits without
closing the database nicely:
>>> conn.flush()
Finally, we should close the connection to release its resources (if we leave
this to the garbage collector, this might not happen for a long time). After
closing, no other methods may be called on the connection, but a new connection
can be made.:
>>> conn.close()
A search connection is opened similarly to an indexing connection. However,
note that multiple search connections may be opened at once (though each
connection must not be accessed from more than one thread). Search connections
can even be open while indexing connections are:
>>> conn = xappy.SearchConnection('db1')
A search connection attempts to provide a stable view of the database, so when
an update is made by a concurrent indexing process, the search connection will
not reflect this change. This allows the results of the search to be gathered
without needing to worry about concurrent updates (but see the section below
about this for limitations on this facility).
The search connection can be reopened at any time to make it point to the
latest version of the database:
>>> conn.reopen()
To perform a search, we need to specify what we're searching for. This is
called a "Query", and the search connection provides several methods for
building up a query. The simplest of these is the query_field method,
which builds a query to search a single field:
>>> q = conn.query_field('text', 'create a paragraph')
>>> str(q)
'Xapian::Query(((ZXBcreat:(pos=1) AND ZXBa:(pos=2) AND ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) AND XBa:(pos=2) AND XBparagraph:(pos=3))))'
As you can see, the str() function will display the underlying Xapian query
which is generated by the search connection. This may look a little weird at
first, but you can get a general idea of the shape of the query.
The default operator for searches is "AND", but if we wish to be a little wider
in our search, we can use the "OR" operator instead:
>>> q = conn.query_field('text', 'create a paragraph', default_op=conn.OP_OR)
>>> str(q)
'Xapian::Query(((ZXBcreat:(pos=1) OR ZXBa:(pos=2) OR ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) OR XBa:(pos=2) OR XBparagraph:(pos=3))))'
Once we have a query, we can use it to get a set of search results. Xapian is
optimised for situations where only a small subset of the total result set is
required, so when we perform a search we specify the starting rank (ie, the
position in the total set of results, starting at 0) of the results we want to
retrieve, and also the ending rank. Following usual Python conventions, the
ending rank isn't inclusive, but the starting rank is.
In this case we want the first 10 results, so we can search with:
>>> results = conn.search(q, 0, 10)
The result set has a variety of pieces of information, but a useful one is the
estimate of the total number of matching documents:
>>> results.matches_estimated
2
Only an estimated value is available because of Xapian's optimisations: the
search process can often stop early because it has proved that there can be no
better ranked documents, and especially for large searches, it would be a waste
of time to then attempt to calculate the precise number of matching documents.
We can check if the estimate is known to be correct by looking at the
estimate_is_exact property:
>>> results.estimate_is_exact
True
The SearchResults object also provides upper and lower bounds on the number
of matching documents, and a check for whether there are more results following
those in this result set (very useful when writing a "pager" type interface,
which needs to know whether to include a "Next" button).
Once you have a SearchResults object, you want to be able to get at the
actual resulting documents. This can be done by using the get_hit()
method, or by iterating through all the results with the usual Python iterator
idiom. Both of these will return SearchResult objects, which is a subclass
of ProcessedDocument , but has the additional property of rank :
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
1 Bible1 ['Bible']
In addition, SearchResults objects have methods allowing a highlighted or
summarised version of a field to be displayed:
>>> results.get_hit(0).highlight('text')[0]
"This is <b>a</b> <b>paragraph</b> of text. It's quite short."
>>> results.get_hit(0).summarise('text', maxlen=20)
'This is <b>a</b> <b>paragraph</b>..'
(Note that the highlight() method returns a list of field instances, as stored
in the document data, so we've asked for it to only return the first of these,
but the summarise() method joins these all together before generating the
summary.)
Queries can be built and combined with other methods. The most flexible of
these is the query_parse() method, which allows a user entered query to be
parsed appropriately. The parser understands "Google style" searches, in which
a search term can be restricted to a specified field by writing
"fieldname:term", and in which boolean operators can be used in the search.
The full syntax is described in the Xapian QueryParser documentation .
(Note that the wildcard option is currently disabled by default.)
If a field has been indexed with the "spell" option turned on, the
spell_correct() method can return a version of the query string with the
spelling corrected. This method takes similar arguments to query_parse() ,
but instead of performing a search, it returns the corrected query string (or
the original query string, if no spelling corrections were found).
>>> conn.spell_correct('teext')
'text'
In addition, two queries may be combined (with an AND or OR operator) using the
query_composite() method, or a query can be "filtered" with another query
such that only documents which match both queries will be returned (but the
rankings are determined by the first query) using the query_filter()
method.
To perform a range restriction, a range query can be built using the
query_range() method. This will return a query which matches all documents
in the database which satisfy the range restriction:
>>> rq = conn.query_range('date', '20000101', '20010101')
This query can be performed on its own, but note that for a large database it
could take a long time to run, because if run on its own it will iterate
through all the values in the database to return those which fit in the range.
Instead, it will usually be used in conjunction with the query_filter()
method, to filter the results of an existing query:
>>> filtered_query = conn.query_filter(q, rq)
>>> print filtered_query
Xapian::Query((((ZXBcreat:(pos=1) OR ZXBa:(pos=2) OR ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) OR XBa:(pos=2) OR XBparagraph:(pos=3))) FILTER VALUE_RANGE 1 20000101 20010101))
Note
The implementation of sorting and range filtering for floating point values uses terms which typically contain non-printable characters. Don't panic if you call print on a query generated with query_range() and odd control-characters are displayed; it's probably normal.)
To get a list of the tags which are contained in the result set, we have to
specify the gettags parameter to the search() method:
>>> results = conn.search(q, 0, 10, gettags='tag')
>>> results.get_top_tags('tag', 10)
[('tag1', 1), ('test document', 1)]
Note
When the result set is being generated, various optimisations are performed to avoid wasting time looking at documents which can't possibly get into the portion of the result set which has been requested. These are normally desirable optimisations because they can speed up searches considerably, but if information about the tags in the result set as a whole is desired, the optimisations can cause inaccurate values to be returned. Therefore, it is possible to force the search engine to look at at least a minimum number of results, by setting the "checkatleast" parameter of the search() method. As a special case, a value of -1 forces all matches to be examined, regardless of database size: this should be used with care, because it can result in slow searches.
To search for only those documents containing a given tag, we can use the
query_field() method:
>>> results = conn.search(conn.query_field('tag', 'tag1'), 0, 10)
>>> results.matches_estimated, results.estimate_is_exact
(1, True)
>>> results.get_hit(0).highlight('text')[0]
"This is a paragraph of text. It's quite short."
To get a list of facets which are relevant to the result set, we have to
specify the getfacets parameter to the search() method. We can also specify
the allowfacets or denyfacets parameters to control the set of facets which are
considered for display (this may be useful to reduce work if we've already
restricted to a particular facet value, for example). Note that as with the
gettags option, it may be advisable to specify a reasonably high value for the
"checkatleast" parameter:
>>> results = conn.search(q, 0, 10, checkatleast=1000, getfacets=True)
>>> results.get_suggested_facets()
[('category', [('bible', 1), ('test documents', 1)]), ('price', [((12.199999999999999, 12.199999999999999), 1), ((20.559999999999999, 20.559999999999999), 1)])]
Note that the values for the suggested facets contain the string for facets of
type "string", but contain a pair of numbers for facets of type "float" - these
numbers define an automatically suggested range of values to use for the facet.
To restrict a further search to a particular value of the facet, or range of
facets, a query can be produced using the query_facet() method. This will
often be combined with an existing query using query_filter(), but you are free
to use it differently if you wish. Note that the values in the output of
get_suggested_facets() are in a form suitable for passing to the value
parameter of query_facet(). For example, results can be restricted using a
"string" facet like this:
>>> facet_q = conn.query_facet('category', 'bible')
>>> results = conn.search(conn.query_filter(q, facet_q), 0, 10)
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 Bible1 ['Bible']
Or can be restricted using a "float" facet like this:
>>> facet_q = conn.query_facet('price', (20.559999999999999, 20.559999999999999))
>>> results = conn.search(conn.query_filter(q, facet_q), 0, 10)
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
Sometimes, instead of searching for documents matching a specific set of
criteria, you want to find documents similar to a document (or documents) that
you already have. You might also want to combine such a similarity search with
a search for some specific criteria; restricting the results by the criteria,
but sorting in similarity order.
This can be achieved using the query_similar() method, which produces a
query, based on a list of document ids, which will return documents similar to
those identified by the supplied document IDs.
The similarity search is only based on the terms generated for free text
searching (ie, with the INDEX_FREETEXT action), so there must be at least
one such field for the similarity search to work. By default, all fields
indexed with INDEX_FREETEXT will be used for the similarity search, but the
list of fields to use may be controlled with the allow and deny
parameters.
In addition, the number of terms to use for the similarity calculation may be
controlled with the simterms parameter (which defaults to 10). A higher
value will allow documents which are less similar to appear in the result set
(but the most similar documents will still occur first). A lower value will
usually result in a faster search. 10 is probably a suitable value in most
situations, but experimentation may be worthwhile for a particular dataset to
determine whether changing the value can improve the results (or produce a
useful speedup without compromising the results).
To perform a simple similarity search, based on a few document IDs:
>>> simq = conn.query_similar(('Bible1',))
>>> results = conn.search(simq, 0, 10)
>>> [result.id for result in results]
['Bible1', 'Bible2', '0']
Note that the document ID supplied came first in the set of results. While
this is not guaranteed (in particular, it may not occur if there are other
documents in the search corpus which are very similar to the supplied
documents), this will usually be the case - if you wish to ignore the documents
specified, you should ask for the appropriate number of extra results, and
filter them out at display time (don't just ignore the top N results, assuming
that they are those supplied).
To perform a normal search, but reorder the ranking based on similarity, use
the query_filter() method to filter the results of a similarity search to
be only those documents which match the normal search:
>>> plainq = conn.query_field('text', 'God OR moved OR text')
>>> simq = conn.query_similar(('Bible1',))
>>> combined = conn.query_filter(simq, plainq)
>>> results = conn.search(plainq, 0, 10)
>>> [result.id for result in results]
['Bible2', '0', 'Bible1']
>>> results = conn.search(combined, 0, 10)
>>> [result.id for result in results]
['Bible1', 'Bible2', '0']
Unfortunately, Xapian's current database implementation doesn't allow search
connections to be arbitrarily old: once two updates have been made to the
database since the connection was opened, the connection may fail with a
"DatabaseModifiedError" when it tries to access the database. Once this has
happened, the search connection needs to be reopened to proceed further, and
will then access a new, updated, view of the database.
To make this easier to manage, if the "DatabaseModifiedError" occurs during the
search process, the error will be handled automatically, and the search will be
re-performed. However, it is still possible for the error to occur when
retrieving the document data from a search result, so handling for this should
be included in code which reads the data from search results.
To avoid this happening, avoid calling the flush() method on the indexer
connection too frequently, and call the reopen() method on the search
connection before performing each new search. You should generally try not to
call flush() more than once every 60 seconds anyway, because performance with
many small flushes will be sub-optimal.
We hope to remove this restriction in a future release of Xapian.
By default, the results are returned in order sorted by their "relevance" to
the query, with the most relevant documents returned first. This order may be
changed by specifying the sortby parameter of the search() method. The field
specified in this parameter must have been given the SORTABLE action before
indexing:
>>> results = conn.search(q, 0, 10, sortby='category')
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 Bible1 ['Bible']
1 0 ['Test documents']
The sort is in ascending order by default (ie, documents with a field value
which is first in order will be returned first). The opposite order can be
requested by preceding the field name with a "-" sign:
>>> results = conn.search(q, 0, 10, sortby='-category')
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
1 Bible1 ['Bible']
Note
There is some potential for confusion here, because Xapian defines
ascending order in the opposite direction: its logic is that ascending order
means that the value should be highest in documents which come top of the
result list. This seems counter-intuitive to many people, and hopefully the
sort order definition here will seem more natural.
If the sort terms are equal, the documents with equal sort terms will be
returned in relevance order.
Xapian offers the useful feature of collapsing the result set such that only
the top result with a given "collapse" value is returned. This feature can be
used by adding a COLLAPSE action to the field before indexing, and then
setting the collapse parameter of the search() method to the field name:
>>> q = conn.query_field('title', 'document')
>>> [result.id for result in conn.search(q, 0, 10)]
['Bible1', '0', 'Bible2']
>>> [result.id for result in conn.search(q, 0, 10, collapse='category')]
['Bible1', '0']
Most errors raised by xappy will be a subclass of xappy.SearchEngineError (the
only deliberate exceptions are standard python errors, caused by invalid
parameters being supplied to xappy). Any errors related to searching will be
instances of xappy.SearchError, and errors related to indexing will be
instances of xappy.IndexerError.
Errors may also be raised by the underlying Xapian library. For example, if
you attempt to make two simultaneous IndexerConnections to a single database,
Xapian will raise a xapian.DatabaseLockError. However, to avoid users of xappy
needing to import xapian, the xapian errors are exposed by xappy. For example,
xapian.DatabaseLockError can be caught by catching
xappy.XapianDatabaseLockError (note the "Xapian" prefix of
"XapianDatabaseLockError"). In addition, the inheritance heirarchy of the
xapian errors is modified so that xappy.XapianError can be used as a catch-all
for all Xapian errors, and xappy.SearchEngineError will catch all Xapian errors as well as any errors directly from xappy.
xappy-0.5/docs/introduction.rst 0000644 0001750 0001750 00000076455 11001744507 016554 0 ustar richard richard Introduction
============
.. contents:: Table of contents
The "xappy" module is an easy-to-use interface to the Xapian search engine.
Xapian provides a low level interface, dealing with terms and documents, but
not really worrying about where terms come from, or how to build searches to
match the way in which data has been indexed. In contrast, Xappy allows you
to design a field structure, specifying what kind of information is held in
particular fields, and then uses this field structure to index data
appropriately, and to build and perform searches.
Installing and testing
======================
Dependencies
------------
You will need an up-to-date version of Xapian (both the core library and the
corresponding Python bindings) to use Xappy. Unfortunately, the latest
release (1.0.3) doesn't support all the features needed by Xappy, so you will
either need a recent snapshot release, or to build from Xapian SVN HEAD. We
recommend using a snapshot unless you are actively developing Xapian itself.
We hope that release 1.0.4 will be suitable for use with Xappy.
Installation
------------
There is not yet a distutils setup script for xappy, but other than Xapian it
has no dependencies or resources which need installing, so it may be installed
simply by copying the "xappy" directory to somewhere on your Python path.
Once Xapian and Xappy are installed, you should be able to start the python
interpreter and run::
>>> import xappy
Running the testsuite
---------------------
To run the testsuite, simply run "./testsuite/runtests.py". This will
display any errors produced when running the testsuite, and then display a
coverage report for the modules tested.
The testsuite is composed of tests taken from three sources:
- doctest tests in the code comments in the
- additional doctest tests in text files with names of the form
'FOO_doctestN.txt', which test the module named "FOO" (and are run in a
context in which the modules public symbols have all been imported).
- additional documentation files (such as this one) which contain doctest
formatted examples.
The list of core modules to test, and additional documentation files to check,
is maintained in the "testsuite/runtests.py" file.
The coverage report displayed after running the testsuite is statement based,
which is sadly one of the least precise methods of generating a coverage
report, and counts lines as having been executed even if they haven't been
tested in all possible code paths. On the plus side, its judgement is reliable
if it considers that a line of code hasn't been tested. For this reason, it is
reasonable to aim for 100% coverage by this metric, and the coverage report can
be helpful to keep track of sections of code which aren't tested at all.
For any released version of Xappy, the coverage report should indicate 100%
coverage for all modules. However, if you are using an SVN snapshot of Xappy,
you may find that some code is not covered. In addition, the coverage testing
currently contains a bug when run under Python 2.5 which causes some lines of
code to be incorectly marked as "not covered" when they actually are. When run
under Python 2.4, this bug doesn't manifest.
Building a database
===================
Setting up a field structure
----------------------------
Before we process any documents, we need to create a database to hold the
documents. This is done simply by creating an "IndexerConnection" object, and
passing it the path we want to create the database at. If the database doesn't
already exist, this will create a new, empty, database::
>>> conn = xappy.IndexerConnection('db1')
.. note:: All connections may only be accessed from a single thread at a time,
and there may only be one IndexerConnection in existence at any given time.
Additionally, it generally gives a large performance gain to ensure that the
connection is kept open between modifications of the database, so that
modifications can be grouped together. Therefore, you must protect access to
the connection with a mutex if multiple threads might access it.
Once we've created an IndexerConnection, we can use it to specify the actions
which should be performed on fields with a given name. There are several
actions available, for different types of field content, and for different
types of searches. You need to decide what actions you need before adding
documents, because the database does not store enough information about
documents to get back to the unprocessed document. The connection will allow
you to change the field actions after documents have been added, but this
change will not be reflected in any documents which have already been added to
the database.
Fields which contain plain text should be added with the ``INDEX_FREETEXT``
action. This action takes various optional parameters:
- ``weight``: if this is supplied, the frequency information for all terms in
the specified field will be multiplied by the given factor; this can be used
for fields which are often a better indication of the subject matter than
other fields (eg, title fields).
- ``language``: if this is supplied, it indicates the language that the
supplied text is written in: this is used to perform language specific term
normalising (to allow, for example, plural and singular forms to be
matched). The language may be specified as a 2 character ISO-639 language
code.
- ``stop``: if this is supplied, it must contain an sequence or other iterable
which returns a list of stopwords, which will be filtered out of the index.
This may reduce index size and improve search and indexing speed, but will
reduce the flexibility of the search. Note that some information on the
terms in the stoplist will still be stored, to allow phrase searches to be
performed.
- ``spell``: this is a boolean flag; if supplied, and true, the contents of
the field will be used for spelling correction.
- ``nopos``: this is a boolean flag; if supplied, and true, the positions of
words in the field will not be stored. These are used for performing phrase
and proximity searches, so this kind of search will not be possible on the
field. On the other hand, the amount of data indexed for the field will be
reduced, resulting in a lower database size, faster indexing, and
potentially faster searching.
- ``allow_field_specific``: this is a boolean flag - if False, prevents terms
with the field prefix being generated. This means that searches specific to
this field will not work, and thus should only be used when only non-field
specific searches are desired. Defaults to True.
- ``search_by_default``: this is a boolean flag - if False, the field will not
be searched by non-field specific searches. If True, or omitted, the field
will be included in searches for non field-specific searches.
All text passed to the interface is assumed to be UTF-8 encoded Unicode.
::
>>> conn.add_field_action('title', xappy.FieldActions.INDEX_FREETEXT, weight=5, language='en')
>>> conn.add_field_action('text', xappy.FieldActions.INDEX_FREETEXT, language='en', spell=True)
Any fields which contain exact values which we want to search for (such as a
category name, or an ID number should be given the ``INDEX_EXACT`` actions.
This doesn't perform any processing on the field value, so any symbols or
punctuation will be preserved in the database::
>>> conn.add_field_action('category', xappy.FieldActions.INDEX_EXACT)
If we want to be able to sort on a field, we need to give it the ``SORTABLE``
action. By default, sorting is performed based on a lexicographical comparison
of string values, but it is possible to set the sort order to be by date, or by
floating point number. Fields which are given then ``SORTABLE`` action can
also be used to restrict the results to a given range - think of it as
declaring that there is a useful ordering for the field values.
Date values can be supplied as strings in the form YYYYMMDD or YYYY-MM-DD (or
using / or . as separators). Floating point numbers can be in any
representation which is understood by Python's float() function::
>>> conn.add_field_action('category', xappy.FieldActions.SORTABLE)
>>> conn.add_field_action('date', xappy.FieldActions.SORTABLE, type="date")
>>> conn.add_field_action('price', xappy.FieldActions.SORTABLE, type="float")
If we want to be able to be able to remove duplicates based on a field, we need
to give it the ``COLLAPSE`` action. This allows the result set to be
"collapsed" such that only the highest result with each value of a field will
be returned. For example, we might want to just display the highest ranked
document in each category (with a link to a list of the results in that
category)::
>>> conn.add_field_action('category', xappy.FieldActions.COLLAPSE)
If we want to be able to retrieve data from the document when it is
the result of a search, we need to set the ``STORE_CONTENT`` action::
>>> conn.add_field_action('text', xappy.FieldActions.STORE_CONTENT)
>>> conn.add_field_action('title', xappy.FieldActions.STORE_CONTENT)
>>> conn.add_field_action('category', xappy.FieldActions.STORE_CONTENT)
If we want to use the contents of a field as "tags", which can be counted at
search time (possibly, in order to build a tag-cloud, or other such
visualisation), we need to set the ``TAG`` action::
>>> conn.add_field_action('tag', xappy.FieldActions.TAG)
Xappy also supports "faceted browsing": this means attaching "facets" to
documents, where a facet is a value representing one aspect of information
about a document: for example, the price of an object would be a facet of a
document representing that object. Xappy supports storing many facets about a
document, restricting the search results to only those documents which contain
a particular facet, and automatically selecting a set of facets which are
relevant to the set of results returned by a search (so that the facets can be
presented to the user to be used to refine their search).
If we want to use a field as a facet, we simply add the ``FACET`` action to it.
Facets can be of two types - "string" (which are just exact string matches), or
"float" (which will automatically be grouped into ranges when returning a
suggested list of facets). The default is "string"::
>>> conn.add_field_action('price', xappy.FieldActions.FACET, type='float')
>>> conn.add_field_action('category', xappy.FieldActions.FACET, type='string')
Indexing
--------
To add data to the database, we first create ``UnprocessedDocument`` objects.
These contain a list of fields, which are processed in turn to create a
``ProcessedDocument``, which can be added to the database. The
``ProcessedDocument`` can't be converted back into an ``UnprocessedDocument``
because some information is generally lost in this processing process (but it
is possible to make alterations directly to the ``ProcessedDocument`` later.
We can access the list of fields in an ``UnprocessedDocument`` directly, using
the ``fields`` member::
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our first document"))
>>> doc.fields.append(xappy.Field("text", "This is a paragraph of text. It's quite short."))
>>> doc.fields.append(xappy.Field("text", "We can create another paragraph of text. "
... "We can have as many of these as we like."))
>>> doc.fields.append(xappy.Field("category", "Test documents"))
>>> doc.fields.append(xappy.Field("tag", "Tag1"))
>>> doc.fields.append(xappy.Field("tag", "Test document"))
>>> doc.fields.append(xappy.Field("tag", "Test document"))
>>> doc.fields.append(xappy.Field("price", "20.56"))
We can add the document directly to the database: if we do this, the connection
will process the document to generate a ``ProcessedDocument`` behind the
scenes, and then add this::
>>> conn.add(doc)
'0'
Note that the ``add`` method returned a value ``'0'``. This is a unique
identifier for the document which was added, and may be used later to delete or
replace the document. If we have externally generated unique identifiers, we
can specify that the system should use them instead of generating its own, by
setting the ``id`` property on the processed or unprocessed document
before adding it to the database.
We can also ask the database to process a document explicitly before calling
the "add" method. We might do this if we want to change the processed document
in some way, but this isn't generally necessary::
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our second document"))
>>> doc.fields.append(xappy.Field("text", "In the beginning God created the heaven and the earth."))
>>> doc.fields.append(xappy.Field("category", "Bible"))
>>> doc.fields.append(xappy.Field("price", "12.20"))
>>> doc.id='Bible1'
>>> pdoc = conn.process(doc)
>>> conn.add(pdoc)
'Bible1'
>>> doc = xappy.UnprocessedDocument()
>>> doc.fields.append(xappy.Field("title", "Our third document"))
>>> doc.fields.append(xappy.Field("text", "And the earth was without form, and void; "
... "and darkness was upon the face of the deep. "
... "And the Spirit of God moved upon the face of the waters."))
>>> doc.fields.append(xappy.Field("category", "Bible"))
>>> doc.fields.append(xappy.Field("date", "17501225"))
>>> doc.fields.append(xappy.Field("price", "16.56"))
>>> doc.id='Bible2'
>>> pdoc = conn.process(doc)
>>> conn.add(pdoc)
'Bible2'
Once we have finished indexing, we should flush the changes to disk. Any
changes which are unflushed may not be preserved if the processes exits without
closing the database nicely::
>>> conn.flush()
Finally, we should close the connection to release its resources (if we leave
this to the garbage collector, this might not happen for a long time). After
closing, no other methods may be called on the connection, but a new connection
can be made.::
>>> conn.close()
Searching
=========
A search connection is opened similarly to an indexing connection. However,
note that multiple search connections may be opened at once (though each
connection must not be accessed from more than one thread). Search connections
can even be open while indexing connections are::
>>> conn = xappy.SearchConnection('db1')
A search connection attempts to provide a stable view of the database, so when
an update is made by a concurrent indexing process, the search connection will
not reflect this change. This allows the results of the search to be gathered
without needing to worry about concurrent updates (but see the section below
about this for limitations on this facility).
The search connection can be reopened at any time to make it point to the
latest version of the database::
>>> conn.reopen()
To perform a search, we need to specify what we're searching for. This is
called a "Query", and the search connection provides several methods for
building up a query. The simplest of these is the ``query_field`` method,
which builds a query to search a single field::
>>> q = conn.query_field('text', 'create a paragraph')
>>> str(q)
'Xapian::Query(((ZXBcreat:(pos=1) AND ZXBa:(pos=2) AND ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) AND XBa:(pos=2) AND XBparagraph:(pos=3))))'
As you can see, the str() function will display the underlying Xapian query
which is generated by the search connection. This may look a little weird at
first, but you can get a general idea of the shape of the query.
The default operator for searches is "AND", but if we wish to be a little wider
in our search, we can use the "OR" operator instead::
>>> q = conn.query_field('text', 'create a paragraph', default_op=conn.OP_OR)
>>> str(q)
'Xapian::Query(((ZXBcreat:(pos=1) OR ZXBa:(pos=2) OR ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) OR XBa:(pos=2) OR XBparagraph:(pos=3))))'
Once we have a query, we can use it to get a set of search results. Xapian is
optimised for situations where only a small subset of the total result set is
required, so when we perform a search we specify the starting `rank` (ie, the
position in the total set of results, starting at 0) of the results we want to
retrieve, and also the ending rank. Following usual Python conventions, the
ending rank isn't inclusive, but the starting rank is.
In this case we want the first 10 results, so we can search with::
>>> results = conn.search(q, 0, 10)
The result set has a variety of pieces of information, but a useful one is the
estimate of the total number of matching documents::
>>> results.matches_estimated
2
Only an estimated value is available because of Xapian's optimisations: the
search process can often stop early because it has proved that there can be no
better ranked documents, and especially for large searches, it would be a waste
of time to then attempt to calculate the precise number of matching documents.
We can check if the estimate is known to be correct by looking at the
``estimate_is_exact`` property::
>>> results.estimate_is_exact
True
The ``SearchResults`` object also provides upper and lower bounds on the number
of matching documents, and a check for whether there are more results following
those in this result set (very useful when writing a "pager" type interface,
which needs to know whether to include a "Next" button).
Once you have a ``SearchResults`` object, you want to be able to get at the
actual resulting documents. This can be done by using the ``get_hit()``
method, or by iterating through all the results with the usual Python iterator
idiom. Both of these will return ``SearchResult`` objects, which is a subclass
of ``ProcessedDocument``, but has the additional property of `rank`::
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
1 Bible1 ['Bible']
In addition, ``SearchResults`` objects have methods allowing a highlighted or
summarised version of a field to be displayed::
>>> results.get_hit(0).highlight('text')[0]
"This is a paragraph of text. It's quite short."
>>> results.get_hit(0).summarise('text', maxlen=20)
'This is a paragraph ..'
(Note that the highlight() method returns a list of field instances, as stored
in the document data, so we've asked for it to only return the first of these,
but the summarise() method joins these all together before generating the
summary.)
Queries can be built and combined with other methods. The most flexible of
these is the ``query_parse()`` method, which allows a user entered query to be
parsed appropriately. The parser understands "Google style" searches, in which
a search term can be restricted to a specified field by writing
"fieldname:term", and in which boolean operators can be used in the search.
The full syntax is described in the `Xapian QueryParser documentation`_.
(Note that the wildcard option is currently disabled by default.)
If a field has been indexed with the "spell" option turned on, the
``spell_correct()`` method can return a version of the query string with the
spelling corrected. This method takes similar arguments to ``query_parse()``,
but instead of performing a search, it returns the corrected query string (or
the original query string, if no spelling corrections were found).
>>> conn.spell_correct('teext')
'text'
In addition, two queries may be combined (with an AND or OR operator) using the
``query_composite()`` method, or a query can be "filtered" with another query
such that only documents which match both queries will be returned (but the
rankings are determined by the first query) using the ``query_filter()``
method.
To perform a range restriction, a range query can be built using the
``query_range()`` method. This will return a query which matches all documents
in the database which satisfy the range restriction::
>>> rq = conn.query_range('date', '20000101', '20010101')
This query can be performed on its own, but note that for a large database it
could take a long time to run, because if run on its own it will iterate
through all the values in the database to return those which fit in the range.
Instead, it will usually be used in conjunction with the ``query_filter()``
method, to filter the results of an existing query::
>>> filtered_query = conn.query_filter(q, rq)
>>> print filtered_query
Xapian::Query((((ZXBcreat:(pos=1) OR ZXBa:(pos=2) OR ZXBparagraph:(pos=3)) AND_MAYBE (XBcreate:(pos=1) OR XBa:(pos=2) OR XBparagraph:(pos=3))) FILTER VALUE_RANGE 1 20000101 20010101))
.. Note:: The implementation of sorting and range filtering for floating point values uses terms which typically contain non-printable characters. Don't panic if you call ``print`` on a query generated with ``query_range()`` and odd control-characters are displayed; it's probably normal.)
To get a list of the tags which are contained in the result set, we have to
specify the gettags parameter to the search() method::
>>> results = conn.search(q, 0, 10, gettags='tag')
>>> results.get_top_tags('tag', 10)
[('tag1', 1), ('test document', 1)]
.. Note:: When the result set is being generated, various optimisations are performed to avoid wasting time looking at documents which can't possibly get into the portion of the result set which has been requested. These are normally desirable optimisations because they can speed up searches considerably, but if information about the tags in the result set as a whole is desired, the optimisations can cause inaccurate values to be returned. Therefore, it is possible to force the search engine to look at at least a minimum number of results, by setting the "checkatleast" parameter of the search() method. As a special case, a value of -1 forces all matches to be examined, regardless of database size: this should be used with care, because it can result in slow searches.
To search for only those documents containing a given tag, we can use the
query_field() method::
>>> results = conn.search(conn.query_field('tag', 'tag1'), 0, 10)
>>> results.matches_estimated, results.estimate_is_exact
(1, True)
>>> results.get_hit(0).highlight('text')[0]
"This is a paragraph of text. It's quite short."
To get a list of facets which are relevant to the result set, we have to
specify the getfacets parameter to the search() method. We can also specify
the allowfacets or denyfacets parameters to control the set of facets which are
considered for display (this may be useful to reduce work if we've already
restricted to a particular facet value, for example). Note that as with the
gettags option, it may be advisable to specify a reasonably high value for the
"checkatleast" parameter::
>>> results = conn.search(q, 0, 10, checkatleast=1000, getfacets=True)
>>> results.get_suggested_facets()
[('category', [('bible', 1), ('test documents', 1)]), ('price', [((12.199999999999999, 12.199999999999999), 1), ((20.559999999999999, 20.559999999999999), 1)])]
Note that the values for the suggested facets contain the string for facets of
type "string", but contain a pair of numbers for facets of type "float" - these
numbers define an automatically suggested range of values to use for the facet.
To restrict a further search to a particular value of the facet, or range of
facets, a query can be produced using the query_facet() method. This will
often be combined with an existing query using query_filter(), but you are free
to use it differently if you wish. Note that the values in the output of
get_suggested_facets() are in a form suitable for passing to the value
parameter of query_facet(). For example, results can be restricted using a
"string" facet like this::
>>> facet_q = conn.query_facet('category', 'bible')
>>> results = conn.search(conn.query_filter(q, facet_q), 0, 10)
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 Bible1 ['Bible']
Or can be restricted using a "float" facet like this::
>>> facet_q = conn.query_facet('price', (20.559999999999999, 20.559999999999999))
>>> results = conn.search(conn.query_filter(q, facet_q), 0, 10)
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
Finding similar documents
-------------------------
Sometimes, instead of searching for documents matching a specific set of
criteria, you want to find documents similar to a document (or documents) that
you already have. You might also want to combine such a similarity search with
a search for some specific criteria; restricting the results by the criteria,
but sorting in similarity order.
This can be achieved using the ``query_similar()`` method, which produces a
query, based on a list of document ids, which will return documents similar to
those identified by the supplied document IDs.
The similarity search is only based on the terms generated for free text
searching (ie, with the ``INDEX_FREETEXT`` action), so there must be at least
one such field for the similarity search to work. By default, all fields
indexed with ``INDEX_FREETEXT`` will be used for the similarity search, but the
list of fields to use may be controlled with the ``allow`` and ``deny``
parameters.
In addition, the number of terms to use for the similarity calculation may be
controlled with the ``simterms`` parameter (which defaults to 10). A higher
value will allow documents which are less similar to appear in the result set
(but the most similar documents will still occur first). A lower value will
usually result in a faster search. 10 is probably a suitable value in most
situations, but experimentation may be worthwhile for a particular dataset to
determine whether changing the value can improve the results (or produce a
useful speedup without compromising the results).
To perform a simple similarity search, based on a few document IDs::
>>> simq = conn.query_similar(('Bible1',))
>>> results = conn.search(simq, 0, 10)
>>> [result.id for result in results]
['Bible1', 'Bible2', '0']
Note that the document ID supplied came first in the set of results. While
this is not guaranteed (in particular, it may not occur if there are other
documents in the search corpus which are very similar to the supplied
documents), this will usually be the case - if you wish to ignore the documents
specified, you should ask for the appropriate number of extra results, and
filter them out at display time (don't just ignore the top N results, assuming
that they are those supplied).
To perform a normal search, but reorder the ranking based on similarity, use
the ``query_filter()`` method to filter the results of a similarity search to
be only those documents which match the normal search::
>>> plainq = conn.query_field('text', 'God OR moved OR text')
>>> simq = conn.query_similar(('Bible1',))
>>> combined = conn.query_filter(simq, plainq)
>>> results = conn.search(plainq, 0, 10)
>>> [result.id for result in results]
['Bible2', '0', 'Bible1']
>>> results = conn.search(combined, 0, 10)
>>> [result.id for result in results]
['Bible1', 'Bible2', '0']
Concurrent update limitations
-----------------------------
Unfortunately, Xapian's current database implementation doesn't allow search
connections to be arbitrarily old: once *two* updates have been made to the
database since the connection was opened, the connection may fail with a
"DatabaseModifiedError" when it tries to access the database. Once this has
happened, the search connection needs to be reopened to proceed further, and
will then access a new, updated, view of the database.
To make this easier to manage, if the "DatabaseModifiedError" occurs during the
search process, the error will be handled automatically, and the search will be
re-performed. However, it is still possible for the error to occur when
retrieving the document data from a search result, so handling for this should
be included in code which reads the data from search results.
To avoid this happening, avoid calling the flush() method on the indexer
connection too frequently, and call the reopen() method on the search
connection before performing each new search. You should generally try not to
call flush() more than once every 60 seconds anyway, because performance with
many small flushes will be sub-optimal.
We hope to remove this restriction in a future release of Xapian.
Sorting
-------
By default, the results are returned in order sorted by their "relevance" to
the query, with the most relevant documents returned first. This order may be
changed by specifying the sortby parameter of the search() method. The field
specified in this parameter must have been given the ``SORTABLE`` action before
indexing::
>>> results = conn.search(q, 0, 10, sortby='category')
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 Bible1 ['Bible']
1 0 ['Test documents']
The sort is in ascending order by default (ie, documents with a field value
which is first in order will be returned first). The opposite order can be
requested by preceding the field name with a "-" sign::
>>> results = conn.search(q, 0, 10, sortby='-category')
>>> for result in results:
... print result.rank, result.id, result.data['category']
0 0 ['Test documents']
1 Bible1 ['Bible']
.. note:: There is some potential for confusion here, because Xapian defines
ascending order in the opposite direction: its logic is that ascending order
means that the value should be highest in documents which come top of the
result list. This seems counter-intuitive to many people, and hopefully the
sort order definition here will seem more natural.
If the sort terms are equal, the documents with equal sort terms will be
returned in relevance order.
Collapsing
----------
Xapian offers the useful feature of collapsing the result set such that only
the top result with a given "collapse" value is returned. This feature can be
used by adding a ``COLLAPSE`` action to the field before indexing, and then
setting the collapse parameter of the ``search()`` method to the field name::
>>> q = conn.query_field('title', 'document')
>>> [result.id for result in conn.search(q, 0, 10)]
['Bible1', '0', 'Bible2']
>>> [result.id for result in conn.search(q, 0, 10, collapse='category')]
['Bible1', '0']
Errors
======
Most errors raised by xappy will be a subclass of xappy.SearchEngineError (the
only deliberate exceptions are standard python errors, caused by invalid
parameters being supplied to xappy). Any errors related to searching will be
instances of xappy.SearchError, and errors related to indexing will be
instances of xappy.IndexerError.
Errors may also be raised by the underlying Xapian library. For example, if
you attempt to make two simultaneous IndexerConnections to a single database,
Xapian will raise a xapian.DatabaseLockError. However, to avoid users of xappy
needing to import xapian, the xapian errors are exposed by xappy. For example,
xapian.DatabaseLockError can be caught by catching
xappy.XapianDatabaseLockError (note the "Xapian" prefix of
"XapianDatabaseLockError"). In addition, the inheritance heirarchy of the
xapian errors is modified so that xappy.XapianError can be used as a catch-all
for all Xapian errors, and xappy.SearchEngineError will catch all Xapian errors as well as any errors directly from xappy.
Other documentation
===================
Detailed API documentation is available as docstrings in the Python code, but
you may find it more convenient to browse it in `formatted form (as generated by
epydoc)`_.
.. _formatted form (as generated by epydoc): api/index.html
.. _Xapian QueryParser documentation: http://xapian.org/docs/queryparser.html
xappy-0.5/docs/running_perftest.txt 0000644 0001750 0001750 00000002016 10702552751 017421 0 ustar richard richard Firstly, check out xappy:
svn co http://xappy.googlecode.com/svn/trunk xappy
cd xappy/
Check it's working properly, if you like:
python testsuite/runtests.py
Now, go into the performance test directory:
cd perftest/
mkdir sampledata
The following instructions assume you're on atreus.tartarus.org. On other
machines, you'll need to get the wikipedia data, and process it into a
"scriptindex" dump format. This can be done using the
"parse_wikipedia/wiki2dump.py" script inside the perftest directory (you can
just ignore the "redirects output file").
Link to the wikipedia sample data:
ln -s /home/richard/pub/data/wikipedia_processed/out_splitaa sampledata/wikipedia.dump
(or use split_ab for a small piece of data)
Generate some sample queries (the source data is in ../testdata - could do with
better source data):
python gen_queries.py
mv ../testdata/queries.txt sampledata/
Finally, run the performance tests:
python perftest.py
The output will be placed in "perftestoutdir/"
xappy-0.5/examples/ 0000755 0001750 0001750 00000000000 11005556727 014157 5 ustar richard richard xappy-0.5/examples/fileindex.py 0000755 0001750 0001750 00000005041 10667537053 016507 0 ustar richard richard #!/usr/bin/env python
import sys
import os
def _setup_path():
"""Set up sys.path to allow us to import Xappy when run uninstalled.
"""
abspath = os.path.abspath(__file__)
dirname = os.path.dirname(abspath)
dirname, ourdir = os.path.split(dirname)
dirname, parentdir = os.path.split(dirname)
if (parentdir, ourdir) == ('xappy', 'examples'):
sys.path.insert(0, '..')
_setup_path()
import xappy
def create_index(dbpath):
"""Create a new index, and set up its field structure.
"""
iconn = xappy.IndexerConnection(dbpath)
iconn.add_field_action('path', xappy.FieldActions.STORE_CONTENT)
iconn.add_field_action('path', xappy.FieldActions.INDEX_EXACT)
iconn.add_field_action('pathcomponent', xappy.FieldActions.INDEX_EXACT)
iconn.add_field_action('text', xappy.FieldActions.STORE_CONTENT)
iconn.add_field_action('text', xappy.FieldActions.INDEX_FREETEXT, language='en')
iconn.close()
def open_index(dbpath):
"""Open an existing index.
"""
return xappy.IndexerConnection(dbpath)
def canonical_path(path):
"""Convert a path to a canonical form."""
path = os.path.realpath(path)
path = os.path.normpath(path)
path = os.path.normcase(path)
return path
def index_content(doc, filepath):
"""Index the content of the file."""
fd = open(filepath)
contents = fd.read()
fd.close()
try:
contents = unicode(contents)
except UnicodeDecodeError:
return
doc.fields.append(xappy.Field('text', contents))
def index_file(iconn, filepath):
"""Index a file."""
filepath = canonical_path(filepath)
doc = xappy.UnprocessedDocument()
doc.fields.append(xappy.Field('path', filepath))
components = filepath
while True:
components, dirname = os.path.split(components)
if len(dirname) == 0 or components == '/':
break
doc.fields.append(xappy.Field('pathcomponent', components))
index_content(doc, filepath)
iconn.add(doc)
return 1
def index_path(iconn, docpath):
"""Index a path."""
count = 0
for dirpath, dirnames, filenames in os.walk(docpath):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
index_file(iconn, filepath)
count += 1
return count
def main(argv):
dbpath = 'foo'
docpath = '/usr/share/doc/python2.5'
create_index(dbpath)
iconn = open_index(dbpath)
count = index_path(iconn, docpath)
print "Indexed %d documents." % count
if __name__ == '__main__':
main(sys.argv)
xappy-0.5/examples/search.py 0000755 0001750 0001750 00000002525 10667537061 016010 0 ustar richard richard #!/usr/bin/env python
import sys
import os
import re
def _setup_path():
"""Set up sys.path to allow us to import Xappy when run uninstalled.
"""
abspath = os.path.abspath(__file__)
dirname = os.path.dirname(abspath)
dirname, ourdir = os.path.split(dirname)
dirname, parentdir = os.path.split(dirname)
if (parentdir, ourdir) == ('xappy', 'examples'):
sys.path.insert(0, '..')
_setup_path()
import xappy
_whitespace_re = re.compile('\s+')
def open_index(dbpath):
return xappy.SearchConnection(dbpath)
def main(argv):
dbpath = 'foo'
search = ' '.join(argv[1:])
sconn = open_index(dbpath)
print "Searching %d documents for \"%s\"" % (
sconn.get_doccount(),
search
)
q = sconn.query_parse(search, default_op=sconn.OP_AND)
results = sconn.search(q, 0, 10)
if results.estimate_is_exact:
print "Found %d results" % results.matches_estimated
else:
print "Found approximately %d results" % results.matches_estimated
for result in results:
print result.data['path'][0]
try:
summary = result.summarise('text', hl=('*', '*'), maxlen=300)
summary = ' '.join(_whitespace_re.split(summary))
print summary
except KeyError:
pass
print
if __name__ == '__main__':
main(sys.argv)
xappy-0.5/libs/ 0000755 0001750 0001750 00000000000 11005556727 013272 5 ustar richard richard xappy-0.5/libs/get_xapian.py 0000755 0001750 0001750 00000014617 11005551573 015771 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""get_xapian.py: Download and unpack the xapian archives.
"""
__docformat__ = "restructuredtext en"
import copy
import glob
import os
import sha
import shutil
import subprocess
import sys
import tarfile
import tempfile
import urllib2
# List of the archives.
#
# The values are, in order:
# - Descriptive name of archive
# - URL to download
# - Filename to store downloaded package as
# - SHA1 sum of package
archives = (
('Xapian core',
'http://xappy.googlecode.com/files/xapian-core-10411.tgz',
'xapian-core.tgz',
'8cb209a20492dcb825aad26bae9da52e42e50e3d',
'',
),
('Xapian bindings',
'http://xappy.googlecode.com/files/xapian-bindings-10411.tgz',
'xapian-bindings.tgz',
'795c45683624e8e1691591c1b36a15215a41b1ad',
'',
),
('Xapian win32 build system',
'http://xappy.googlecode.com/files/win32msvc-10411.tgz',
'win32msvc.tgz',
'f48b542ca5f3896923f8a0e1e677d15de417f5a2',
'xapian-core/win32',
),
)
def get_script_dir():
"""Get the path of the directory containing this script.
"""
global scriptdir
if 'scriptdir' not in globals():
scriptdir = os.path.dirname(os.path.abspath(__file__))
return scriptdir
def get_package_dir():
"""Get the path to store the downloaded packages in.
This is a standard location relative to this script.
"""
return os.path.abspath(os.path.join(get_script_dir(), '..', 'libs'))
def calc_sha_hash(filepath):
"""Calculate the SHA1 hash of the file at the given path.
"""
hasher = sha.new()
fd = open(filepath, 'rb', 0)
try:
while True:
chunk = fd.read(65536)
if len(chunk) == 0:
break
hasher.update(chunk)
finally:
fd.close()
return hasher.hexdigest()
def download_file(url, destpath):
"""Download a file, and place it in destpath.
"""
destdir = os.path.dirname(destpath)
if not os.path.isdir(destdir):
os.makedirs(destdir)
fd = urllib2.urlopen(url)
tmpfd, tmpname = tempfile.mkstemp(dir=destdir, prefix='xappy')
try:
os.write(tmpfd, fd.read())
os.close(tmpfd)
os.rename(tmpname, destpath)
finally:
if os.path.exists(tmpname):
os.unlink(tmpname)
def unpack_tar_archive(filename, tempdir):
"""Unpack the tar archive at filename.
Puts the contents in a directory with basename tempdir.
"""
tf = tarfile.open(filename)
try:
dirname = None
for member in tf.getmembers():
topdir = member.name.split('/', 1)[0]
if dirname is None:
dirname = topdir
else:
if dirname != topdir:
raise ValueError('Archive has multiple toplevel directories: %s and %s' % (topdir, dirname))
tf.extract(member, path=tempdir)
return os.path.join(tempdir, dirname)
finally:
tf.close()
def get_archive_from_url(name, url, archivename, expected_hash):
"""Download an archive from the specified URL.
Returns the path the archive was downloaded to, or None if
the archive couldn't be downloaded
"""
print("Checking for %s" % name)
# Get the path that the package should be downloaded to
filepath = os.path.join(package_dir, archivename)
# Check if the package is already downloaded (and has correct SHA key).
if os.path.exists(filepath):
calculated_hash = calc_sha_hash(filepath)
if expected_hash != calculated_hash:
print("Package of %s at '%s' has wrong hash - discarding" % (name, archivename))
print("(Got %s, expected %s)" % (calculated_hash, expected_hash))
os.unlink(filepath)
# Download the package if needed.
if not os.path.exists(filepath):
print("Downloading %s from %s" % (name, url))
download_file(url, filepath)
calculated_hash = calc_sha_hash(filepath)
if expected_hash != calculated_hash:
print("Package of %s at '%s' has wrong hash - cannot continue" % (name, archivename))
print("(Got %s, expected %s)" % (calculated_hash, expected_hash))
os.unlink(filepath)
return None
return filepath
def get_archives(archives):
"""Download and unpack the xapian archives.
"""
package_dir = get_package_dir()
for name, url, archivename, expected_hash, target_location in archives:
archivepath = get_archive_from_url(name, url, archivename, expected_hash)
if archivepath is None:
return False
print("Unpacking %s" % name)
archivedir = unpack_tar_archive(archivepath, package_dir)
if target_location != '':
target_path = os.path.join(package_dir, target_location)
if os.path.exists(target_path):
print("Removing old unpacked copy of archive from %s" %
target_location)
shutil.rmtree(target_path)
print("Moving %s to %s" % (name, target_location))
shutil.move(archivedir, target_path)
return True
def make_file_writable(filename):
if os.name == 'nt':
import win32api, win32con
x = win32api.GetFileAttributes(filename)
x &= ~win32con.FILE_ATTRIBUTE_READONLY
win32api.SetFileAttributes(filename, x)
else:
os.chmod(filename, 700)
def make_tree_writable(root):
for dirpath, dirnames, filenames in os.walk(root):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
make_file_writable(filepath)
if __name__ == '__main__':
package_dir = get_package_dir()
if not get_archives(archives):
sys.exit(1)
sys.exit(0)
xappy-0.5/perftest/ 0000755 0001750 0001750 00000000000 11005556727 014175 5 ustar richard richard xappy-0.5/perftest/parse_wikipedia/ 0000755 0001750 0001750 00000000000 11005556727 017335 5 ustar richard richard xappy-0.5/perftest/parse_wikipedia/Errors.py 0000644 0001750 0001750 00000003617 10667526240 021172 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2006 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import HTMLUtils
class UserError(Exception):
"""
Class used to pass a minor error from code performing an action to code
which displays errors to the user.
The message stored in such an exception should be raw HTML, as passed to
the browser. Any content in this message resulting from user inputs, MUST
be HTML encoded (probably using HTMLUtils.encodeText()) to avoid risk of
cross-site scripting attacks.
For convenience, extra arguments may be provided which will be encoded and
then merged with the message using the % operator. For example:
>>> print UserError('Error message')
Error message
>>> print UserError('Error %s', 'message with quoted')
Error message with <html> quoted
"""
_cname = 'UserError'
def __init__(self, msg, *args):
self.msg = msg % tuple(HTMLUtils.encodeText(arg) for arg in args)
def __str__(self):
return self.msg
def __repr__(self):
return '%s("%s")' % (self._cname, self.msg.replace('\\', '\\\\').replace('"', '\\"'))
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/perftest/parse_wikipedia/HTMLUtils.py 0000644 0001750 0001750 00000020307 10667526240 021476 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2006 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import urllib
import re
import htmlentitydefs
def __booltonum(val):
"""Convert any boolean values to '0' or '1'.
Leave other values alone.
"""
if val is True:
return '1'
elif val is False:
return '0'
return val
def encodeParams(paramdict, **kwargs):
"""Encode a dictionary of parameters to a querystring.
`paramdict` is a dictionary of parameters to encode.
`kwargs` is an optional set of keyword arguments to be added to the
parameters to be encoded. Any entries in kwargs which are also present in
paramdict override the entries in paramdict. Any entries in kwargs with a
value of None cause any corresponding entry in paramdict to be omitted from
the encoded output.
"""
if isinstance(paramdict, dict):
paramlist = [(key, __booltonum(val))
for (key, val) in paramdict.iteritems()
if key not in kwargs and val is not None]
else:
paramlist = [(key, __booltonum(val))
for (key, val) in paramdict
if key not in kwargs and val is not None]
paramlist.extend([(key, val)
for (key, val) in kwargs.iteritems()
if val is not None])
paramlist.sort()
return urllib.urlencode (paramlist)
def encodeAttribValue(value):
"""
Encode an attribute value by replacing HTML characters with entity values.
The value may be unicode or a UTF-8 encoded string.
The result is a UTF-8 encoded string.
>>> encodeAttribValue('bar')
'bar'
>>> encodeAttribValue('bar"')
'bar"'
>>> encodeAttribValue('bar"<>&"')
'bar"<>&"'
>>> print repr(encodeAttribValue(u'bar\\xa3'))
'bar£'
>>> utf8=u'bar\\xa3\\u1234'.encode('utf-8')
>>> print repr(utf8)
'bar\\xc2\\xa3\\xe1\\x88\\xb4'
>>> print repr(encodeAttribValue(utf8))
'bar£ሴ'
Ampersands are escaped even if they already form part of a valid
entity:
>>> encodeAttribValue('bar"<>&"')
'bar"<>&"'
All non-alphanumeric characters are also escaped.
"""
result = []
if isinstance(value, str):
value = unicode(value, 'utf-8')
for char in value:
if (char >= '0' and char <= '9') or (char >= 'a' and char <= 'z') or (char >= 'A' and char <= 'Z') or char in './#_':
result.append(char)
elif char == '&':
result.append('&')
elif char == '"':
result.append('"')
elif char == '<':
result.append('<')
elif char == '>':
result.append('>')
elif char == '(':
result.append('(')
elif char == ')':
result.append(')')
elif char == '#':
result.append('#')
else:
result.append('%s;' % hex(ord(char))[1:])
return ''.join(result).encode('utf-8')
def encodeText(value):
"""Encode a piece of text by replacing HTML characters with entity values.
>>> encodeText('bar')
'bar'
>>> encodeText('bar"')
'bar"'
>>> encodeText('bar"<>&"(')
'bar"<>&"('
Ampersands are escaped even if they already form part of a valid
entity:
>>> encodeText('bar"<>&"')
'bar"<>&"'
A non-string will be returned unchanged:
>>> encodeText(1)
1
"""
if not isinstance(value, basestring):
return value
result = value.replace('&', '&')
result = result.replace('#', '#')
result = result.replace('"', '"')
result = result.replace('<', '<')
result = result.replace('>', '>')
return result
def percentEncode(value):
"""Percent encode a component of a URI.
This replaces special characters with %XX where XX is the hexadecimal value
of the character.
Currently replaces all non-alphanumeric characters with the following
exceptions:
is replaced by +
., /, #, _, = are not replaced.
>>> percentEncode('q=M&%&%; S')
'q=M%26%25%26%25%3B+S'
>>> percentEncode(u'\u00a3')
'%C2%A3'
"""
result = []
if isinstance(value, unicode):
value = value.encode('utf-8')
assert isinstance(value, str)
for char in value:
if (char >= '0' and char <= '9') or (char >= 'a' and char <= 'z') or (char >= 'A' and char <= 'Z') or char in './#_=':
result.append(char)
elif char == ' ':
result.append('+')
else:
result.append('%%%s' % hex(ord(char)).upper()[2:])
return ''.join(result)
def percentDecode(value):
r"""Percent decode a component or a URI.
This replaces percent encode sequences (ie, %XX, where XX is the
hexadecimal value of the character) with the corresponding character.
In addition, it replaces '+' with a space character (ie, + is equivalent to
%20).
Any other sequences following a % will be ignored.
>>> percentDecode('q=M%26%25%26%25%3B+S')
'q=M&%&%; S'
>>> percentDecode('%C2%A3')
'\xc2\xa3'
"""
value = value
if isinstance(value, unicode):
value = value.encode('utf-8')
value = value.replace('+', ' ')
i = 0
result = []
while i != -1:
j = value.find('%', i)
if j == -1:
result.append(value[i:])
break
if j != i:
result.append(value[i:j])
# Everything before position j has now been added to result.
hexdigits = value[j + 1 : j + 3]
try:
hexval = int(hexdigits, 16)
result.append(chr(hexval))
i = j + 3
except ValueError:
result.append(value[j])
i = j + 1
return ''.join(result)
_markupre = re.compile ('?\w[^>]*>')
def stripMarkup (s):
"""
Strip all markup () out of the supplied string.
"""
return _markupre.sub ('', s)
_wikitags = { "''":'i', "'''":'b', '`':'tt', '__':'u', '^':'sup', ',,':'sub',
'~-':'small', '~+':'big' }
_ent_re = re.compile ('[\da-fA-F]+;|\d+;|&\w+;')
def ents2uni (s):
"""
Substitute unicode characters for common HTML entities.
This returns a unicode string.
"""
def _subst (mo):
ms = mo.group(0).lower()
if ms.startswith (''):
return unichr (int (ms[3:-1], 16))
elif ms.startswith (''):
return unichr (int (ms[2:-1]))
elif ms.startswith ('&'):
try:
return unichr (htmlentitydefs.name2codepoint[ms[1:-1]])
except KeyError:
return ms
else:
return ''
return _ent_re.sub (_subst, unicode (s))
_js_slash = { '"':'\\"', '\n':'\\n', '\r':'\\r' }
def js_encode (s):
"""
Encode a unicode string in Javascript literal form.
"""
if isinstance (s, str): return s
ret = []
for c in s:
if c in _js_slash:
ret.append (_js_slash[c])
elif ord(c) < 128:
ret.append (str(c))
else:
ret.append ('\\u%04x' % ord(c))
return ''.join (ret)
__tests__ = {
"Invalid % sequences to decode": """
>>> print percentDecode('%')
%
>>> print percentDecode('%')
%
>>> print percentDecode('foo%')
foo%
>>> print percentDecode('foo%%')
foo%%
>>> print percentDecode('foo%7g')
foo%7g
>>> print percentDecode('foo+%%20%')
foo % %
"""
}
if __name__ == "__main__":
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/perftest/parse_wikipedia/XMLUtils.py 0000644 0001750 0001750 00000127447 10667526240 021407 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2006 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import xml.dom.minidom
import xml.dom.pulldom
import xml.parsers.expat
import xml.sax
import copy, re
import Errors, HTMLUtils
class ParsedXmlTextGetter:
"""
Class used to implement the process of extracting the textual contents of
some XML. Implemented as a class rather than a method so that the setup
process can be shared between calls.
"""
__spaces_re = re.compile(r'\s+')
def __init__(self, nospacetags=None, spacetags=None,
ignoretags=None, requiretags=None,
condenseSpaces=False,
caseInsensitiveTags=False):
"""Set up a text getter.
`nospacetags` is a sequence of tags where the tags should be discarded,
but the contents preserved.
`spacetags` is a sequence of tags where the tags should be replaced by
whitespace, but the contents preserved.
`ignoretags` is a sequence of tags which should be ignored completely.
`requiretags` is a sequence of tags which, if supplied, will cause any
content not contained in one of the tags to be ignored completely.
`condenseSpaces` is a flag; if True, all sequences of whitespace in the
output will be replaced by a single space, and whitespace will be
stripped from the start and end of the result.
`caseInsensitiveTags` is a flag; if True, all tag names will be matched
in a case insensitive manner.
Any tags which are found which are not in one of the above lists will
be treated as if it were in spacetags. (Future implementations may
raise an error here, or be configurable, however.)
"""
if nospacetags is None:
nospacetags = set()
else:
nospacetags = set(nospacetags)
if spacetags is None:
spacetags = set()
else:
spacetags = set(spacetags)
if ignoretags is None:
ignoretags = set()
else:
ignoretags = set(ignoretags)
if requiretags is not None:
requiretags = set(requiretags)
if nospacetags.intersection(spacetags):
raise ValueError, "Tags may not be shared between nospacetags and spacetags"
if nospacetags.intersection(ignoretags):
raise ValueError, "Tags may not be shared between nospacetags and ignoretags"
if spacetags.intersection(ignoretags):
raise ValueError, "Tags may not be shared between spacetags and ignoretags"
if requiretags is not None and ignoretags.intersection(requiretags):
raise ValueError, "Tags may not be shared between ignoretags and requiretags"
if caseInsensitiveTags:
if requiretags is not None:
requiretags = set((item.lower() for item in requiretags))
nospacetags = set((item.lower() for item in nospacetags))
spacetags = set((item.lower() for item in spacetags))
ignoretags = set((item.lower() for item in ignoretags))
self._nospacetags = nospacetags
self._spacetags = spacetags
self._ignoretags = ignoretags
self._requiretags = requiretags
self._condenseSpaces = condenseSpaces
self._caseInsensitiveTags = caseInsensitiveTags
def toText(self, parsedXml):
"""
Convert a parsedXML object to text, according to the rules set up in
this getter.
"""
text = u''
ignoring = 0 # Count of number of ignore tags we're within
required = 0 # Count of number of require tags we're within
if self._requiretags is None:
required = 1 # Pretend we're always within a require tag
for item in parsedXml.getItems():
if item.type == ParsedXmlItem.START:
name = item.nodeNames[-1]
if self._caseInsensitiveTags:
name = name.lower()
if self._requiretags is not None and name in self._requiretags:
required += 1
if name in self._ignoretags:
ignoring += 1
elif ignoring == 0 and required != 0:
if name in self._nospacetags:
pass
elif name in self._spacetags:
text += u' '
else:
text += u' '
elif item.type == ParsedXmlItem.END:
name = item.nodeNames[-1]
if self._caseInsensitiveTags:
name = name.lower()
if name in self._ignoretags:
ignoring -= 1
elif ignoring == 0 and required != 0:
if name in self._nospacetags:
pass
elif name in self._spacetags:
text += u' '
else:
text += u' '
if self._requiretags is not None and name in self._requiretags:
required -= 1
elif item.type == ParsedXmlItem.DATA:
if ignoring == 0 and required != 0:
text += item.data
if self._condenseSpaces:
text = self.__spaces_re.sub(' ', text).strip()
return text
class ParsedXmlItem:
"""
Class representing an item of XML. This is either the start of an element,
the end of an element, or a piece of textual data.
"""
START = 0
END = 1
DATA = 2
typenames = {
START: "START",
END: "END",
DATA: "DATA",
}
def __init__(self, type, nodeNames, atts=None, data=None, node=None, unlinker=None):
self.type = type
self.nodeNames = nodeNames
self.atts = atts
self.data = data
self._node = node
self._unlinker = unlinker
def expand(self):
assert self.type == self.START, 'Cannot expand() when item is not a START item'
expanded = ParsedXml()
expanded._node = self._node
expanded._unlinker = self._unlinker
return expanded
def getAttr(self, name, default=None):
"""Return the attribute of the given name.
If not found, returns default.
"""
try:
return self.atts[name].nodeValue
except KeyError:
return default
def __str__(self):
extra=u''
if self.atts is not None:
for i in xrange(len(self.atts)):
att = self.atts.item(i)
extra += u" %s='%s'" % (att.name, att.nodeValue)
if self.data is not None:
extra += u' data=%s' % repr(self.data)
if len(extra) != 0:
extra = u',' + extra
return u'(%s, %s%s)' % (
self.typenames[self.type],
repr(self.nodeNames),
extra
)
def __repr__(self):
extra=''
if self.atts is not None:
extra += ', atts=%s' % repr(self.atts)
if self.data is not None:
extra += ', data=%s' % repr(self.data)
return 'ParsedXmlItem(ParsedXmlItem.%s, %s%s)' % (
self.typenames[self.type],
repr(self.nodeNames),
extra
)
def toxml (self):
"""
Return this tag/data formatted as XML.
"""
if self.type == self.START:
ret = ['<%s' % self.nodeNames[-1]]
for i in xrange(len(self.atts)):
att = self.atts.item (i)
ret.append (u' %s="%s"' % (att.name, HTMLUtils.encodeText (att.nodeValue)))
ret.append ('>')
return ''.join (ret)
elif self.type == self.END:
return '%s>' % self.nodeNames[-1]
else:
return HTMLUtils.encodeText (self.data)
def _convertParseExceptions(callable, xmlString=None):
"""
Convert exceptions raised by XML parsers to UserErrors describing the
error.
"""
try:
return callable()
except xml.parsers.expat.ExpatError, e:
context = ''
if xmlString:
try:
lines = xmlString.split('\n')
pos = max(e.offset - 10, 0)
line = lines[e.lineno - 1]
context = " (near %s )" % HTMLUtils.encodeText(line[pos:pos + 20])
context = context.replace('%', '%%')
except:
pass
raise Errors.UserError("at line %%s, column %%s%s: %%s" % context,
e.lineno, e.offset,
xml.parsers.expat.ErrorString(e.code))
except xml.sax.SAXParseException, e:
context = ''
if xmlString:
try:
lines = xmlString.split('\n')
pos = max(e.getColumnNumber() - 10, 0)
line = lines[e.getLineNumber() - 1]
context = " (near %s )" % HTMLUtils.encodeText(line[pos:pos + 20])
context = context.replace('%', '%%')
except:
pass
raise Errors.UserError("at line %%s, column %%s%s: %%s" % context,
e.getLineNumber(), e.getColumnNumber(),
e.getMessage())
except ValueError, e:
raise Errors.UserError("Parse error: %s", str(e))
class ParsedXml:
"""
Class representing a parsed piece of XML, and providing several convenience
methods for getting at the parsed XML.
The parsed piece of XML is a single well-formed tag (ie, has exactly one
root node).
"""
def __init__(self, xmlString=None):
"""Initialise the ParsedXml object.
If xmlString is supplied (and not None), it should contain either a
unicode object or utf-8 encoded string object. If fh is supplied, it
should be a filehandle which is open for reading, and is pointing to
the start of an XML file.
Only one of xmlString and fh may be supplied.
"""
# A DOM node representing the parsed XML.
# Used if reading from a string.
self._node = None
# The parsedXml object which should call unlink() on _node, or None if
# this is the object which should do that.
# This is used to ensure that the object which calls unlink isn't
# garbage collected (and hence calls unlink) before all users have
# finished, and hence released their references to it.
self._unlinker = None
# Parse the string:
if xmlString is not None:
self._parseFragment(xmlString)
def __del__(self):
"""
Free the internals. This avoids cyclic garbage collection being
needed.
"""
if self._node is not None:
if self._unlinker is None:
self._node.unlink()
self._node = None
self._unlinker = None
def getAsString(self):
"""Get the parsed piece of XML as a utf-8 string.
"""
if self._node is not None:
return self._node.toxml('utf-8')
def getContentsAsString(self):
"""Get the contents of the parsed piece of XML.
This returns the contents as a utf-8 string.
This includes the contents of the root tag, but not the root tag
itself.
"""
if not self._node.hasChildNodes:
return ''
contents = []
currnode = self._node.firstChild
while currnode is not None:
contents.append(currnode.toxml('utf-8'))
currnode = currnode.nextSibling
return ''.join(contents)
def getText(self, *args, **kwargs):
"""
Get the textual contents of this piece of XML, as a unicode string.
See the documentation for ParsedXmlTextGetter.__init__() for details of
the parameters.
"""
getter = ParsedXmlTextGetter(*args, **kwargs)
return getter.toText(self)
def _parseFragment(self, xmlString):
"""
Parse a fragment of XML, storing the resulting DOM node in this
ParsedXml object.
"""
if isinstance(xmlString, unicode):
# Convert to utf-8
xmlString = xmlString.encode('utf-8')
result = []
def callable():
result.append(xml.dom.minidom.parseString(xmlString))
_convertParseExceptions(callable, xmlString)
# Don't call unlink on the old value of _node: we can't guarantee that
# noone is using it, so we just have to wait for cyclic garbage
# collection to pick it up.
self._node = result[0]
self._unlinker = None
def getItems(self):
"""Return an iterator which returns all the items in the parsed XML.
"""
root = self._node
if root is None:
return iter(())
if root.nodeType == root.DOCUMENT_NODE:
root = root.documentElement
class Iter:
def __init__(self, root, unlinker):
self._unlinker = unlinker
self._nodelist = [[root, None]]
self._nodeNames = []
def __iter__(self):
'Method needed to satisfy iterator protocol.'
return self
def next(self):
'Move to next element, or throw StopIteration.'
if len(self._nodelist) == 0:
raise StopIteration
while len(self._nodelist) != 0:
(node, subpos) = self._nodelist[-1]
if node.nodeType == node.ELEMENT_NODE:
if subpos is None:
# Haven't returned start of node yet.
self._nodeNames.append(node.nodeName)
self._nodelist[-1][1] = 0
return ParsedXmlItem(ParsedXmlItem.START, self._nodeNames, atts=node.attributes, node=node, unlinker=self._unlinker)
else:
# Get next subnode which we care about.
while True:
if subpos >= len(node.childNodes):
break
newnode = node.childNodes[subpos]
subpos += 1
if newnode.nodeType == newnode.ELEMENT_NODE:
# Have an element node
self._nodelist[-1][1] = subpos
self._nodelist.append([newnode, 0])
self._nodeNames.append(newnode.nodeName)
return ParsedXmlItem(ParsedXmlItem.START, self._nodeNames, atts=newnode.attributes, node=newnode, unlinker=self._unlinker)
elif newnode.nodeType == newnode.TEXT_NODE or newnode.nodeType == newnode.CDATA_SECTION_NODE:
# Have a text node - join it with any subsequent text nodes.
result = ParsedXmlItem(ParsedXmlItem.DATA, self._nodeNames, data=newnode.data)
resultdata = [result.data]
while subpos < len(node.childNodes):
nextnode = node.childNodes[subpos]
if nextnode.nodeType == nextnode.ELEMENT_NODE:
# An element - need to leave this
# to be dealt with later.
break
elif nextnode.nodeType == nextnode.TEXT_NODE or nextnode.nodeType == nextnode.CDATA_SECTION_NODE:
# More text - add it to this node.
resultdata.append(nextnode.data)
else:
pass
subpos += 1
result.data = u''.join(resultdata)
self._nodelist[-1][1] = subpos
return result
else:
# Have a node which is neither text nor an element.
# Skip it.
pass
# No more subnodes - return end of parent node.
result = ParsedXmlItem(ParsedXmlItem.END, copy.copy(self._nodeNames), atts=node.attributes)
self._nodeNames.pop()
self._nodelist.pop()
return result
elif node.nodeType == node.TEXT_NODE or node.nodeType == node.CDATA_SECTION_NODE:
# Have a text node
self._nodelist.pop()
return ParsedXmlItem(ParsedXmlItem.DATA, self._nodeNames, data=node.data)
else:
# Have a node which is neither text nor an element.
# Skip it.
pass
def expand(self):
"""
Expand the current item (and its subitems) by returning a
ParsedXml object representing the current item.
Only valid when the current item (ie, last returned by next())
is a START item. See also the skipContents() method, which is
often useful in conjunction with this method.
"""
assert self._nodelist[-1][1] != 0, 'Cannot expand() when current item is not a START item'
expanded = ParsedXml()
expanded._node = self._nodelist[-1][0]
expanded._unlinker = self._unlinker
return expanded
def skipContents(self):
"""
If the current item is a START item, advances the iterator such
that the next item is the corresponding END item. Otherwise,
has no effect.
"""
if self._nodelist[-1][1] != 0:
return
self._nodelist[-1][1] = len(self._nodelist[-1][0].childNodes)
if self._unlinker is None:
return Iter(root, self)
else:
return Iter(root, self._unlinker)
class ParsedXmlFileItem(ParsedXmlItem):
"""Class representing an item of XML read from a file.
This is either the start of an element, the end of an element, or a piece
of textual data.
"""
def __init__(self, type, nodeNames, atts=None, data=None, node=None, unlinker=None, expander=None):
ParsedXmlItem.__init__(self, type, nodeNames, atts=atts, data=data, node=node, unlinker=unlinker)
self._expander = expander
def expand(self):
"""Expand the item, by returning a ParsedXml object representing the
current item.
Note that this is only valid if the iterator that this
ParsedXmlFileItem came from hasn't moved since making this
ParsedXmlFileItem.
"""
return self._expander.expand(node=self._node)
def __repr__(self):
extra=''
if self.atts is not None:
extra += ', atts=%s' % repr(self.atts)
if self.data is not None:
extra += ', data=%s' % repr(self.data)
return 'ParsedXmlFileItem(ParsedXmlItem.%s, %s%s)' % (
self.typenames[self.type],
repr(self.nodeNames),
extra
)
class ParsedXmlFile(ParsedXml):
"""Class representing a parsed XML file.
The file is actually read and parsed lazily, but this implementation is
hidden, and the interface provided is precisely that of ParsedXml.
"""
def __init__(self, fh):
ParsedXml.__init__(self, None)
# File handle that file is being read from.
# Used if reading from a file.
self._fh = None
# Position in file handle that XML starts at.
# Used if reading from a file.
self._startpos = None
# If we've been supplied a filename instead of a file handle, try
# opening it.
if isinstance(fh, basestring):
try:
handle = open(fh)
except IOError, e:
raise Errors.UserError("Can't open file %s : %s", fh, str(e))
fh = handle
# Store the file handle and current position, for use when we start
# reading the file.
if fh is not None:
self._fh = fh
self._startpos = fh.tell()
def _getParseEvents(self):
"""Parse from a file handle.
This uses the pulldom interfsce to avoid having to read in the whole
file at once. It returns a DOMEventStream object, which provides a
stream of parse events.
"""
if self._fh.tell() != self._startpos:
self._fh.seek(self._startpos)
result = []
def callable():
result.append(xml.dom.pulldom.parse(self._fh))
_convertParseExceptions(callable)
return result[0]
def getAsString(self):
"""Get the parsed piece of XML as a utf-8 string.
"""
events = self._getParseEvents()
result = []
def callable():
for (event, node) in events:
if event == "START_ELEMENT":
events.expandNode(node)
result.append(node.toxml())
_convertParseExceptions(callable)
return ''.join(result)
def getContentsAsString(self):
"""Get the contents of the parsed piece of XML.
This returns the contents as a utf-8 string.
This includes the contents of the root tag, but not the root tag
itself.
"""
events = self._getParseEvents()
result = []
def callable():
for (event, node) in events:
if event == "START_ELEMENT":
break
for (event, node) in events:
if event == "START_ELEMENT":
events.expandNode(node)
result.append(node.toxml())
if event == "END_ELEMENT":
break
_convertParseExceptions(callable)
return ''.join(result)
def getItems(self):
"""
Return an iterator which returns all the items in the parsed XML.
"""
class Iter:
def __init__(self, events, unlinker):
self._events = events
self._unlinker = unlinker
self._nodeNames = []
self._lastEvent = None
self._lastNode = None
self._nextItem = None
self._expandedIter = None
self._expandedIterStarted = False
self._expandedXml = None
def callable():
while True:
self._nextItem = self._events.next()
if self._nextItem[0] == 'START_ELEMENT':
break
try:
_convertParseExceptions(callable)
except StopIteration:
self._events = None
def __iter__(self):
'Method needed to satisfy iterator protocol.'
return self
def next(self):
'Move to next element, or throw StopIteration.'
# If we've got an expanded iterator, pass through items from
# the iterator over the expanded node, but add the preceding
# nodenames to it.
if self._expandedIter is not None:
try:
item = self._expandedIter.next()
self._expandedIterStarted = True
newNodeNames = []
newNodeNames.extend(self._nodeNames[:-1])
newNodeNames.extend(item.nodeNames)
item.nodeNames = newNodeNames
return item
except StopIteration:
self._expandedIter = None
self._expandedXml = None
self._expandedIterStarted = False
self._nodeNames.pop()
# Read events from the file, merging any character events, and
# return ParsedXmlFileItems for each one.
while True:
# If we haven't already read ahead by one, read the next
# event.
if self._nextItem is None:
if self._events is None:
raise StopIteration
def callable():
self._nextItem = self._events.next()
try:
_convertParseExceptions(callable)
except StopIteration:
self._events = None
raise
(self._lastEvent, self._lastNode) = self._nextItem
self._nextItem = None
if self._lastEvent is None:
raise StopIteration
# Now return a node based on self._lastEvent and self._lastNode
if self._lastEvent == 'START_ELEMENT':
# Return start of node
self._nodeNames.append(self._lastNode.nodeName)
return ParsedXmlFileItem(ParsedXmlFileItem.START, self._nodeNames, atts=self._lastNode.attributes, node=self._lastNode, unlinker=self._unlinker, expander=self)
elif self._lastEvent == 'CHARACTERS':
# Text data in the node.
# Move forward merging CHARACTERS nodes together, until
# we have a different type of node.
characters = [self._lastNode.data]
def callable():
while self._nextItem is None:
self._nextItem = self._events.next()
if self._nextItem[0] == 'CHARACTERS':
characters.append(self._nextItem[1].data)
self._nextItem = None
try:
_convertParseExceptions(callable)
except StopIteration:
self._nextItem = None
self._events = None
return ParsedXmlFileItem(ParsedXmlFileItem.DATA, self._nodeNames, data=''.join(characters))
elif self._lastEvent == 'END_ELEMENT':
# End of a node.
result = ParsedXmlFileItem(ParsedXmlFileItem.END, copy.copy(self._nodeNames), atts=self._lastNode.attributes)
self._nodeNames.pop()
return result
else:
# Something else: ignore it, go round the loop again.
pass
def expand(self, node=None):
"""
Expand the current item (and its subitems) by returning a
ParsedXml object representing the current item.
Only valid when the current item (ie, last returned by next())
is a START item. See also the skipContents() method, which is
often useful in conjunction with this method.
If node is supplied, will raise an error if the supplied node
is not the last node supplied.
"""
if self._expandedIter is not None:
if self._expandedIterStarted:
return self._expandedIter.expand()
else:
return self._expandedXml
assert node is None or node is self._lastNode
assert self._lastEvent == 'START_ELEMENT', 'Cannot expand() when current item is not a START item'
def callable():
self._events.expandNode(self._lastNode)
_convertParseExceptions(callable)
self._expandedXml = ParsedXml()
self._expandedXml._node = self._lastNode
self._expandedXml._unlinker = self._unlinker
self._expandedIter = self._expandedXml.getItems()
self._expandedIterStarted = False
try:
self._expandedIter.next()
except StopIteration:
self._expandedIter = None
self._expandedXml = None
return self._expandedXml
def skipContents(self):
"""
If the current item is a START item, advances the iterator such
that the next item is the corresponding END item. Otherwise,
has no effect.
"""
if self._lastEvent != 'START_ELEMENT':
return
if self._expandedXml:
self._expandedIter.skipContents()
return
def callable():
nodeNames = [self._lastNode.nodeName]
while len(nodeNames) != 0:
if self._nextItem is not None:
(self._lastEvent, self._lastNode) = self._nextItem
self._nextItem = self._events.next()
print self._nextItem, nodeNames
(event, node) = self._nextItem
if event == 'START_ELEMENT':
nodeNames.append(node.nodeName)
elif event == 'END_ELEMENT':
assert nodeNames[-1] == node.nodeName
nodeNames.pop()
try:
_convertParseExceptions(callable)
except StopIteration:
self._nextItem = None
return Iter(self._getParseEvents(), self)
__test__ = {
'Getting items': r"""
Get some items, and check that all the subitems expand correctly.
>>> parsed=ParsedXml('A ')
>>> for item in parsed.getItems():
... print "Item:", item
... if item.type == item.START:
... subparsed = item.expand()
... for item2 in subparsed.getItems():
... print "Item2:", item2
Item: (START, [u'b'], a='' c='' b='')
Item2: (START, [u'b'], a='' c='' b='')
Item2: (START, [u'b', u'a'])
Item2: (DATA, [u'b', u'a'], data=u'A')
Item2: (END, [u'b', u'a'])
Item2: (END, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item2: (START, [u'a'])
Item2: (DATA, [u'a'], data=u'A')
Item2: (END, [u'a'])
Item: (DATA, [u'b', u'a'], data=u'A')
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Get some items, and check that all the subitems expand correctly.
>>> parsed=ParsedXml('A ')
>>> it = parsed.getItems()
>>> for item in it:
... print "Item:", item
... if item.type == item.START and item.nodeNames[-1] == 'a':
... it.skipContents()
... subparsed = item.expand()
... it.skipContents()
... for item2 in subparsed.getItems():
... print "Item2:", item2
Item: (START, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item2: (START, [u'a'])
Item2: (DATA, [u'a'], data=u'A')
Item2: (END, [u'a'])
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Check that iterator now raises StopIteration
>>> it.next()
Traceback (most recent call last):
...
StopIteration
First, just parse some simple XML and check that the element list is right.
>>> parsed=ParsedXml('Normal italic italicbold normalagain mix ed. ')
>>> for item in parsed.getItems(): print item
(START, [u'field'], name='title')
(DATA, [u'field'], data=u'Normal ')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'italic ')
(START, [u'field', u'i', u'b'])
(DATA, [u'field', u'i', u'b'], data=u'italicbold')
(END, [u'field', u'i', u'b'])
(END, [u'field', u'i'])
(DATA, [u'field'], data=u' normalagain mi')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'x')
(END, [u'field', u'i'])
(DATA, [u'field'], data=u'ed.')
(END, [u'field'], name='title')
Next, parse some XML with an SGML comment. Should get exactly the same output.
>>> parsed=ParsedXml('Normal italic italicbold normalagain mix ed. ')
>>> for item in parsed.getItems(): print item
(START, [u'field'], name='title')
(DATA, [u'field'], data=u'Normal ')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'italic ')
(START, [u'field', u'i', u'b'])
(DATA, [u'field', u'i', u'b'], data=u'italicbold')
(END, [u'field', u'i', u'b'])
(END, [u'field', u'i'])
(DATA, [u'field'], data=u' normalagain mi')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'x')
(END, [u'field', u'i'])
(DATA, [u'field'], data=u'ed.')
(END, [u'field'], name='title')
Now, convert some XML to text.
>>> parsed=ParsedXml('Normal italic italicbold normalagain mix ed. ')
>>> print parsed.getText(nospacetags=['field', 'i', 'b'])
Normal italic italicbold normalagain mixed.
>>> for item in parsed.getItems():
... if item.type == item.START and item.nodeNames[-1] == 'i':
... print item.expand().getText(nospacetags=['i', 'b'])
italic italicbold
x
Check if parameters supplied to the getText() method work.
>>> for item in parsed.getItems():
... if item.type == item.START and item.nodeNames[-1] == 'i':
... print item.expand().getText(spacetags=['b'], nospacetags=['i'])
italic italicbold
x
>>> parsed=ParsedXml('C1 B1C2 A1B2 C3 A2 ')
>>> for item in parsed.getItems():
... if item.type == item.START:
... expanded = item.expand()
... print expanded.getAsString()
... print expanded.getContentsAsString()
... print item.expand().getText(nospacetags=['b', 'a'])
... print item.expand().getText(nospacetags=['b', 'a'], spacetags=['c'])
... print item.expand().getText(spacetags=['b'])
... print item.expand().getText(nospacetags=['a'], ignoretags=['c'])
... print item.expand().getText(ignoretags=['b'])
... print '.' #doctest: +REPORT_NDIFF
C1 B1C2 A1B2 C3 A2
C1 B1C2 A1B2 C3 A2
C1 B1 C2 A1B2 C3 A2
C1 B1 C2 A1B2 C3 A2
C1 B1 C2 A1 B2 C3 A2
B1 A1 B2 A2
A1 C3 A2
.
C1 B1C2
C1 B1C2
C1 B1 C2
C1 B1 C2
C1 B1 C2
B1
.
C1
C1
C1
C1
C1
C1
.
C2
C2
C2
C2
C2
C2
.
B2
B2
B2
B2
B2
B2
.
C3
C3
C3
C3
C3
C3
.
""",
'Getting items from file': r"""
Get some items, and check that all the subitems expand correctly.
>>> import StringIO
>>> iostring = StringIO.StringIO('A ')
>>> parsed=ParsedXmlFile(iostring)
>>> for item in parsed.getItems():
... print "Item:", item
... if item.type == item.START:
... subparsed = item.expand()
... for item2 in subparsed.getItems():
... print "Item2:", item2 #doctest: +REPORT_NDIFF
Item: (START, [u'b'], a='' c='' b='')
Item2: (START, [u'b'], a='' c='' b='')
Item2: (START, [u'b', u'a'])
Item2: (DATA, [u'b', u'a'], data=u'A')
Item2: (END, [u'b', u'a'])
Item2: (END, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item2: (START, [u'a'])
Item2: (DATA, [u'a'], data=u'A')
Item2: (END, [u'a'])
Item: (DATA, [u'b', u'a'], data=u'A')
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
""",
'Get items from file and check expand': r"""
Get some items, and check that all the subitems expand correctly.
>>> import StringIO
>>> parsed=ParsedXmlFile(StringIO.StringIO('A '))
>>> it = parsed.getItems()
>>> for item in it:
... print "Item:", item
... if item.type == item.START and item.nodeNames[-1] == 'a':
... subparsed = item.expand()
... it.skipContents()
... it.skipContents()
... for item2 in subparsed.getItems():
... print "Item2:", item2 #doctest: +REPORT_NDIFF
Item: (START, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item2: (START, [u'a'])
Item2: (DATA, [u'a'], data=u'A')
Item2: (END, [u'a'])
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Check that iterator now raises StopIteration
>>> it.next()
Traceback (most recent call last):
...
StopIteration
Check that if skipContents() is not used, the results are the same whether
expand is called or not.
>>> it = parsed.getItems()
>>> for item in it:
... print "Item:", item
... if item.type == item.START and item.nodeNames[-1] == 'a':
... subparsed = item.expand()
... for item2 in subparsed.getItems():
... print "Item2:", item2 #doctest: +REPORT_NDIFF
Item: (START, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item2: (START, [u'a'])
Item2: (DATA, [u'a'], data=u'A')
Item2: (END, [u'a'])
Item: (DATA, [u'b', u'a'], data=u'A')
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Check that iterator now raises StopIteration
>>> it.next()
Traceback (most recent call last):
...
StopIteration
>>> it = parsed.getItems()
>>> for item in it:
... print "Item:", item
... if item.type == item.START and item.nodeNames[-1] == 'a':
... subparsed = item.expand() #doctest: +REPORT_NDIFF
Item: (START, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item: (DATA, [u'b', u'a'], data=u'A')
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Check that iterator now raises StopIteration
>>> it.next()
Traceback (most recent call last):
...
StopIteration
>>> it = parsed.getItems()
>>> for item in it:
... print "Item:", item #doctest: +REPORT_NDIFF
Item: (START, [u'b'], a='' c='' b='')
Item: (START, [u'b', u'a'])
Item: (DATA, [u'b', u'a'], data=u'A')
Item: (END, [u'b', u'a'])
Item: (END, [u'b'], a='' c='' b='')
Check that iterator now raises StopIteration
>>> it.next()
Traceback (most recent call last):
...
StopIteration
""",
'Parse XML from file': r"""
First, just parse some simple XML and check that the element list is right.
>>> import StringIO
>>> parsed=ParsedXmlFile(StringIO.StringIO('Normal italic italicbold normalagain mix ed. '))
>>> for item in parsed.getItems(): print item #doctest: +REPORT_NDIFF
(START, [u'field'], name='title')
(DATA, [u'field'], data=u'Normal ')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'italic ')
(START, [u'field', u'i', u'b'])
(DATA, [u'field', u'i', u'b'], data=u'italicbold')
(END, [u'field', u'i', u'b'])
(END, [u'field', u'i'])
(DATA, [u'field'], data=u' normalagain mi')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'x')
(END, [u'field', u'i'])
(DATA, [u'field'], data=u'ed.')
(END, [u'field'], name='title')
""",
'Parse XML with SGML comment from file': r"""
Next, parse some XML with an SGML comment. Should get exactly the same output.
>>> import StringIO
>>> parsed=ParsedXmlFile(StringIO.StringIO('Normal italic italicbold normalagain mix ed. '))
>>> for item in parsed.getItems(): print item #doctest: +REPORT_NDIFF
(START, [u'field'], name='title')
(DATA, [u'field'], data=u'Normal ')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'italic ')
(START, [u'field', u'i', u'b'])
(DATA, [u'field', u'i', u'b'], data=u'italicbold')
(END, [u'field', u'i', u'b'])
(END, [u'field', u'i'])
(DATA, [u'field'], data=u' normalagain mi')
(START, [u'field', u'i'])
(DATA, [u'field', u'i'], data=u'x')
(END, [u'field', u'i'])
(DATA, [u'field'], data=u'ed.')
(END, [u'field'], name='title')
""",
'Parse XML from file and convert to text': r"""
Now, convert some XML to text.
>>> import StringIO
>>> parsed=ParsedXmlFile(StringIO.StringIO('Normal italic italicbold normalagain mix ed. '))
>>> print parsed.getText(nospacetags=['field', 'i', 'b'])
Normal italic italicbold normalagain mixed.
>>> for item in parsed.getItems():
... if item.type == item.START and item.nodeNames[-1] == 'i':
... print item.expand().getText(nospacetags=['i', 'b'])
italic italicbold
x
Check if parameters supplied to the getText() method work.
>>> for item in parsed.getItems():
... if item.type == item.START and item.nodeNames[-1] == 'i':
... print item.expand().getText(spacetags=['b'], nospacetags=['i'])
italic italicbold
x
>>> parsed=ParsedXmlFile(StringIO.StringIO('C1 B1C2 A1B2 C3 A2 '))
>>> for item in parsed.getItems():
... if item.type == item.START:
... expanded = item.expand()
... print expanded.getAsString()
... print expanded.getContentsAsString()
... print item.expand().getText(nospacetags=['b', 'a'])
... print item.expand().getText(nospacetags=['b', 'a'], spacetags=['c'])
... print item.expand().getText(spacetags=['b'])
... print item.expand().getText(nospacetags=['a'], ignoretags=['c'])
... print item.expand().getText(ignoretags=['b'])
... print '.' #doctest: +REPORT_NDIFF
C1 B1C2 A1B2 C3 A2
C1 B1C2 A1B2 C3 A2
C1 B1 C2 A1B2 C3 A2
C1 B1 C2 A1B2 C3 A2
C1 B1 C2 A1 B2 C3 A2
B1 A1 B2 A2
A1 C3 A2
.
C1 B1C2
C1 B1C2
C1 B1 C2
C1 B1 C2
C1 B1 C2
B1
.
C1
C1
C1
C1
C1
C1
.
C2
C2
C2
C2
C2
C2
.
B2
B2
B2
B2
B2
B2
.
C3
C3
C3
C3
C3
C3
.
"""
}
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/perftest/parse_wikipedia/wiki2dump.py 0000755 0001750 0001750 00000015060 10667526240 021627 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2006 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""wiki2dump.py: Convert wikimedia xml dump files to scriptindex input files.
Usage:
./wiki2dump.py
Outputs result to standard output.
"""
import sys
import os.path
from XMLUtils import ParsedXmlFile
from Errors import UserError
import re
class PageRevision:
"""A revision of a wikimedia page.
This has an id number, timestamp, contributor_name, contributor_id, minor
edit flag, comment, and text.
"""
_re_redirect = re.compile('#REDIRECT\s*\[\[(?P.*?)\]\]',
re.IGNORECASE)
def __init__(self, xml):
self.id = None
self.timestamp = None
self.contributor_name = ''
self.contributor_id = None
self.minor = False
self.comment = ''
self.text = ''
self.redirect = None
it = xml.getItems()
for item in it:
if item.type == item.DATA:
if item.nodeNames[-2:] == [u'contributor', u'username']:
self.contributor_name = item.data
elif item.nodeNames[-2:] == [u'contributor', u'id']:
self.contributor_id = item.data # FIXME - convert (checked) to int
elif item.nodeNames[-1] == u'id':
self.id = item.data # FIXME - convert (checked) to int
if item.nodeNames[-1] == u'timestamp':
self.timestamp = item.data # FIXME - convert (checked) to datetime
if item.nodeNames[-1] == u'comment':
self.comment = item.data
if item.nodeNames[-1] == u'text':
self.text = item.data
elif item.type == item.START:
if item.nodeNames[-1] == u'minor':
self.minor = True
if len(self.text) > 0 and self.text[0] == '#':
# Deal with special directives
g = self._re_redirect.match(self.text)
if g:
self.redirect = g.group('target')
def __repr__(self):
return '' % (
self.id, self.timestamp, self.contributor_name,
self.contributor_id, self.minor, self.comment, self.text,
self.redirect,
)
class Page:
"""A wikimedia page.
This corresponds to a page tag in the input XML file. It has a title, id
number, and a list of PageRevision objects (which will often contain only a
single entry).
"""
def __init__(self, xml):
self.title = None
self.id = None
self.revisions = []
it = xml.getItems()
for item in it:
if item.type == item.START:
if item.nodeNames[-1] == 'revision':
self.revisions.append(PageRevision(item.expand()))
it.skipContents()
elif item.type == item.DATA:
if item.nodeNames[-1] == 'title':
self.title = item.data
elif item.nodeNames[-1] == 'id':
self.id = item.data # FIXME - convert (checked) to int
def dump(self):
redirect = False
result = []
if self.title is not None:
result.append("title=%s" % self.title)
if self.id is not None:
result.append("id=%s" % self.id)
maxrev = None
for revision in self.revisions:
if maxrev is None or maxrev.timestamp < revision.timestamp:
maxrev = revision
if maxrev is not None:
if maxrev.redirect is not None:
result.append("redirect=%s" % maxrev.redirect)
redirect = True
elif len(maxrev.text) > 0:
text = maxrev.text.replace('\n', '\n=')
result.append("text=%s" % text)
return (u'\n'.join(result), redirect)
def parse(infile, outfile, redirfile):
infile_size = os.path.getsize(infile)
infh = open(infile, "rb")
if os.path.exists(outfile):
raise UserError("Error: output file \"%s\" already exists.", outfile)
if os.path.exists(redirfile):
raise UserError("Error: redirections output file \"%s\" already exists.", redirfile)
outfh = open(outfile, "wb")
redirfh = open(redirfile, "wb")
xml = ParsedXmlFile(infh)
state = 0
it = xml.getItems()
for item in it:
if state == 0:
if item.type != item.START:
raise UserError('Didn\'t get correct header at start of file')
else:
state = 1
continue
if state == 1:
if item.type == item.START:
if item.nodeNames[-1] == u'page':
page = Page(item.expand())
(dump, redirect) = page.dump()
if redirect:
redirfh.write(dump.encode('utf-8'))
redirfh.write('\n\n')
else:
outfh.write(dump.encode('utf-8'))
outfh.write('\n\n')
it.skipContents()
pos = infh.tell()
percent = 100.0 * pos / infile_size
if redirect:
print "Processed %f%%: %r (redirect to %r)" % (percent, page.title, redirect)
else:
print "Processed %f%%: %r" % (percent, page.title)
infh.close()
outfh.close()
redirfh.close()
# Start
if len(sys.argv) != 4:
print """
Usage: ./wiki2dump.py
""".strip()
sys.exit(0)
infile = sys.argv[1]
outfile = sys.argv[2]
redirfile = sys.argv[3]
try:
parse(infile, outfile, redirfile)
except UserError, e:
print e
xappy-0.5/perftest/analyse_indexlogs.py 0000644 0001750 0001750 00000020427 10702531177 020257 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import csv
import pylab
import sys
def get_av_docspersec(times, interval, docscale):
docspersec = []
docs = []
for i in xrange(interval, len(times)):
docinterval = times[i].docs - times[i-interval].docs
timeinterval = times[i].time - times[i-interval].time
docspersec.append(docinterval / timeinterval)
docs.append(times[i].docs / docscale)
if interval >= len(times):
return docspersec, docs, 0
else:
return docspersec, docs, times[interval].docs - times[0].docs
def calc_docscale(times):
docscale = 1000
if len(times) > 2:
docdiff = times[1].docs - times[0].docs
while docscale > 1 and docdiff <= docscale:
docscale //= 10
if docscale == 1:
docscalestr = ""
else:
docscalestr = " (x%d)" % docscale
return docscale, docscalestr
def generate_figures(times, outprefix, pretitle):
docscale, docscalestr = calc_docscale(times)
# Generate a "total time" versus "total documents" plot
if len(times) > 1:
pylab.figure()
total_times = [row.time / 3600.0 for row in times]
total_documents = [row.docs / docscale for row in times]
pylab.plot(total_times, total_documents)
pylab.xlabel('Time (hours)')
pylab.ylabel('Documents%s' % docscalestr)
pylab.title(pretitle + r': documents indexed after a given time')
pylab.axis([0, max(total_times) * 1.05, 0, max(total_documents) * 1.05])
pylab.savefig(outprefix + "totaltime_v_totaldocs.png", format="png")
# Generate a "documents/second" plot
docspersec_av1, docs_av1, docinterval = get_av_docspersec(times, 1, docscale)
if len(docs_av1) > 1:
pylab.figure()
pylab.plot(docs_av1, docspersec_av1)
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, max(docs_av1) * 1.05, 0, max(docspersec_av1) * 1.05])
pylab.savefig(outprefix + "docspersec_v_totaldocs_av1.png", format="png")
docspersec_av10, docs_av10, docinterval = get_av_docspersec(times, 10, docscale)
if len(docs_av10) > 1:
pylab.figure()
pylab.plot(docs_av10, docspersec_av10)
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, max(docs_av10) * 1.05, 0, max(docspersec_av10) * 1.05])
pylab.savefig(outprefix + "docspersec_v_totaldocs_av10.png", format="png")
docspersec_av100, docs_av100, docinterval = get_av_docspersec(times, 100, docscale)
if len(docs_av100) > 1:
pylab.figure()
pylab.plot(docs_av100, docspersec_av100)
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, max(docs_av100) * 1.05, 0, max(docspersec_av100) * 1.05])
pylab.savefig(outprefix + "docspersec_v_totaldocs_av100.png", format="png")
def generate_comparison_figures(alltimes, outprefix, pretitle):
docscale, docscalestr = calc_docscale(alltimes[0][1])
# Generate a "total time" versus "total documents" plot
have_plotted = False
xaxis = 0
yaxis = 0
for legend, times in alltimes:
if len(times) > 1:
if not have_plotted:
pylab.figure()
have_plotted = True
total_times = [row.time / 3600.0 for row in times]
total_documents = [row.docs / docscale for row in times]
pylab.plot(total_times, total_documents, label=legend)
xaxis = max(xaxis, max(total_times) * 1.05)
yaxis = max(yaxis, max(total_documents) * 1.05)
pylab.legend(loc="lower right")
pylab.xlabel('Time (hours)')
pylab.ylabel('Documents%s' % docscalestr)
pylab.title(pretitle + r': documents indexed after a given time')
pylab.axis([0, xaxis, 0, yaxis])
if have_plotted:
pylab.savefig(outprefix + "totaltime_v_totaldocs.png", format="png")
# Generate a "documents/second" plot
have_plotted = False
xaxis = 0
yaxis = 0
for legend, times in alltimes:
docspersec_av1, docs_av1, docinterval = get_av_docspersec(times, 1, docscale)
if len(docs_av1) > 1:
if not have_plotted:
pylab.figure()
have_plotted = True
pylab.plot(docs_av1, docspersec_av1, label=legend)
xaxis = max(xaxis, max(docs_av1) * 1.05)
yaxis = max(yaxis, max(docspersec_av1) * 1.05)
pylab.legend(loc="lower left")
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, xaxis, 0, yaxis])
if have_plotted:
pylab.savefig(outprefix + "docspersec_v_totaldocs_av1.png", format="png")
have_plotted = False
xaxis = 0
yaxis = 0
for legend, times in alltimes:
docspersec_av10, docs_av10, docinterval = get_av_docspersec(times, 10, docscale)
if len(docs_av10) > 1:
if not have_plotted:
pylab.figure()
have_plotted = True
pylab.plot(docs_av10, docspersec_av10, label=legend)
xaxis = max(xaxis, max(docs_av10) * 1.05)
yaxis = max(yaxis, max(docspersec_av10) * 1.05)
pylab.legend(loc="lower left")
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, xaxis, 0, yaxis])
if have_plotted:
pylab.savefig(outprefix + "docspersec_v_totaldocs_av10.png", format="png")
have_plotted = False
xaxis = 0
yaxis = 0
for legend, times in alltimes:
docspersec_av100, docs_av100, docinterval = get_av_docspersec(times, 100, docscale)
if len(docs_av100) > 1:
if not have_plotted:
pylab.figure()
have_plotted = True
pylab.plot(docs_av100, docspersec_av100, label=legend)
xaxis = max(xaxis, max(docs_av100) * 1.05)
yaxis = max(yaxis, max(docspersec_av100) * 1.05)
pylab.legend(loc="lower left")
pylab.xlabel('Documents%s' % docscalestr)
pylab.ylabel('Docs per second')
pylab.title(pretitle + ': indexing rate versus documents processed\nAveraged every %d documents' % docinterval)
pylab.axis([0, xaxis, 0, yaxis])
if have_plotted:
pylab.savefig(outprefix + "docspersec_v_totaldocs_av100.png", format="png")
class logrow(object):
__slots__ = ('docs', 'time', 'dbsize', 'tablesizes')
def __init__(self, docs, time, dbsize, *tablesizes):
self.docs = int(docs)
self.time = float(time)
self.dbsize = int(dbsize)
self.tablesizes = [int(tablesize) for tablesize in tablesizes]
def parse_logfile(filename):
fd = open(filename)
times = []
reader = csv.reader(fd)
descline = reader.next()
headings = reader.next()
assert(','.join(headings) == 'Documents Added,Time(seconds),dbsize(bytes),inputsize(bytes)')
for row in reader:
newrow = logrow(*row)
if len(times) > 0 and times[-1].docs == newrow.docs:
times[-1] = newrow
else:
times.append(newrow)
return descline, times
xappy-0.5/perftest/analyse_searchlogs.py 0000755 0001750 0001750 00000005216 10702541535 020416 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import csv
import pylab
def get_stats(log):
query_v_time = [(row.time, row.query) for row in log]
query_v_time.sort()
query_v_time.reverse()
print "Average speed: %f seconds" % (sum((row.time for row in log)) / len(log))
print "Slowest queries:"
for time, query in query_v_time[:10]:
print "%s: %f seconds" % (query, time)
def generate_figures(log, outprefix, pretitle):
# Generate a "total time" versus "total documents" plot
total_times = [row.tottime for row in log]
query_times = [row.time for row in log]
pylab.figure(figsize=(8,12))
pylab.subplot(311)
pylab.plot(total_times)
pylab.xlabel('Queries completed')
pylab.ylabel('Total time (seconds)')
pylab.title(pretitle + '\nQueries completed after given time')
pylab.subplot(312)
pylab.axis([0, len(query_times), 0, max(query_times) * 1.05])
pylab.plot(query_times)
pylab.xlabel('Queries completed')
pylab.ylabel('Query time (seconds)')
pylab.title('Query times')
pylab.subplot(313)
pylab.axis([0, len(query_times), 0, 50])
pylab.hist(query_times, 50, log="true")
pylab.xlabel('Query time (seconds)')
pylab.ylabel('Queries')
pylab.title('Query time histogram')
pylab.savefig(outprefix + "query_times.png", format="png")
class logrow(object):
__slots__ = ('querynum', 'estmatches', 'time', 'tottime')
def __init__(self, threadnum, querynum, matchcount, estmatches, time, tottime, querylen, *query):
self.querynum = int(querynum)
self.estmatches = int(estmatches)
self.time = float(time)
self.tottime = float(tottime)
def parse_logfile(filename):
fd = open(filename)
times = []
titles = None
reader = csv.reader(fd)
for row in reader:
if titles is None:
titles = row
else:
newrow = logrow(*row)
times.append(newrow)
return times
xappy-0.5/perftest/gen_queries.py 0000755 0001750 0001750 00000004442 10667526240 017064 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import random
from sets import Set
# Remove this line, or change to a different value, to get different output.
random.seed(1)
class WordSource:
def __init__(self, infile):
fd = open(infile, "r")
words = Set()
for line in fd.readlines():
line = line.replace('"', ' ')
for word in line.split():
words.add(word)
self.words = []
for word in words:
self.words.append(word)
def next(self):
return random.choice(self.words)
class QueryGenerator:
def __init__(self, source, distribution):
self.source = source
self.distribution = []
for key, val in distribution.iteritems():
self.distribution.extend((key,) * val)
def __iter__(self):
return self
def next(self):
qlen = random.choice(self.distribution)
qterms = []
while qlen > 0:
qterms.append(self.source.next())
qlen -= 1
return ' '.join(qterms)
def gen_queries(infile, outfile, limit, distribution):
querygen = QueryGenerator(WordSource(infile), distribution)
outfd = open(outfile, 'wb')
count = 0
for query in querygen:
query = query.replace('\n', ' ')
outfd.write(query + '\n')
count += 1
if count >= limit:
break
outfd.close()
if __name__ == '__main__':
infile = '../testdata/query_sourcewords.txt'
outfile = '../testdata/queries.txt'
limit = 100000
gen_queries(infile, outfile, limit, {1: 10, 2:3, 5:1})
xappy-0.5/perftest/indexer.py 0000755 0001750 0001750 00000011657 10702544277 016222 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import csv
import os
import sys
import time
import xappy
class CsvLogger(object):
def __init__(self, filepath):
self.fd = open(filepath, 'ab')
self.csvwriter = csv.writer(self.fd)
def log(self, *args):
self.csvwriter.writerow(args)
self.fd.flush()
def create_index(dbpath):
"""Create a new index, and set up its field structure.
"""
iconn = xappy.IndexerConnection(dbpath)
iconn.add_field_action('title', xappy.FieldActions.STORE_CONTENT)
iconn.add_field_action('title', xappy.FieldActions.INDEX_FREETEXT,
language="en", weight=5)
iconn.add_field_action('text', xappy.FieldActions.STORE_CONTENT)
iconn.add_field_action('text', xappy.FieldActions.INDEX_FREETEXT,
language='en')
iconn.add_field_action('doclen', xappy.FieldActions.STORE_CONTENT)
iconn.add_field_action('doclen', xappy.FieldActions.SORTABLE, type='float')
iconn.add_field_action('doclen', xappy.FieldActions.COLLAPSE)
iconn.close()
def open_index(dbpath):
"""Open an existing index.
"""
return xappy.IndexerConnection(dbpath)
def dirsize(dirname):
size = 0
for dirpath, dirnames, filenames in os.walk(dirname):
for filename in filenames:
size += os.stat(os.path.join(dirpath, filename)).st_size
return size
def log_entry(logger, dbpath, addcount, starttime, inputsize):
currtime = time.time()
dbsize = dirsize(dbpath)
logger.log(addcount, currtime - starttime, dbsize, inputsize)
def index_scriptindex_file(iconn, dbpath, dumpfd, logger, flushspeed, maxdocs,
logspeed):
"""Index a xapian "scriptindex" format file.
"""
logger.log("Documents Added", "Time(seconds)", "dbsize(bytes)", "inputsize(bytes)")
starttime = time.time()
linenum = 0
addcount = 0
doc = xappy.UnprocessedDocument()
doclen = 0
inputsize = 0
fieldlen = 0
while maxdocs is None or addcount < maxdocs:
line = dumpfd.readline()
linenum += 1
if len(line) == 0:
break
inputsize += len(line)
line = line.rstrip('\n\r')
if len(line) == 0:
if len(doc.fields) != 0:
doc.fields.append(xappy.Field('doclen', doclen))
iconn.add(doc)
addcount += 1
if flushspeed is not None and (addcount % flushspeed) == 0:
iconn.flush()
if addcount % logspeed == 0:
log_entry(logger, dbpath, addcount, starttime, inputsize)
doc = xappy.UnprocessedDocument()
continue
if line[0] == '#':
continue
equals = line.find("=")
if equals == -1:
raise ValueErrror("Missing '=' in line %d" % linenum)
elif equals == 0:
if len(doc.fields) == 0:
raise ValueError("Continuation line %d is first in document" % linenum)
else:
doc.fields[-1].value += '\n' + line[1:]
if doc.fields[-1].name == 'text':
doclen = len(doc.fields[-1].value)
else:
doc.fields.append(xappy.Field(line[:equals], line[equals + 1:]))
if doc.fields[-1].name == 'id':
doc.id = doc.fields[-1].value
elif doc.fields[-1].name == 'text':
doclen = len(doc.fields[-1].value)
# Add any left-over documents
if len(doc.fields) != 0:
doc.fields.append(xappy.Field('doclen', doclen))
iconn.add(doc)
addcount += 1
iconn.flush()
log_entry(logger, dbpath, addcount, starttime, inputsize)
def index_file(inputfile, dbpath, logpath, flushspeed, description, maxdocs, logspeed):
create_index(dbpath)
iconn = open_index(dbpath)
dumpfd = open(inputfile)
logger = CsvLogger(logpath)
descline = [description, "flushspeed=%d" % flushspeed]
if maxdocs is not None:
descline.append("maxdocs=%d" % maxdocs)
if logspeed is not None:
descline.append("logspeed=%d" % logspeed)
logger.log(*descline)
index_scriptindex_file(iconn, dbpath, dumpfd, logger, flushspeed, maxdocs,
logspeed)
xappy-0.5/perftest/parseargs.py 0000755 0001750 0001750 00000002736 10677232134 016546 0 ustar richard richard #!/usr/bin/env python
"""Parse command line arguments.
"""
import getopt
import sys
class Config(object):
def __init__(self, **kwargs):
for key, val in kwargs.iteritems():
setattr(self, key, val)
def usage(exitval):
print("Usage: perftest.py [options]")
print("Options are:")
print(" --help: Get help message")
print(" --outdir: Set output directory")
print(" --tmpdir: Set temporary directory")
print(" --preserve: Preserve existing runs")
sys.exit(exitval)
def parse_argv(argv, **defaults):
config = Config(**defaults)
try:
optlist, argv = getopt.gnu_getopt(argv, 'ho:t:p',
('help', 'outdir=', 'tmpdir=', 'preserve', 'searchruns='))
for (opt, val) in optlist:
if opt == '-h' or opt == '--help':
usage(0)
elif opt == '-o' or opt == '--outdir':
config.outdir = val
elif opt == '-t' or opt == '--tmpdir':
config.tmpdir = val
elif opt == '-p' or opt == '--preserve':
config.preserve = True
elif opt == '--searchruns':
config.searchruns = int(val)
else:
print("Unknown option %r" % opt)
usage(1)
except getopt.GetoptError, e:
print("Bad options: %r" % str(e))
usage(1)
if len(argv) != 1:
print("Wrong number of arguments")
usage(1)
return config
xappy-0.5/perftest/perftest.py 0000755 0001750 0001750 00000033325 10703210275 016401 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""perftest.py: Perform automated performance tests.
This script performs automated performance tests of the Xappy module.
First, it downloads sample data to use for the performance tests, if such data
isn't already downloaded.
Next, it performs some timed indexing runs, producing CSV log files and graphs
of the performance of these runs.
Next, it performs some timed search runs, producing CSV log files and graphs
of the performance of these runs.
FIXME - needs to have support for clearing the cache between runs (but also do
some hot-cache runs):
To clear the cache:
1. If /proc/sys/vm/drop_caches exists, and is writable, writing "1" to it
clears the cache.
2. Otherwise, creates a large file containing random data, read all the
data from it, and then delete it.
"""
import getopt
import os
import os.path
import shutil
import sys
import time
import urllib
import setuppaths
import indexer
import searcher
try:
import analyse_indexlogs
import analyse_searchlogs
except ImportError:
analyse_indexlogs = None
analyse_searchlogs = None
class Config(object):
def __init__(self, **kwargs):
for key, val in kwargs.iteritems():
setattr(self, key, val)
def usage(exitval):
print("Usage: perftest.py [options]")
print("Options are:")
print(" --help: Get help message")
print(" --outdir: Set output directory")
print(" --tmpdir: Set temporary directory")
print(" --preserve: Preserve existing runs")
print(" --searchruns: How many times to repeat each search run")
print(" --usedb: Use a particular existing database (only do search tests)")
sys.exit(exitval)
def parse_argv(argv, **defaults):
config = Config(**defaults)
try:
optlist, argv = getopt.gnu_getopt(argv, 'ho:t:p',
('help', 'outdir=', 'tmpdir=', 'preserve', 'searchruns=', 'usedb='))
for (opt, val) in optlist:
if opt == '-h' or opt == '--help':
usage(0)
elif opt == '-o' or opt == '--outdir':
config.outdir = val
elif opt == '-t' or opt == '--tmpdir':
config.tmpdir = val
elif opt == '-p' or opt == '--preserve':
config.preserve = True
elif opt == '--searchruns':
config.searchruns = int(val)
elif opt == '--usedb':
config.usedb = val
else:
print("Unknown option %r" % opt)
usage(1)
except getopt.GetoptError, e:
print("Bad options: %r" % str(e))
usage(1)
if len(argv) != 1:
print("Wrong number of arguments")
usage(1)
return config
def do_index(config, testrun):
dbpath = testrun.dbpath(config)
indexlogpath = testrun.indexlogpath(config)
if not config.preserve or \
not os.path.exists(dbpath) or \
not os.path.exists(indexlogpath):
if os.path.exists(dbpath):
shutil.rmtree(dbpath)
if os.path.exists(indexlogpath):
os.unlink(indexlogpath)
print "Starting index run (creating %s)" % dbpath
indexer.index_file(inputfile=testrun.inputfile,
dbpath=dbpath,
logpath=indexlogpath,
flushspeed=testrun.flushspeed,
description=testrun.description,
maxdocs=testrun.maxdocs,
logspeed=testrun.logspeed)
print "Ending index run"
def do_search(config, testrun):
dbpath = testrun.dbpath(config)
# FIXME - clear cache before first run
for runnum in range(1, config.searchruns + 1):
for queryfile, concurrency, extraargs in testrun.queryruns:
searchlogfile = testrun.searchlogpath(config, queryfile, concurrency, extraargs, runnum)
if config.preserve and \
os.path.exists(searchlogfile):
continue
print "Starting search run (logging to %s)" % searchlogfile
tests = searcher.QueryTests(queryfile, dbpath, searchlogfile, concurrency, **extraargs)
tests.run()
print "Ending search run"
def analyse_index(config):
if analyse_indexlogs is None:
return
alltimes = {}
for testrun in config.testruns:
if testrun.noindex:
continue
indexlogpath = testrun.indexlogpath(config)
outprefix = testrun.indexoutprefix(config)
desc_line, times = analyse_indexlogs.parse_logfile(indexlogpath)
title_line = testrun.description
if testrun.maxdocs is not None:
title_line += ", maxdocs=%d" % testrun.maxdocs
title_line += ", flush=%d" % testrun.flushspeed
filenameprefix = testrun.filename_safe_description() + testrun.maxdocs_pathbit()
analyse_indexlogs.generate_figures(times, outprefix, title_line)
if filenameprefix not in alltimes:
alltimes[filenameprefix] = (testrun.description, [])
alltimes[filenameprefix][1].append(("flush=%d" % testrun.flushspeed, times))
for desc in alltimes.iterkeys():
outprefix = os.path.join(config.outdir, 'index_comparison_%s_' % (desc, ))
analyse_indexlogs.generate_comparison_figures(alltimes[desc][1], outprefix, alltimes[desc][0])
def analyse_search(config):
if analyse_searchlogs is None:
return
for testrun in config.testruns:
for runnum in range(1, config.searchruns + 1):
for queryfile, concurrency, extraargs in testrun.queryruns:
searchlogpath = testrun.searchlogpath(config, queryfile, concurrency, extraargs, runnum)
outprefix = testrun.searchoutprefix(config, queryfile, concurrency, extraargs, runnum)
log = analyse_searchlogs.parse_logfile(searchlogpath)
title = testrun.description
title += ", " + os.path.basename(queryfile)
if concurrency != 1:
title += ", concurrency=%d" % concurrency
for arg in extraargs:
if arg == 'range':
title += ", range=%s,%d,%d" % extraargs[arg]
elif arg == 'gettags':
title += ", gettags=%s,%d" % extraargs[arg]
else:
title += ", %s=%s" % (arg, extraargs[arg])
analyse_searchlogs.generate_figures(log, outprefix, title)
class TestRun(object):
def __init__(self, inputfile, description, flushspeed=10000, maxdocs=None, logspeed=1000, noindex=False):
"""
- description: textual description of this run (excluding information
about other parameters specified here)
- flushspeed: frequency (ie, number of adds) with which to explicitly
call flush() on the database.
- maxdocs: maximum number of documents to add (stop automatically
after this many).
- logspeed: make a log entry each time we add "logspeed" documents.
- noindex: If True, don't do an indexing run (use existing database)
"""
self.inputfile = os.path.abspath(inputfile)
self.description = description
self.flushspeed = flushspeed
self.maxdocs = maxdocs
self.logspeed = logspeed
self.noindex = noindex
self.queryruns = []
def add_query_run(self, queryfile, concurrency, **extraargs):
self.queryruns.append((os.path.abspath(queryfile), concurrency, extraargs))
def maxdocs_pathbit(self):
if self.maxdocs is None: return ''
return "_maxdocs%d" % self.maxdocs
def _flushspeed_pathbit(self):
return "_flush%d" % self.flushspeed
def _index_pathbit(self):
return "%s%s%s" % (self.filename_safe_description(),
self._flushspeed_pathbit(),
self.maxdocs_pathbit())
def _filename_safe_path(self, path):
desc = []
for char in path.lower():
if char.isalnum():
desc.append(char)
elif len(desc) > 0 and desc[-1] != '_':
desc.append('_')
return ''.join(desc)
def filename_safe_description(self):
return self._filename_safe_path(self.description)
def dbpath(self, config):
if self.noindex:
return self.inputfile
return os.path.join(config.tmpdir, 'db_%s' % self._index_pathbit())
def indexlogpath(self, config):
return os.path.join(config.outdir, 'indexlog_%s.csv' % self._index_pathbit())
def indexoutprefix(self, config):
return os.path.join(config.outdir, 'index_%s_' % self._index_pathbit())
def extraargs_pathbit(self, extraargs):
extraargs_list = list(extraargs.iteritems())
extraargs_list.sort()
extraargs = []
for key, val in extraargs_list:
extraargs.append(key + "_" + str(val))
extraargs = '_'.join(extraargs)
extraargs = self._filename_safe_path(extraargs)
while extraargs.endswith('_'):
extraargs = extraargs[:-1]
if extraargs == '':
return ''
return "_" + extraargs
def queryfile_pathbit(self, queryfile):
return self._filename_safe_path(os.path.splitext(os.path.basename(queryfile))[0])
def searchlogpath(self, config, queryfile, concurrency, extraargs, runnum):
return os.path.join(config.outdir, 'searchlog_%s_%s_threads%d%s_run%d.csv' %
(self._index_pathbit(),
self.queryfile_pathbit(queryfile),
concurrency,
self.extraargs_pathbit(extraargs),
runnum))
def searchoutprefix(self, config, queryfile, concurrency, extraargs, runnum):
return os.path.join(config.outdir, 'search_%s_%s_threads%d%s_run%d_' %
(self._index_pathbit(),
self.queryfile_pathbit(queryfile),
concurrency,
self.extraargs_pathbit(extraargs),
runnum))
def searchdumpdir(self, config, queryfile, concurrency, extraargs, runnum):
return os.path.join(config.tmpdir, 'searchdump_%s_%s_threads%d%s_run%d' %
(self._index_pathbit(),
self.queryfile_pathbit(queryfile),
concurrency,
self.extraargs_pathbit(extraargs),
runnum))
if __name__ == '__main__':
config = parse_argv(sys.argv,
tmpdir='perftesttmpdir',
outdir='perftestoutdir',
preserve=False,
searchruns=5,
usedb=None)
for key in ('tmpdir', 'outdir', ):
setattr(config, key, os.path.abspath(getattr(config, key)))
# Build up a set of test runs to do.
config.testruns = []
# Comment out the index runs with different flush values for now.
if False:
testrun = TestRun("sampledata/wikipedia.dump", "wikipedia", flushspeed=1, maxdocs=1000, logspeed=10)
config.testruns.append(testrun)
testrun = TestRun("sampledata/wikipedia.dump", "wikipedia", flushspeed=10, maxdocs=1000, logspeed=10)
config.testruns.append(testrun)
testrun = TestRun("sampledata/wikipedia.dump", "wikipedia", 1000, maxdocs=10000)
config.testruns.append(testrun)
testrun = TestRun("sampledata/wikipedia.dump", "wikipedia", 10000)
config.testruns.append(testrun)
if config.usedb is None:
testrun = TestRun("sampledata/wikipedia.dump", "wikipedia", 100000)
else:
testrun = TestRun(config.usedb, "wikipedia", noindex=True)
testrun.add_query_run("sampledata/queries.txt", 1)
testrun.add_query_run("sampledata/queries.txt", 1, use_or=True)
testrun.add_query_run("sampledata/queries.txt", 10)
testrun.add_query_run("sampledata/queries.txt", 100)
testrun.add_query_run("sampledata/queries.txt", 1, sort="doclen")
testrun.add_query_run("sampledata/queries.txt", 1, collapse="doclen")
testrun.add_query_run("sampledata/queries.txt", 1, range=("doclen", 10000, 30000))
#testrun.add_query_run("sampledata/queries.txt", 1, getfacets=10)
#testrun.add_query_run("sampledata/queries.txt", 1, gettags=("tags",10))
config.testruns.append(testrun)
# Make directories (and ensure they're empty)
if not config.preserve:
if os.path.exists(config.outdir):
shutil.rmtree(config.outdir)
if os.path.exists(config.tmpdir):
shutil.rmtree(config.tmpdir)
if not os.path.exists(config.outdir):
os.mkdir(config.outdir)
if not os.path.exists(config.tmpdir):
os.mkdir(config.tmpdir)
# Do the indexing
for testrun in config.testruns:
if not testrun.noindex:
do_index(config, testrun)
analyse_index(config)
# Do the searching
for testrun in config.testruns:
do_search(config, testrun)
analyse_search(config)
xappy-0.5/perftest/searcher.py 0000755 0001750 0001750 00000011406 10703015433 016334 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import time
import thread
import threading
import getopt
import xappy
class TestRunner(threading.Thread):
def __init__(self, tests, num):
threading.Thread.__init__(self)
self.tests = tests
self.num = num
self.sconn = xappy.SearchConnection(tests.dbdir)
def run(self):
try:
while True:
querynum, query = self.tests.get_query()
query = query.strip()
querystart = time.time()
if self.tests.use_or:
parsedquery = self.sconn.query_parse(query,
default_op=self.sconn.OP_OR)
else:
parsedquery = self.sconn.query_parse(query)
if self.tests.range is not None:
rangequery = self.sconn.query_range(*self.tests.range)
parsedquery = self.sconn.query_filter(parsedquery, rangequery)
search_getfacets = (self.tests.getfacets is not None)
search_gettags = None
if self.tests.gettags is not None:
self.search_gettags = self.tests.gettags[0]
results = self.sconn.search(parsedquery, 0, 10,
sortby=self.tests.sort,
collapse=self.tests.collapse,
getfacets=search_getfacets,
gettags=search_gettags)
self.tests.log_search(self.num, querynum, results.matches_estimated, querystart, parsedquery.get_length(), query)
except StopIteration:
return
class QueryTests(object):
def __init__(self, queryfile=None, dbdir=None, logfile=None, threads=1,
sort=None, collapse=None, range=None, getfacets=None,
gettags=None, use_or=False):
self.queryfile = queryfile
self.dbdir = dbdir
self.logfile = logfile
self.qfd = open(queryfile)
self.logfd = open(logfile, "a")
self.logfd.write("Thread Num,Query Num,Count of queries with some matches,Estimated matches,Time (seconds),Elapsed Time(seconds)\n")
self.querycount = 0
self.matchingcount = 0
self.starttime = time.time()
self.threads = threads
self.use_or = use_or
self.sort = sort
self.collapse = collapse
self.range = range
self.getfacets = getfacets
self.gettags = gettags
self.mutex = threading.Lock()
def get_query(self):
self.mutex.acquire()
try:
q = self.qfd.readline()
if len(q) == 0:
raise StopIteration
self.querycount += 1
return self.querycount, q
finally:
self.mutex.release()
def log_search(self, threadnum, querynum, resultest, querystart, querylen, query):
self.mutex.acquire()
try:
try:
if resultest != 0:
self.matchingcount += 1
currtime = time.time()
self.logfd.write("%d,%d,%d,%d,%f,%f,%d,%r\n" % (threadnum,
querynum,
self.matchingcount,
resultest,
currtime - querystart,
currtime - self.starttime,
querylen,
query))
self.logfd.flush()
except StopIteration:
return
finally:
self.mutex.release()
def run(self):
for i in xrange(self.threads):
runner = TestRunner(self, i + 1)
runner.start()
runner.join()
xappy-0.5/perftest/setuppaths.py 0000644 0001750 0001750 00000002670 10702510046 016737 0 ustar richard richard # Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""setuppaths.py: Setup sys.path
This is a special module which ensures that sys.path is set appropriately
simply by being imported.
To use, simply import it at the very start of any module which requires
use of xappy. This will allow the module to work with an uninstalled version
of xappy located relative to this path.
"""
__docformat__ = "restructuredtext en"
import os
import sys
def setup_path():
"""Set up sys.path to allow us to import Xappy when run uninstalled.
"""
abspath = os.path.abspath(__file__)
dirname = os.path.dirname(abspath)
dirname = os.path.dirname(dirname)
if os.path.exists(os.path.join(dirname, 'xappy')):
sys.path.insert(0, dirname)
setup_path()
xappy-0.5/secore/ 0000755 0001750 0001750 00000000000 11005556727 013621 5 ustar richard richard xappy-0.5/secore/__init__.py 0000644 0001750 0001750 00000002313 10667533120 015724 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
Xappy used to be called "secore". To assist in migration to secore, this
simple compatibility wrapper is provided, which allows existing code which use:
>>> import secore
to work without changes. References to the "secore" name should be changed to
"xappy" whenever possible, however, since this compatibility wrapper will be
removed at some point.
"""
__docformat__ = "restructuredtext en"
from xappy import *
xappy-0.5/secore/datastructures.py 0000644 0001750 0001750 00000001521 10667533345 017253 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.datastructures import *
xappy-0.5/secore/errors.py 0000644 0001750 0001750 00000001511 10667533467 015516 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.errors import *
xappy-0.5/secore/fieldactions.py 0000644 0001750 0001750 00000001517 10667533503 016643 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.fieldactions import *
xappy-0.5/secore/fieldmappings.py 0000644 0001750 0001750 00000001520 10667533512 017013 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.fieldmappings import *
xappy-0.5/secore/highlight.py 0000644 0001750 0001750 00000001514 10667533525 016147 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.highlight import *
xappy-0.5/secore/indexerconnection.py 0000644 0001750 0001750 00000001524 10667533534 017717 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.indexerconnection import *
xappy-0.5/secore/marshall.py 0000644 0001750 0001750 00000001513 10667533543 016002 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.marshall import *
xappy-0.5/secore/parsedate.py 0000644 0001750 0001750 00000001514 10667533551 016147 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.parsedate import *
xappy-0.5/secore/searchconnection.py 0000644 0001750 0001750 00000001523 10667533565 017531 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Compatibility wrapper for Xappy.
"""
from xappy.searchconnection import *
xappy-0.5/testdata/ 0000755 0001750 0001750 00000000000 11005556727 014152 5 ustar richard richard xappy-0.5/testdata/query_sourcewords.txt 0000644 0001750 0001750 00003624513 10667526240 020535 0 ustar richard richard A
A's
Advent
Advent's
Advents
Africa
Africa's
African
Africans
Allah
Allah's
America
America's
American
Americana
Americana's
Americanism
Americanism's
Americanisms
Americans
Anglican
Anglicans
Anglo
Anglo's
Anglos
Antarctic
Antarctic's
Antarctica
Antarctica's
Apr
Apr's
April
April's
Aprils
Aquarius
Aquarius's
Aquariuses
Arab
Arab's
Arabic
Arabic's
Arabs
Arctic
Arctic's
Aries
Arieses
As
Asia
Asia's
Asian
Asians
AstroTurf
AstroTurfs
Atlantic
Atlantic's
Aug
Aug's
August
August's
Augusts
Australia
Australia's
Australian
Australian's
Australians
Ave
Ave's
Aves
B
B's
Baptist
Baptist's
Baptists
Bible
Bible's
Bibles
Black
Black's
Blacks
Blvd
Braille
Braille's
Brailled
Brailles
Brailling
Britain
Britain's
British
Britisher
Brown
Brown's
Brownie
Brownie's
Brownies
Buddha
Buddha's
Buddhas
Buddhism
Buddhism's
Buddhisms
Buddhist
Buddhist's
Buddhists
C
C's
Cabinet
Cabinets
Canadian
Canadians
Cancer
Cancer's
Cancers
Cantonese
Cantonese's
Capitol
Capitol's
Capitols
Capricorn
Capricorn's
Capricorns
Caribbean
Caribbeans
Catholic
Catholicism
Catholicism's
Catholicisms
Catholics
Caucasian
Caucasians
Celsius
Celsiuses
Chicano
Chicano's
Chicanos
Chinatown
Chinatown's
Chinatowns
Chinese
Christ
Christ's
Christian
Christian's
Christianities
Christianity
Christianity's
Christians
Christmas
Christmas's
Christmases
Christs
Ci
Co
Co's
Coke
Coke's
Cokes
Communion
Communion's
Communions
Confederacy
Confederacy's
Confederate
Confederates
Congress
Congress's
Congresses
Constitution
Cs
Cyrillic
D
D's
Dalmatian
Dalmatian's
Dalmatians
Danish
Dec
Dec's
December
December's
Decembers
Democrat
Democrat's
Democratic
Democrats
Dixie
Dixie's
Doctor
Dr
Dr's
Dumpster
Dumpsters
Dutch
Dutch's
E
E's
Earth
Easter
Easter's
Easters
Emmies
Emmy
Emmy's
Emmys
England
England's
English
English's
Englished
Englisher
Englishes
Englishing
Episcopalian
Episcopalians
Es
Eskimo
Eskimo's
Eskimos
Europe
Europe's
European
Europeans
F
F's
Fahrenheit
Fahrenheits
Father
Father's
Fathers
Feb
Feb's
Februaries
February
February's
Februarys
Fed
Fed's
Feds
French
French's
Frenched
Frenches
Frenching
Freudian
Freudians
Fri
Fri's
Friday
Friday's
Fridays
Frisbee
Frisbee's
Frisbees
G
G's
Gemini
Gemini's
Geminis
Gen
Gen's
German
German's
Germans
God
God's
Gospel
Gospel's
Gospels
Grammies
Grammy
Greek
Greek's
Greeks
H
H's
Halloween
Halloween's
Halloweens
Hanukkah
Hanukkah's
Hanukkahs
Hebrew
Hebrew's
Hebrews
Highness
Highness's
Hindu
Hindu's
Hinduism
Hinduism's
Hinduisms
Hindus
Hispanic
Hispanics
Hollywood
Hollywood's
Holocaust
House
House's
I
I'd
I'll
I'm
I've
Inc
Inc's
Indian
Indian's
Indians
Internet
Inuit
Inuit's
Inuits
Irish
Irisher
Islam
Islam's
Islamic
Islamics
Islams
Italian
Italian's
Italians
J
J's
Jacuzzi
Jacuzzis
Jan
Jan's
Januaries
January
January's
Januarys
Japanese
Japaneses
Jeep
Jeeps
Jesus
Jew
Jew's
Jewish
Jews
John
John's
Jr
Jr's
Judaism
Judaism's
Judaisms
Jul
Jul's
Julies
July
July's
Jun
Jun's
June
June's
Junes
Junior
Juniors
Jupiter
Jupiter's
K
K's
Kleenex
Kleenex's
Kleenexes
Koran
Koran's
Korans
Korean
Koreans
Kwanzaa
Kwanzaas
L
L's
Latin
Latin's
Latina
Latina's
Latinas
Latiner
Latino
Latinos
Latins
Laundromat
Laundromat's
Laundromats
Lent
Lent's
Lents
Leo
Leo's
Leos
Libra
Libra's
Libras
Ln
Lord
Lord's
Lords
Lutheran
Lutheran's
Lutherans
M
M's
Mace
Mace's
Maced
Maces
Macing
Mafia
Mafia's
Mafias
Mandarin
Maori
Maori's
Maoris
Mar
Mar's
March
March's
Marches
Marine
Marines
Mars
Martian
Martians
Marxism
Marxism's
Marxisms
Marxist
Marxist's
Marxists
Mason
Mason's
Masons
Mass
Masses
May
May's
Mays
McCoy
McCoy's
McCoys
Mecca
Mecca's
Meccas
Medicaid
Medicaid's
Medicaids
Medicare
Medicare's
Medicares
Mediterranean
Mediterranean's
Mediterraneans
Mercuries
Mercury
Mercury's
Messiah
Messiah's
Messiahs
Messrs
Messrs's
Methodist
Methodist's
Methodists
Mexican
Mexicans
Midwest
Midwest's
Midwestern
Miss
Miss's
Misses
Mister
Mister's
Mon
Mon's
Monday
Monday's
Mondays
Mons
Mormon
Mormon's
Mormons
Moslem
Moslem's
Moslems
Mount
Mount's
Mr
Mr's
Mrs
Ms
Mt
Mt's
Muhammad
Muhammad's
Muslim
Muslim's
Muslims
Muzak
Muzak's
Muzaks
N
N's
Nazi
Nazi's
Nazis
Negro
Negro's
Negroes
Neptune
Neptune's
Nov
Nov's
November
November's
Novembers
O
OK
OKs
Oct
Oct's
October
October's
Octobers
Olympic
Olympics
Orient
Orient's
Oriental
Orientals
Orients
Os
Oscar
Oscar's
Oscars
P
P's
Pacific
Pacific's
Passover
Passover's
Passovers
Pentagon
Pentagon's
Pharaoh
Pharaoh's
Pharaohs
Pilgrim
Pilgrims
Pisces
Pisces's
Pkwy
Pl
Plexiglas
Plexiglas's
Plexiglases
Pluto
Pluto's
Polaroid
Polaroid's
Polaroids
Pole
Pole's
Poles
Polish
Pope
Pope's
Popes
Popsicle
Popsicle's
Popsicles
Portuguese
Portuguese's
Presbyterian
Presbyterians
President
Presidents
Prof
Prohibition
Prohibition's
Prohibitions
Protestant
Protestant's
Protestants
Puritan
Puritan's
Puritans
Pyrex
Pyrex's
Pyrexes
Q
Q's
R
R's
Ramadan
Ramadan's
Ramadans
Rd
Rd's
Realtor
Realtors
Renaissance
Renaissance's
Renaissances
Rep
Rep's
Representative
Representatives
Republican
Republicans
Resurrection
Resurrection's
Resurrections
Rev
Rev's
Reverend
Rollerblade
Rollerblades
Roman
Romans
Rte
Russian
Russian's
Russians
S
S's
Sabbath
Sabbath's
Sabbaths
Sagittarius
Sagittarius's
Sagittariuses
Santa
Santa's
Sat
Sat's
Satan
Satan's
Saturday
Saturday's
Saturdays
Saturn
Saturn's
Savior
Savior's
Scandinavia
Scandinavia's
Scandinavian
Scandinavians
Scorpio
Scorpio's
Scorpios
Scotch
Scotches
Scottish
Scripture
Scripture's
Scriptures
Sec
Secretaries
Secretary
Sen
Senate
Senate's
Senates
Senator
Senior
Seniors
Sept
Sept's
September
September's
Septembers
Sgt
Sikh
Sikh's
Sikhism
Sikhism's
Sikhisms
Sikhs
Sister
Sisters
Soviet
Soviets
Spanish
Spanish's
Spartan
Spartans
Sq
Sq's
Sr
St
St's
Styrofoam
Styrofoams
Sun
Sunday
Sunday's
Sundays
Swiss
Swisses
T
T's
Taiwanese
Talmud
Talmud's
Talmuds
Taurus
Taurus's
Tauruses
Teflon
Teflon's
Teflons
Terr
Terr's
Thanksgiving
Thanksgivings
Thermos
Thermos's
Thermoses
Thurs
Thursday
Thursday's
Thursdays
Trinities
Trinity
Trinity's
Tues
Tuesday
Tuesday's
Tuesdays
Tylenol
U
Uranus
Uranus's
V
V's
Velcro
Velcro's
Velcros
Venus
Venuses
Virgo
Virgo's
Virgos
W
W's
Walkman
Walkmans
Wed
Wed's
Wednesday
Wednesday's
Wednesdays
Welsh
Western
Westerner
Westerners
Westerns
White
White's
Whites
X
X's
Xerox
Xerox's
Xeroxed
Xeroxes
Xeroxing
Xmas
Xmas's
Xmases
Y
Y's
Yank
Yank's
Yankee
Yankee's
Yankees
Yanks
Yiddish
Yiddish's
Yuletide
Yuletides
Z
Z's
a
aardvark
aardvark's
abaci
aback
abacus
abacus's
abacuses
abandon
abandoned
abandoning
abandonment
abandonment's
abandons
abash
abashed
abashes
abashing
abate
abated
abates
abating
abbey
abbey's
abbeys
abbot
abbot's
abbots
abbreviate
abbreviated
abbreviates
abbreviating
abbreviation
abbreviation's
abbreviations
abdicate
abdicated
abdicates
abdicating
abdication
abdication's
abdications
abdomen
abdomen's
abdomens
abdominal
abduct
abducted
abducting
abduction
abduction's
abductions
abducts
aberration
aberration's
aberrations
abet
abets
abetted
abetting
abhor
abhorred
abhorrence
abhorrence's
abhorrent
abhorring
abhors
abide
abided
abides
abiding
abidings
abilities
ability
ability's
abject
abjected
abjecting
abjects
ablaze
able
abler
ables
ablest
ably
abnormal
abnormalities
abnormality
abnormality's
abnormally
aboard
abode
abode's
aboded
abodes
aboding
abolish
abolished
abolishes
abolishing
abolition
abolition's
abolitionist
abolitionist's
abolitionists
abominable
abomination
abomination's
aboriginal
aboriginals
aborigine
aborigine's
aborigines
abort
aborted
aborting
abortion
abortion's
abortions
abortive
aborts
abound
abounded
abounding
abounds
about
abouts
above
aboveboard
abrasive
abrasive's
abrasively
abrasives
abreast
abridge
abridged
abridgement
abridgement's
abridgements
abridges
abridging
abroad
abrupt
abrupter
abruptest
abruptly
abruptness
abruptness's
abscess
abscess's
abscessed
abscesses
abscessing
abscond
absconded
absconding
absconds
absence
absence's
absences
absent
absented
absentee
absentee's
absenteeism
absenteeism's
absentees
absenting
absently
absents
absolute
absolutely
absoluter
absolutes
absolutest
absolve
absolved
absolves
absolving
absorb
absorbed
absorbent
absorbents
absorbing
absorbs
absorption
absorption's
abstain
abstained
abstaining
abstains
abstention
abstention's
abstentions
abstinence
abstinence's
abstinent
abstract
abstracted
abstracter
abstractest
abstracting
abstraction
abstraction's
abstractions
abstracts
abstruse
absurd
absurder
absurdest
absurdities
absurdity
absurdity's
absurdly
abundance
abundance's
abundances
abundant
abundantly
abuse
abused
abuser
abusers
abuses
abusing
abusive
abysmal
abysmally
abyss
abyss's
abysses
academic
academically
academics
academies
academy
academy's
accede
acceded
accedes
acceding
accelerate
accelerated
accelerates
accelerating
acceleration
acceleration's
accelerations
accelerator
accelerator's
accelerators
accent
accent's
accented
accenting
accents
accentuate
accentuated
accentuates
accentuating
accept
acceptability
acceptability's
acceptable
acceptably
acceptance
acceptance's
acceptances
accepted
accepting
accepts
access
access's
accessed
accesses
accessibility
accessibility's
accessible
accessing
accessories
accessory
accessory's
accident
accident's
accidental
accidentally
accidentals
accidents
acclaim
acclaimed
acclaiming
acclaims
acclimate
acclimated
acclimates
acclimating
acclimation
acclimation's
acclimatize
acclimatized
acclimatizes
acclimatizing
accolade
accolade's
accoladed
accolades
accolading
accommodate
accommodated
accommodates
accommodating
accommodation
accommodation's
accommodations
accompanied
accompanies
accompaniment
accompaniment's
accompaniments
accompanist
accompanist's
accompanists
accompany
accompanying
accomplice
accomplice's
accomplices
accomplish
accomplished
accomplishes
accomplishing
accomplishment
accomplishment's
accomplishments
accord
accord's
accordance
accordance's
accorded
according
accordingly
accordion
accordion's
accordions
accords
accost
accosted
accosting
accosts
account
account's
accountability
accountability's
accountable
accountancy
accountancy's
accountant
accountant's
accountants
accounted
accounting
accounting's
accounts
accredit
accreditation
accreditation's
accredited
accrediting
accredits
accrue
accrued
accrues
accruing
accumulate
accumulated
accumulates
accumulating
accumulation
accumulation's
accumulations
accuracy
accuracy's
accurate
accurately
accusation
accusation's
accusations
accuse
accused
accused's
accuser
accuser's
accusers
accuses
accusing
accusingly
accustom
accustomed
accustoming
accustoms
ace
ace's
aced
acerbic
aces
ache
ached
aches
achier
achiest
achievable
achieve
achieved
achievement
achievement's
achievements
achiever
achiever's
achievers
achieves
achieving
aching
achy
acid
acid's
acidic
acidity
acidity's
acids
acing
acknowledge
acknowledged
acknowledgement
acknowledgement's
acknowledgements
acknowledges
acknowledging
acne
acne's
acorn
acorn's
acorns
acoustic
acoustics
acoustics's
acquaint
acquaintance
acquaintance's
acquaintances
acquainted
acquainting
acquaints
acquiesce
acquiesced
acquiescence
acquiescence's
acquiesces
acquiescing
acquire
acquired
acquires
acquiring
acquisition
acquisition's
acquisitions
acquit
acquited
acquiting
acquits
acquittal
acquittal's
acquittals
acquitted
acquitting
acre
acre's
acreage
acreage's
acreages
acres
acrid
acrider
acridest
acrimonious
acrimony
acrimony's
acrobat
acrobat's
acrobatic
acrobatics
acrobatics's
acrobats
acronym
acronym's
acronyms
across
acrylic
acrylics
act
act's
acted
acting
action
action's
actioned
actioning
actions
activate
activated
activates
activating
activation
activation's
active
actively
actives
activism
activism's
activist
activist's
activists
activities
activity
activity's
actor
actor's
actors
actress
actress's
actresses
acts
actual
actualisation
actualisation's
actualities
actuality
actuality's
actually
actuary
actuary's
acumen
acumen's
acupuncture
acupuncture's
acute
acutely
acuter
acutes
acutest
ad
ad's
adage
adage's
adages
adamant
adamantly
adapt
adaptable
adaptation
adaptation's
adaptations
adapted
adapting
adaptive
adaptor
adaptor's
adaptors
adapts
add
added
addendum
addendum's
addict
addicted
addicting
addiction
addiction's
addictions
addictive
addicts
adding
addition
addition's
additional
additionally
additions
additive
additives
address
address's
addressed
addressee
addressee's
addressees
addresses
addressing
adds
adept
adepter
adeptest
adeptly
adepts
adequacy
adequacy's
adequate
adequately
adhere
adhered
adherence
adherence's
adherent
adherent's
adherents
adheres
adhering
adhesion
adhesion's
adhesive
adhesives
adjacent
adjectival
adjective
adjective's
adjectives
adjoin
adjoined
adjoining
adjoins
adjourn
adjourned
adjourning
adjournment
adjournment's
adjournments
adjourns
adjudicate
adjudicated
adjudicates
adjudicating
adjudicator
adjudicator's
adjudicators
adjunct
adjunct's
adjuncts
adjust
adjustable
adjusted
adjusting
adjustment
adjustment's
adjustments
adjusts
administer
administered
administering
administers
administration
administration's
administrations
administrative
administrator
administrator's
administrators
admirable
admirably
admiral
admiral's
admirals
admiration
admiration's
admire
admired
admirer
admirer's
admirers
admires
admiring
admiringly
admissible
admission
admission's
admissions
admit
admits
admittance
admittance's
admitted
admittedly
admitting
admonish
admonished
admonishes
admonishing
admonition
admonition's
admonitions
ado
ado's
adobe
adobe's
adobes
adolescence
adolescence's
adolescences
adolescent
adolescents
adopt
adopted
adopting
adoption
adoption's
adoptions
adoptive
adopts
adorable
adoration
adoration's
adore
adored
adores
adoring
adorn
adorned
adorning
adornment
adornment's
adornments
adorns
adrenaline
adrenaline's
adrift
adroit
adroiter
adroitest
adroitly
ads
adulation
adulation's
adult
adulterate
adulterated
adulterates
adulterating
adulteration
adulteration's
adulteries
adultery
adultery's
adulthood
adulthood's
adults
advance
advanced
advancement
advancement's
advancements
advances
advancing
advantage
advantage's
advantaged
advantageous
advantages
advantaging
advent
advent's
advents
adventure
adventure's
adventured
adventurer
adventurer's
adventurers
adventures
adventuring
adventurous
adverb
adverb's
adverbial
adverbial's
adverbials
adverbs
adversaries
adversary
adversary's
adverse
adversely
adverser
adversest
adversities
adversity
adversity's
advert
advertise
advertised
advertisement
advertisement's
advertisements
advertiser
advertiser's
advertisers
advertises
advertising
advertising's
adverts
advice
advice's
advisable
advise
advised
adviser
adviser's
advisers
advises
advising
advisor
advisories
advisors
advisory
advocacy
advocacy's
advocate
advocated
advocates
advocating
aerial
aerials
aerobic
aerobics
aerodynamic
aerodynamics
aerodynamics's
aeroplane
aeroplane's
aeroplanes
aerosol
aerosol's
aerosols
aerospace
aerospace's
aesthetic
aesthetically
aesthetics
aesthetics's
afar
affable
affabler
affablest
affably
affair
affair's
affairs
affect
affectation
affectation's
affectations
affected
affecting
affection
affection's
affectionate
affectionately
affectioned
affectioning
affections
affects
affidavit
affidavit's
affidavits
affiliate
affiliated
affiliates
affiliating
affiliation
affiliation's
affiliations
affinities
affinity
affinity's
affirm
affirmation
affirmation's
affirmations
affirmative
affirmatively
affirmatives
affirmed
affirming
affirms
affix
affixed
affixes
affixing
afflict
afflicted
afflicting
affliction
affliction's
afflictions
afflicts
affluence
affluence's
affluent
afford
affordable
afforded
affording
affords
affront
affront's
affronted
affronting
affronts
afield
aflame
afloat
afoot
aforementioned
aforesaid
afraid
afresh
after
aftereffect
aftereffect's
aftereffects
afterlife
afterlife's
afterlives
aftermath
aftermath's
aftermaths
afternoon
afternoon's
afternoons
afters
aftershave
aftershaves
aftershock
aftershock's
aftershocks
afterthought
afterthought's
afterthoughts
afterwards
again
against
age
age's
aged
ageing
ageings
agencies
agency
agency's
agenda
agenda's
agendas
agent
agent's
agents
ages
aggravate
aggravated
aggravates
aggravating
aggravation
aggravation's
aggravations
aggregate
aggregated
aggregates
aggregating
aggression
aggression's
aggressive
aggressively
aggressiveness
aggressor
aggressor's
aggressors
aggrieve
aggrieved
aggrieves
aggrieving
aghast
agile
agiler
agilest
agility
agility's
agitate
agitated
agitates
agitating
agitation
agitation's
agitations
agitator
agitator's
agitators
aglow
agnostic
agnostic's
agnosticism
agnosticism's
agnostics
ago
agonies
agonise
agonised
agonises
agonising
agonisingly
agony
agony's
agree
agreeable
agreeably
agreed
agreeing
agreement
agreement's
agreements
agrees
agricultural
agriculture
agriculture's
aground
ah
aha
ahas
ahead
ahoy
ahoys
aid
aide
aide's
aided
aides
aiding
aids
ail
ailed
ailing
ailment
ailment's
ailments
ails
aim
aimed
aiming
aimless
aimlessly
aims
ain't
air
air's
airborne
aircraft
aircraft's
aired
airfare
airfares
airfield
airfield's
airfields
airier
airiest
airily
airing
airing's
airings
airless
airline
airline's
airliner
airliner's
airliners
airlines
airmail
airmailed
airmailing
airmails
airport
airport's
airports
airs
airspace
airspace's
airstrip
airstrip's
airstrips
airtight
airwaves
airy
aisle
aisle's
aisled
aisles
aisling
ajar
akin
alarm
alarmed
alarming
alarmingly
alarmist
alarmist's
alarmists
alarms
alas
alases
albeit
albino
albino's
albinos
album
album's
albums
alcohol
alcohol's
alcoholic
alcoholic's
alcoholics
alcoholism
alcoholism's
alcohols
alcove
alcove's
alcoves
alderman
alderman's
aldermen
alderwoman
alderwomen
ale
ale's
alert
alerted
alerter
alertest
alerting
alerts
ales
alfalfa
alfalfa's
alga
algae
algebra
algebra's
algebraic
algorithm
algorithm's
algorithms
alias
aliased
aliases
aliasing
alibi
alibi's
alibied
alibiing
alibis
alien
alien's
alienate
alienated
alienates
alienating
alienation
alienation's
aliened
aliening
aliens
alight
alighted
alighting
alights
align
aligned
aligning
alignment
alignment's
alignments
aligns
alike
alimony
alimony's
alit
alive
alkali
alkali's
alkalies
alkaline
alkalis
all
allay
allayed
allaying
allays
allegation
allegation's
allegations
allege
alleged
allegedly
alleges
allegiance
allegiance's
allegiances
alleging
allegorical
allegories
allegory
allegory's
allergic
allergies
allergy
allergy's
alleviate
alleviated
alleviates
alleviating
alleviation
alleviation's
alley
alley's
alleys
alliance
alliance's
alliances
allied
allies
allies's
alligator
alligator's
alligators
allocate
allocated
allocates
allocating
allocation
allocation's
allocations
allot
allotment
allotment's
allotments
allots
allotted
allotting
allow
allowable
allowance
allowance's
allowances
allowed
allowing
allows
alloy
alloy's
alloyed
alloying
alloys
allude
alluded
alludes
alluding
allure
allured
allures
alluring
allusion
allusion's
allusions
ally
allying
almanac
almanac's
almanacs
almighty
almond
almond's
almonds
almost
alms
aloft
aloha
aloha's
alohas
alone
along
alongside
aloof
aloud
alpha
alpha's
alphabet
alphabet's
alphabeted
alphabetic
alphabetical
alphabetically
alphabeting
alphabets
alphanumeric
alpine
alpines
already
alright
also
altar
altar's
altars
alter
alterable
alteration
alteration's
alterations
altercation
altercation's
altercations
altered
altering
alternate
alternated
alternately
alternates
alternating
alternation
alternation's
alternations
alternative
alternative's
alternatively
alternatives
alternator
alternator's
alters
although
altitude
altitude's
altitudes
alto
alto's
altogether
altos
altruism
altruism's
altruistic
aluminium
aluminium's
alumna
alumna's
alumnae
alumni
alumnus
alumnus's
always
am
amalgamate
amalgamated
amalgamates
amalgamating
amalgamation
amalgamation's
amalgamations
amass
amassed
amasses
amassing
amateur
amateur's
amateurish
amateurs
amaze
amazed
amazement
amazement's
amazes
amazing
amazingly
ambassador
ambassador's
ambassadorial
ambassadors
amber
amber's
ambiance
ambiance's
ambiances
ambidextrous
ambience
ambience's
ambiences
ambient
ambiguities
ambiguity
ambiguity's
ambiguous
ambiguously
ambition
ambition's
ambitions
ambitious
ambitiously
ambivalence
ambivalence's
ambivalent
amble
ambled
ambles
ambling
ambulance
ambulance's
ambulances
ambush
ambush's
ambushed
ambushes
ambushing
ameba
ameba's
amebae
amebas
ameliorate
ameliorated
ameliorates
ameliorating
amelioration
amelioration's
amen
amenable
amend
amended
amending
amendment
amendment's
amendments
amends
amends's
amened
amening
amenities
amenity
amenity's
amens
amethyst
amethyst's
amethysts
amiable
amiably
amicable
amicably
amid
amids
amidst
amiss
ammo
ammo's
ammonia
ammonia's
ammunition
ammunition's
amnesia
amnesia's
amnesiac
amnesiac's
amnesiacs
amnestied
amnesties
amnesty
amnesty's
amnestying
amoeba
amoeba's
amoebae
amoebas
amok
amok's
among
amongst
amoral
amorous
amorphous
amount
amount's
amounted
amounting
amounts
amp
amp's
amped
ampere
ampere's
amperes
ampersand
ampersand's
ampersands
amphetamine
amphetamine's
amphetamines
amphibian
amphibian's
amphibians
amphibious
amphitheatre
amphitheatre's
amphitheatres
amping
ample
ampler
amplest
amplification
amplification's
amplifications
amplified
amplifier
amplifier's
amplifiers
amplifies
amplify
amplifying
amplitude
amplitude's
amply
amps
amputate
amputated
amputates
amputating
amputation
amputation's
amputations
amputee
amputee's
amputees
amuck
amuck's
amulet
amulet's
amulets
amuse
amused
amusement
amusement's
amusements
amuses
amusing
amusingly
an
anachronism
anachronism's
anachronisms
anachronistic
anaemia
anaemia's
anaemic
anaesthesia
anaesthesia's
anaesthesiologist
anaesthesiologist's
anaesthesiologists
anaesthetic
anaesthetic's
anaesthetics
anaesthetise
anaesthetised
anaesthetises
anaesthetising
anaesthetist
anaesthetist's
anaesthetists
anaesthetize
anaesthetized
anaesthetizes
anaesthetizing
anagram
anagram's
anagrams
anal
analgesic
analgesics
analogies
analogous
analogue
analogue's
analogy
analogy's
analyse
analysed
analyser
analyser's
analyses
analysing
analysis
analysis's
analyst
analyst's
analysts
analytic
analytical
analytics
anarchic
anarchism
anarchism's
anarchist
anarchist's
anarchists
anarchy
anarchy's
anathema
anathema's
anatomical
anatomies
anatomy
anatomy's
ancestor
ancestor's
ancestored
ancestoring
ancestors
ancestral
ancestries
ancestry
ancestry's
anchor
anchor's
anchorage
anchorage's
anchorages
anchored
anchoring
anchorman
anchorman's
anchormen
anchors
anchorwoman
anchorwomen
anchovies
anchovy
anchovy's
ancient
ancienter
ancientest
ancients
and
android
android's
androids
ands
anecdota
anecdotal
anecdote
anecdote's
anecdotes
anew
angel
angel's
angelic
angelically
angels
anger
anger's
angered
angering
angers
angle
angle's
angled
angler
angler's
anglers
angles
angling
angling's
angrier
angriest
angrily
angry
angst
angst's
anguish
anguish's
anguished
anguishes
anguishing
angular
ani
animal
animal's
animals
animate
animated
animates
animating
animation
animation's
animations
animosities
animosity
animosity's
ankle
ankle's
ankled
ankles
ankling
annals
annex
annexation
annexation's
annexations
annexe
annexed
annexes
annexing
annihilate
annihilated
annihilates
annihilating
annihilation
annihilation's
anniversaries
anniversary
anniversary's
annotate
annotated
annotates
annotating
annotation
annotation's
annotations
announce
announced
announcement
announcement's
announcements
announcer
announcer's
announcers
announces
announcing
annoy
annoyance
annoyance's
annoyances
annoyed
annoying
annoyingly
annoys
annual
annually
annuals
annuities
annuity
annuity's
annul
annulled
annulling
annulment
annulment's
annulments
annuls
anoint
anointed
anointing
anoints
anomalies
anomalous
anomaly
anomaly's
anon
anonymity
anonymity's
anonymous
anonymously
anorak
anoraks
anorexia
anorexia's
anorexic
anorexics
another
answer
answer's
answerable
answered
answering
answers
ant
ant's
antacid
antacid's
antacids
antagonise
antagonised
antagonises
antagonising
antagonism
antagonism's
antagonisms
antagonist
antagonist's
antagonistic
antagonistically
antagonists
ante
ante's
anteater
anteater's
anteaters
antebellum
anted
anteed
anteing
antelope
antelope's
antelopes
antenna
antenna's
antennae
antennas
antes
anthem
anthem's
anthems
anthill
anthills
anthologies
anthology
anthology's
anthrax
anthrax's
anthropological
anthropologist
anthropologist's
anthropologists
anthropology
anthropology's
antibiotic
antibiotic's
antibiotics
antibodies
antibody
antibody's
antic
anticipate
anticipated
anticipates
anticipating
anticipation
anticipation's
anticipations
anticlimactic
anticlimax
anticlimax's
anticlimaxes
antics
antidote
antidote's
antidotes
antifreeze
antifreeze's
antihistamine
antihistamine's
antihistamines
anting
antipathies
antipathy
antipathy's
antiperspirant
antiperspirant's
antiperspirants
antiquate
antiquated
antiquates
antiquating
antique
antique's
antiqued
antiques
antiquing
antiquities
antiquity
antiquity's
antiseptic
antiseptics
antisocial
antitheses
antithesis
antithesis's
antitrust
antitrust's
antler
antler's
antlers
antonym
antonym's
antonyms
ants
anus
anus's
anuses
anvil
anvil's
anvilled
anvilling
anvils
anxieties
anxiety
anxiety's
anxious
anxiously
any
anybodies
anybody
anyhow
anymore
anyone
anyplace
anything
anythings
anytime
anyway
anyways
anywhere
anywheres
aorta
aorta's
aortae
aortas
apart
apartheid
apartheid's
apartment
apartment's
apartments
apathetic
apathy
apathy's
ape
ape's
aped
aperitif
aperitifs
aperture
aperture's
apertures
apes
apex
apex's
apexes
aphorism
aphorism's
aphorisms
aphrodisiac
aphrodisiac's
aphrodisiacs
apices
apiece
aping
aplomb
aplomb's
apocalypse
apocalypse's
apocalypses
apocalyptic
apocryphal
apolitical
apologetic
apologetically
apologetics
apologies
apologise
apologised
apologises
apologising
apology
apology's
apoplectic
apoplexies
apoplexy
apoplexy's
apostle
apostle's
apostles
apostolic
apostrophe
apostrophe's
apostrophes
appal
appalled
appalling
appallingly
appals
apparatus
apparatus's
apparatuses
apparel
apparel's
apparelled
apparelling
apparels
apparent
apparently
apparition
apparition's
apparitions
appeal
appeal's
appealed
appealing
appeals
appear
appearance
appearance's
appearances
appeared
appearing
appears
appease
appeased
appeasement
appeasement's
appeasements
appeases
appeasing
append
appendage
appendage's
appendages
appended
appendices
appendicitis
appendicitis's
appending
appendix
appendix's
appendixes
appends
appetiser
appetiser's
appetisers
appetising
appetite
appetite's
appetites
applaud
applauded
applauding
applauds
applause
applause's
apple
apple's
apples
applesauce
applesauce's
appliance
appliance's
appliances
applicability
applicability's
applicable
applicant
applicant's
applicants
application
application's
applications
applicator
applicator's
applicators
applied
applies
apply
applying
appoint
appointed
appointee
appointee's
appointees
appointing
appointment
appointment's
appointments
appoints
apportion
apportioned
apportioning
apportions
apposite
appraisal
appraisal's
appraisals
appraise
appraised
appraises
appraising
appreciable
appreciate
appreciated
appreciates
appreciating
appreciation
appreciation's
appreciations
appreciative
appreciatively
apprehend
apprehended
apprehending
apprehends
apprehension
apprehension's
apprehensions
apprehensive
apprentice
apprentice's
apprenticed
apprentices
apprenticeship
apprenticeship's
apprenticeships
apprenticing
apprise
apprised
apprises
apprising
approach
approachable
approached
approaches
approaching
approbation
approbation's
approbations
appropriate
appropriated
appropriately
appropriates
appropriating
appropriation
appropriation's
appropriations
approval
approval's
approvals
approve
approved
approves
approving
approvingly
approximate
approximated
approximately
approximates
approximating
approximation
approximation's
approximations
apricot
apricot's
apricots
apron
apron's
aprons
apt
apter
aptest
aptitude
aptitude's
aptitudes
aptly
aquamarine
aquamarine's
aquamarines
aquaria
aquarium
aquarium's
aquariums
aquatic
aquatics
aqueduct
aqueduct's
aqueducts
arable
arbiter
arbiter's
arbiters
arbitrarily
arbitrary
arbitrate
arbitrated
arbitrates
arbitrating
arbitration
arbitration's
arbitrator
arbitrator's
arbitrators
arbores
arbour
arbour's
arboures
arbours
arc
arc's
arcade
arcade's
arcades
arcane
arced
arch
arch's
archaeological
archaeologist
archaeologist's
archaeologists
archaeology
archaeology's
archaic
archbishop
archbishop's
archbishops
arched
archeology
archer
archer's
archers
archery
archery's
arches
archest
archetypal
arching
archipelago
archipelago's
archipelagoes
archipelagos
architect
architect's
architects
architectural
architecture
architecture's
architectures
archive
archive's
archived
archives
archiving
archway
archway's
archways
arcing
arcked
arcking
arcs
arctic
arctics
ardent
ardently
ardour
ardour's
ardours
arduous
arduously
are
area
area's
areas
aren't
arena
arena's
arenas
ares
arguable
arguably
argue
argued
argues
arguing
argument
argument's
argumentative
arguments
aria
aria's
arias
arid
arider
aridest
arise
arisen
arises
arising
aristocracies
aristocracy
aristocracy's
aristocrat
aristocrat's
aristocratic
aristocrats
arithmetic
arithmetic's
ark
ark's
arks
arm
arm's
armadillo
armadillo's
armadillos
armament
armament's
armaments
armband
armband's
armbands
armchair
armchair's
armchairs
armed
armful
armful's
armfuls
armhole
armhole's
armholes
armies
arming
armistice
armistice's
armistices
armour
armour's
armoured
armouries
armouring
armours
armoury
armoury's
armpit
armpit's
armpits
arms
armsful
army
army's
aroma
aroma's
aromas
aromatic
aromatics
arose
around
arousal
arousal's
arouse
aroused
arouses
arousing
arraign
arraigned
arraigning
arraignment
arraignment's
arraignments
arraigns
arrange
arranged
arrangement
arrangement's
arrangements
arranges
arranging
array
array's
arrayed
arraying
arrays
arrears
arrest
arrested
arresting
arrests
arrival
arrival's
arrivals
arrive
arrived
arrives
arriving
arrogance
arrogance's
arrogant
arrogantly
arrow
arrow's
arrows
arse
arse's
arsehole
arseholes
arsenal
arsenal's
arsenals
arsenic
arsenic's
arses
arson
arson's
arsonist
arsonist's
arsonists
art
art's
artefact
artefacts
arterial
arteries
artery
artery's
artful
arthritic
arthritics
arthritis
arthritis's
artichoke
artichoke's
artichokes
article
article's
articles
articulate
articulated
articulately
articulates
articulating
articulation
articulation's
articulations
artifact
artifact's
artifacts
artifice
artifice's
artifices
artificial
artificially
artillery
artillery's
artisan
artisan's
artisans
artist
artist's
artistic
artistically
artistry
artistry's
artists
arts
artsier
artsiest
artsy
artwork
artwork's
artworks
as
asbestos
asbestos's
ascend
ascendancy
ascendancy's
ascended
ascending
ascends
ascension
ascension's
ascensions
ascent
ascent's
ascents
ascertain
ascertained
ascertaining
ascertains
ascetic
ascetic's
ascetics
ascribe
ascribed
ascribes
ascribing
asexual
ash
ash's
ashamed
ashcan
ashcan's
ashed
ashen
ashes
ashing
ashore
ashtray
ashtray's
ashtrays
aside
asides
ask
askance
asked
askew
asking
asks
asleep
asparagus
asparagus's
aspect
aspect's
aspects
aspen
aspen's
aspens
aspersion
aspersion's
aspersions
asphalt
asphalt's
asphalted
asphalting
asphalts
asphyxiate
asphyxiated
asphyxiates
asphyxiating
asphyxiation
asphyxiation's
asphyxiations
aspirant
aspirant's
aspirants
aspiration
aspiration's
aspirations
aspire
aspired
aspires
aspirin
aspirin's
aspiring
aspirins
ass
ass's
assail
assailant
assailant's
assailants
assailed
assailing
assails
assassin
assassin's
assassinate
assassinated
assassinates
assassinating
assassination
assassination's
assassinations
assassins
assault
assault's
assaulted
assaulter
assaulting
assaults
assemble
assembled
assembler
assembler's
assemblers
assembles
assemblies
assembling
assembly
assembly's
assemblyman
assemblyman's
assemblymen
assemblywoman
assemblywomen
assent
assent's
assented
assenting
assents
assert
asserted
asserting
assertion
assertion's
assertions
assertive
assertively
assertiveness
assertiveness's
asserts
asses
assess
assessed
assesses
assessing
assessment
assessment's
assessments
assessor
assessor's
assessors
asset
asset's
assets
assign
assigned
assigning
assignment
assignment's
assignments
assigns
assimilate
assimilated
assimilates
assimilating
assimilation
assimilation's
assist
assistance
assistance's
assistant
assistant's
assistants
assisted
assisting
assists
associate
associated
associates
associating
association
association's
associations
associative
assort
assorted
assorting
assortment
assortment's
assortments
assorts
assume
assumed
assumes
assuming
assumption
assumption's
assumptions
assurance
assurance's
assurances
assure
assured
assuredly
assureds
assures
assuring
asterisk
asterisk's
asterisked
asterisking
asterisks
asteroid
asteroid's
asteroids
asthma
asthma's
asthmatic
asthmatics
astonish
astonished
astonishes
astonishing
astonishingly
astonishment
astonishment's
astound
astounded
astounding
astounds
astray
astride
astringent
astringents
astrologer
astrologer's
astrologers
astrological
astrology
astrology's
astronaut
astronaut's
astronauts
astronomer
astronomer's
astronomers
astronomical
astronomy
astronomy's
astute
astutely
astuter
astutest
asylum
asylum's
asylums
asymmetry
asymmetry's
asynchronous
asynchronously
at
ate
ates
atheism
atheism's
atheist
atheist's
atheistic
atheists
athlete
athlete's
athletes
athletic
athletics
athletics's
atlantes
atlas
atlas's
atlases
atmosphere
atmosphere's
atmospheres
atmospheric
atmospherics
atom
atom's
atomic
atomics
atoms
atone
atoned
atonement
atonement's
atones
atoning
atrocious
atrociously
atrocities
atrocity
atrocity's
attach
attach's
attached
attaching
attachment
attachment's
attachments
attach
attachs
attack
attacked
attacker
attacker's
attackers
attacking
attacks
attain
attainable
attained
attaining
attainment
attainment's
attainments
attains
attempt
attempted
attempting
attempts
attend
attendance
attendance's
attendances
attendant
attendant's
attendants
attended
attending
attends
attention
attention's
attentions
attentive
attentively
attest
attested
attesting
attests
attic
attic's
attics
attire
attired
attires
attiring
attitude
attitude's
attitudes
attorney
attorney's
attorneys
attract
attracted
attracting
attraction
attraction's
attractions
attractive
attractively
attractiveness
attractiveness's
attracts
attributable
attribute
attributed
attributes
attributing
attribution
attribution's
attributions
attune
attuned
attunes
attuning
auburn
auburn's
auction
auction's
auctioned
auctioneer
auctioneer's
auctioneers
auctioning
auctions
audacious
audacity
audacity's
audible
audibles
audibly
audience
audience's
audiences
audio
audio's
audios
audiovisual
audit
audit's
audited
auditing
audition
audition's
auditioned
auditioning
auditions
auditor
auditor's
auditoria
auditorium
auditorium's
auditoriums
auditors
auditory
audits
augment
augmented
augmenting
augments
august
auguster
augustest
augusts
aunt
aunt's
aunts
aura
aura's
aurae
aural
auras
auspice
auspices
auspicious
austere
austerer
austerest
austerities
austerity
austerity's
authentic
authentically
authenticate
authenticated
authenticates
authenticating
authenticity
authenticity's
author
author's
authored
authoring
authorisation
authorisation's
authorisations
authorise
authorised
authorises
authorising
authoritarian
authoritarians
authoritative
authoritatively
authorities
authority
authority's
authors
authorship
authorship's
autistic
autistics
auto
auto's
autobiographical
autobiographies
autobiography
autobiography's
autocracies
autocracy
autocracy's
autocrat
autocrat's
autocratic
autocrats
autoed
autograph
autograph's
autographed
autographing
autographs
autoing
automate
automated
automates
automatic
automatically
automatics
automating
automation
automation's
automobile
automobile's
automobiled
automobiles
automobiling
automotive
autonomous
autonomously
autonomy
autonomy's
autopsied
autopsies
autopsy
autopsy's
autopsying
autos
autoworker
autoworkers
autumn
autumn's
autumnal
autumns
auxiliaries
auxiliary
avail
availability
availability's
available
availed
availing
avails
avalanche
avalanche's
avalanches
avarice
avarice's
avaricious
avenge
avenged
avenges
avenging
avenue
avenue's
avenues
average
average's
averaged
averages
averaging
averse
aversion
aversion's
aversions
avert
averted
averting
averts
aviation
aviation's
aviator
aviator's
aviators
avid
avider
avidest
avidly
avocado
avocado's
avocadoes
avocados
avoid
avoidable
avoidance
avoidance's
avoided
avoiding
avoids
avow
avowal
avowal's
avowals
avowed
avowing
avows
await
awaited
awaiting
awaits
awake
awaked
awaken
awakened
awakening
awakenings
awakens
awakes
awaking
award
awarded
awarding
awards
aware
awareness
awareness's
awarer
awarest
awash
away
aways
awe
awe's
awed
awes
awesome
awful
awfuller
awfullest
awfully
awhile
awing
awkward
awkwarder
awkwardest
awkwardly
awkwardness
awkwardness's
awning
awning's
awnings
awoke
awoken
awry
axe
axe's
axed
axes
axing
axiom
axiom's
axiomatic
axiomatics
axioms
axis
axis's
axises
axle
axle's
axles
ay
aye
aye's
ayes
azalea
azalea's
azaleas
azure
azure's
azures
b
baa
baaed
baaing
baas
babble
babbled
babbles
babbling
babe
babe's
babes
babied
babier
babies
babiest
baboon
baboon's
baboons
baby
baby's
babying
babyish
babysat
babysit
babysits
babysitter
babysitters
babysitting
bachelor
bachelor's
bachelors
back
back's
backbone
backbone's
backbones
backbreaking
backdrop
backdrop's
backdrops
backed
backer
backer's
backers
backfire
backfired
backfires
backfiring
backgammon
backgammon's
background
background's
backgrounds
backhand
backhand's
backhanded
backhanding
backhands
backing
backing's
backings
backlash
backlash's
backlashes
backlog
backlog's
backlogged
backlogging
backlogs
backpack
backpack's
backpacked
backpacker
backpacker's
backpackers
backpacking
backpacks
backs
backside
backside's
backsides
backslash
backspace
backstage
backstroke
backstroke's
backstroked
backstrokes
backstroking
backtrack
backtracked
backtracking
backtracks
backup
backup's
backups
backward
backwards
backwoods
backyard
backyard's
backyards
bacon
bacon's
bacteria
bacterial
bacterias
bacterium
bad
badder
baddest
bade
badge
badge's
badger
badger's
badgered
badgering
badgers
badges
badlands
badly
badminton
badminton's
badmouth
badmouthed
badmouthing
badmouths
badness
badness's
baffle
baffled
baffles
baffling
bag
bag's
bagel
bagel's
bagels
baggage
baggage's
bagged
baggie
baggier
baggies
baggiest
bagging
baggy
bagpipe
bagpipes
bags
bail
bail's
bailed
bailiff
bailiff's
bailiffs
bailing
bails
bait
bait's
baited
baiting
baits
bake
baked
baker
baker's
bakeries
bakers
bakery
bakery's
bakes
baking
balance
balance's
balanced
balances
balancing
balconies
balcony
balcony's
bald
balded
balder
baldest
balding
baldness
baldness's
balds
bale
bale's
baled
baleful
balefuller
balefullest
bales
baling
balk
balked
balking
balks
ball
ball's
ballad
ballad's
ballads
ballast
ballast's
ballasted
ballasting
ballasts
balled
ballerina
ballerina's
ballerinas
ballet
ballet's
ballets
balling
ballistic
ballistics
ballistics's
balloon
balloon's
ballooned
ballooning
balloons
ballot
ballot's
balloted
balloting
ballots
ballpark
ballpark's
ballparks
ballroom
ballroom's
ballrooms
balls
balm
balm's
balmier
balmiest
balms
balmy
baloney
baloney's
bamboo
bamboo's
bamboos
bamboozle
bamboozled
bamboozles
bamboozling
ban
banal
banaler
banalest
banalities
banality
banality's
banana
banana's
bananas
band
band's
bandage
bandage's
bandaged
bandages
bandaging
bandanna
bandanna's
bandannas
banded
bandied
bandier
bandies
bandiest
banding
bandit
bandit's
bandits
banditti
bands
bandstand
bandstand's
bandstands
bandwagon
bandwagon's
bandwagons
bandwidth
bandwidth's
bandy
bandying
bane
bane's
baned
banes
bang
bang's
banged
banging
bangle
bangle's
bangles
bangs
bani
baning
banish
banished
banishes
banishing
banister
banister's
banisters
banjo
banjo's
banjoes
banjos
bank
bank's
banked
banker
banker's
bankers
banking
banking's
banknote
banknotes
bankrupt
bankrupt's
bankruptcies
bankruptcy
bankruptcy's
bankrupted
bankrupting
bankrupts
banks
banned
banner
banner's
bannered
bannering
banners
banning
banquet
banquet's
banqueted
banqueting
banquets
bans
banter
bantered
bantering
banters
baptise
baptised
baptises
baptising
baptism
baptism's
baptismal
baptisms
bar
bar's
barb
barb's
barbarian
barbarian's
barbarians
barbaric
barbarism
barbarism's
barbarisms
barbarous
barbecue
barbecue's
barbecued
barbecues
barbecuing
barbed
barbell
barbell's
barbells
barber
barber's
barbered
barbering
barbers
barbing
barbiturate
barbiturate's
barbiturates
barbs
bard
bard's
bards
bare
bareback
bared
barefoot
barely
barer
bares
barest
barf
barfed
barfing
barfs
bargain
bargain's
bargained
bargainer
bargaining
bargains
barge
barge's
barged
barges
barging
baring
baritone
baritone's
baritones
bark
bark's
barked
barking
barks
barley
barley's
barman
barman's
barn
barn's
barnacle
barnacle's
barnacles
barns
barnyard
barnyard's
barnyards
barometer
barometer's
barometers
barometric
baron
baron's
barons
baroque
baroque's
barrack
barracks
barrage
barrage's
barraged
barrages
barraging
barred
barrel
barrel's
barrelled
barrelling
barrels
barren
barrener
barrenest
barrens
barrette
barrette's
barrettes
barricade
barricade's
barricaded
barricades
barricading
barrier
barrier's
barriers
barring
barrings
barrio
barrio's
barrios
barrister
barrister's
barristers
barroom
barroom's
barrooms
bars
bartender
bartender's
bartenders
barter
bartered
bartering
barters
base
base's
baseball
baseball's
baseballs
based
baseline
baseline's
basement
basement's
basements
baser
bases
basest
bash
bashed
bashes
bashful
bashing
basic
basically
basics
basil
basil's
basin
basin's
basing
basins
basis
basis's
bask
basked
basket
basket's
basketball
basketball's
basketballs
baskets
basking
basks
bass
bass's
basses
bassist
bassist's
bassists
bassoon
bassoon's
bassoons
bastard
bastard's
bastards
baste
basted
bastes
basting
bat
bat's
batch
batch's
batched
batches
batching
bate
bated
bates
bath
bath's
bathe
bathed
bathes
bathing
bathrobe
bathrobe's
bathrobes
bathroom
bathroom's
bathrooms
baths
bathtub
bathtub's
bathtubs
bating
baton
baton's
batons
bats
batsman
batsman's
battalion
battalion's
battalions
batted
batter
battered
batteries
battering
batters
battery
battery's
batting
batting's
battle
battle's
battled
battlefield
battlefield's
battlefields
battleground
battlegrounds
battles
battleship
battleship's
battleships
battling
baud
baud's
bauds
bawdier
bawdiest
bawdy
bawl
bawled
bawling
bawls
bay
bay's
bayed
baying
bayonet
bayonet's
bayoneted
bayoneting
bayonets
bayonetted
bayonetting
bayou
bayou's
bayous
bays
bazaar
bazaar's
bazaars
be
beach
beach's
beached
beaches
beaching
beacon
beacon's
beacons
bead
bead's
beaded
beadier
beadiest
beading
beads
beady
beagle
beagle's
beagled
beagles
beagling
beak
beak's
beaked
beaker
beaker's
beakers
beaks
beam
beam's
beamed
beaming
beams
bean
bean's
beaned
beaning
beans
bear
bearable
beard
beard's
bearded
bearding
beards
bearer
bearer's
bearers
bearing
bearing's
bearings
bears
beast
beast's
beasts
beat
beaten
beater
beater's
beaters
beating
beating's
beatings
beats
beautician
beautician's
beauticians
beauties
beautified
beautifies
beautiful
beautifuler
beautifulest
beautifully
beautify
beautifying
beauty
beauty's
beaver
beaver's
beavered
beavering
beavers
bebop
bebop's
bebops
became
because
beckon
beckoned
beckoning
beckons
become
becomes
becoming
becomings
bed
bed's
bedbug
bedbug's
bedbugs
bedclothes
bedded
bedder
bedder's
bedding
bedding's
bedlam
bedlam's
bedlams
bedpan
bedpan's
bedpans
bedraggle
bedraggled
bedraggles
bedraggling
bedridden
bedrock
bedrock's
bedrocks
bedroom
bedroom's
bedrooms
beds
bedside
bedside's
bedsides
bedspread
bedspread's
bedspreads
bedtime
bedtime's
bedtimes
bee
bee's
beech
beech's
beeches
beef
beef's
beefed
beefier
beefiest
beefing
beefs
beefy
beehive
beehive's
beehives
beeline
beeline's
beelined
beelines
beelining
been
beep
beep's
beeped
beeper
beeper's
beepers
beeping
beeps
beer
beer's
beers
bees
beeswax
beeswax's
beet
beet's
beetle
beetle's
beetled
beetles
beetling
beets
beeves
befall
befallen
befalling
befalls
befell
befit
befits
befitted
befitting
before
beforehand
befriend
befriended
befriending
befriends
beg
began
beggar
beggar's
beggared
beggaring
beggars
begged
begging
begin
beginner
beginner's
beginners
beginning
beginning's
beginnings
begins
begrudge
begrudged
begrudges
begrudging
begs
beguile
beguiled
beguiles
beguiling
begun
behalf
behalf's
behalves
behave
behaved
behaves
behaving
behaviour
behaviour's
behavioural
behead
beheaded
beheading
beheads
beheld
behind
behinds
behold
beholder
beholder's
beholders
beholding
beholds
beige
beige's
being
being's
beings
belabour
belaboured
belabouring
belabours
belated
belatedly
belch
belched
belches
belching
belfries
belfry
belfry's
belie
belied
belief
belief's
beliefs
belies
believable
believe
believed
believer
believer's
believers
believes
believing
belittle
belittled
belittles
belittling
bell
bell's
bellboy
bellboy's
bellboys
belled
bellhop
bellhop's
bellhops
bellied
bellies
belligerence
belligerence's
belligerent
belligerents
belling
bellow
bellowed
bellowing
bellows
bellows's
bells
belly
belly's
bellybutton
bellybutton's
bellybuttons
bellying
belong
belonged
belonging
belonging's
belongings
belongs
beloved
beloveds
below
belows
belt
belt's
belted
belting
belts
beltway
beltway's
beltways
belying
bemoan
bemoaned
bemoaning
bemoans
bemuse
bemused
bemuses
bemusing
bench
bench's
benched
benches
benching
benchmark
benchmark's
benchmarks
bend
bender
bender's
bending
bends
beneath
benediction
benediction's
benedictions
benefactor
benefactor's
benefactors
beneficial
beneficiaries
beneficiary
beneficiary's
benefit
benefit's
benefited
benefiting
benefits
benefitted
benefitting
benevolence
benevolence's
benevolences
benevolent
benighted
benign
bent
bents
bequeath
bequeathed
bequeathing
bequeaths
bequest
bequest's
bequests
berate
berated
berates
berating
bereave
bereaved
bereavement
bereavement's
bereavements
bereaves
bereaving
bereft
beret
beret's
berets
berried
berries
berry
berry's
berrying
berserk
berth
berth's
berthed
berthing
berths
beseech
beseeched
beseeches
beseeching
beset
besets
besetting
beside
besides
besiege
besieged
besieges
besieging
besought
best
bested
bestial
bestiality
bestiality's
besting
bestow
bestowed
bestowing
bestows
bests
bestseller
bestsellers
bet
bet's
beta
beta's
betcha
betray
betrayal
betrayal's
betrayals
betrayed
betraying
betrays
betrothal
betrothal's
betrothals
bets
betted
better
bettered
bettering
betterment
betterment's
betters
betting
bettor
bettor's
bettors
between
bevel
bevelled
bevelling
bevels
beverage
beverage's
beverages
beware
bewared
bewares
bewaring
bewilder
bewildered
bewildering
bewilderment
bewilderment's
bewilders
bewitch
bewitched
bewitches
bewitching
beyond
beyonds
bias
bias's
biased
biases
biasing
biassed
biassing
bib
bib's
bible
bibles
biblical
bibliographic
bibliographies
bibliography
bibliography's
bibs
bicentennial
bicentennials
bicep
biceps
biceps's
bicepses
bicker
bickered
bickering
bickering's
bickers
bicycle
bicycle's
bicycled
bicycles
bicycling
bid
bidden
bidder
bidders
bidding
bidding's
bide
bided
bides
biding
bids
biennial
biennials
bifocals
big
bigamist
bigamist's
bigamists
bigamous
bigamy
bigamy's
bigger
biggest
biggie
biggie's
biggies
bigmouth
bigmouth's
bigmouths
bigot
bigot's
bigoted
bigotries
bigotry
bigotry's
bigots
bigwig
bigwig's
bigwigs
bike
bike's
biked
biker
bikers
bikes
biking
bikini
bikini's
bikinis
bilateral
bilaterally
bile
bile's
bilingual
bilinguals
bill
bill's
billboard
billboard's
billboards
billed
billfold
billfold's
billfolds
billiards
billing
billion
billion's
billionaire
billionaire's
billionaires
billions
billionth
billionths
billow
billow's
billowed
billowing
billows
bills
bimbo
bimbo's
bimboes
bimbos
bimonthlies
bimonthly
bin
bin's
binaries
binary
bind
binder
binder's
binders
binding
binding's
bindings
binds
binge
binge's
binged
bingeing
binges
binging
bingo
bingo's
binned
binning
binocular
binoculars
binomial
binomial's
bins
biochemical
biochemistry
biochemistry's
biodegradable
biographer
biographer's
biographers
biographical
biographies
biography
biography's
biological
biologically
biologist
biologist's
biologists
biology
biology's
biopsied
biopsies
biopsy
biopsy's
biopsying
bipartisan
biped
biped's
bipeds
biplane
biplane's
biplanes
birch
birch's
birched
birches
birching
bird
bird's
birdbrained
birdcage
birdcage's
birdcages
birded
birding
birds
birdseed
birdseed's
birth
birth's
birthday
birthday's
birthdays
birthed
birthing
birthmark
birthmark's
birthmarks
birthplace
birthplace's
birthplaces
birthrate
birthrates
births
biscuit
biscuit's
biscuits
bisect
bisected
bisecting
bisection
bisection's
bisections
bisects
bisexual
bisexuals
bishop
bishop's
bishops
bison
bison's
bisons
bit
bit's
bitch
bitch's
bitched
bitches
bitchier
bitchiest
bitching
bitchy
bite
bites
biting
bitings
bitmap
bits
bitten
bitter
bitterer
bitterest
bitterly
bitterness
bitterness's
bittersweet
bittersweet's
bittersweets
biweeklies
biweekly
bizarre
bizarres
blab
blabbed
blabbermouth
blabbermouth's
blabbermouths
blabbing
blabs
black
blackberries
blackberry
blackberry's
blackberrying
blackbird
blackbird's
blackbirds
blackboard
blackboard's
blackboards
blacked
blacken
blackened
blackening
blackens
blacker
blackest
blackhead
blackhead's
blackheads
blacking
blackjack
blackjack's
blackjacked
blackjacking
blackjacks
blacklist
blacklist's
blacklisted
blacklisting
blacklists
blackmail
blackmail's
blackmailed
blackmailer
blackmailer's
blackmailers
blackmailing
blackmails
blackness
blackness's
blackout
blackout's
blackouts
blacks
blacksmith
blacksmith's
blacksmiths
blacktop
blacktop's
blacktopped
blacktopping
blacktops
bladder
bladder's
bladders
blade
blade's
bladed
blades
blading
blah
blah's
blahed
blahing
blahs
blame
blame's
blamed
blameless
blamer
blames
blaming
blanch
blanched
blanches
blanching
blancmange
blancmange's
bland
blander
blandest
blandly
blank
blanked
blanker
blankest
blanket
blanket's
blanketed
blanketing
blankets
blanking
blankly
blankness
blankness's
blanks
blare
blared
blares
blaring
blaspheme
blasphemed
blasphemes
blasphemies
blaspheming
blasphemous
blasphemy
blasphemy's
blast
blast's
blasted
blaster
blaster's
blasting
blastoff
blastoff's
blastoffs
blasts
blas
blatant
blatantly
blaze
blaze's
blazed
blazer
blazer's
blazers
blazes
blazing
bleach
bleached
bleacher
bleachers
bleaches
bleaching
bleak
bleaker
bleakest
bleakly
bleakness
bleakness's
blearier
bleariest
blearily
bleary
bleat
bleated
bleating
bleats
bled
bleed
bleeding
bleeds
blemish
blemish's
blemished
blemishes
blemishing
blend
blended
blender
blender's
blenders
blending
blends
blent
bless
blessed
blesseder
blessedest
blesses
blessing
blessing's
blessings
blest
blew
blight
blight's
blighted
blighting
blights
blimp
blimp's
blimps
blind
blinded
blinder
blindest
blindfold
blindfolded
blindfolding
blindfolds
blinding
blinding's
blindingly
blindly
blindness
blindness's
blinds
blink
blinked
blinker
blinkered
blinkering
blinkers
blinking
blinks
blip
blip's
blips
bliss
bliss's
blissed
blisses
blissful
blissfully
blissing
blister
blister's
blistered
blistering
blisters
blithe
blithely
blither
blithest
blitz
blitz's
blitzed
blitzes
blitzing
blizzard
blizzard's
blizzards
bloat
bloated
bloating
bloats
blob
blob's
blobbed
blobbing
blobs
bloc
bloc's
block
block's
blockade
blockade's
blockaded
blockades
blockading
blockage
blockage's
blockages
blockbuster
blockbuster's
blockbusters
blocked
blockhead
blockhead's
blockheads
blocking
blocks
blocs
blond
blonde
blonde's
blonder
blondes
blondest
blonds
blood
blood's
bloodbath
bloodbaths
blooded
bloodhound
bloodhound's
bloodhounds
bloodied
bloodier
bloodies
bloodiest
blooding
bloodless
bloods
bloodshed
bloodshed's
bloodshot
bloodstain
bloodstain's
bloodstained
bloodstains
bloodstream
bloodstream's
bloodstreams
bloodthirstier
bloodthirstiest
bloodthirsty
bloody
bloodying
bloom
bloom's
bloomed
blooming
blooms
blooper
blooper's
bloopers
blossom
blossom's
blossomed
blossoming
blossoms
blot
blot's
blotch
blotch's
blotched
blotches
blotchier
blotchiest
blotching
blotchy
blots
blotted
blotter
blotter's
blotters
blotting
blouse
blouse's
bloused
blouses
blousing
blow
blowing
blowing's
blown
blowout
blowout's
blowouts
blows
blowtorch
blowtorch's
blowtorches
blowup
blowup's
blowups
blubber
blubbered
blubbering
blubbers
bludgeon
bludgeon's
bludgeoned
bludgeoning
bludgeons
blue
blue's
bluebell
bluebell's
bluebells
blueberries
blueberry
blueberry's
bluebird
bluebird's
bluebirds
blued
bluegrass
bluegrass's
blueing
blueprint
blueprint's
blueprinted
blueprinting
blueprints
bluer
blues
bluest
bluff
bluffed
bluffer
bluffest
bluffing
bluffs
bluing
bluish
blunder
blunder's
blundered
blundering
blunders
blunt
blunted
blunter
bluntest
blunting
bluntly
bluntness
bluntness's
blunts
blur
blurb
blurb's
blurbs
blurred
blurrier
blurriest
blurring
blurry
blurs
blurt
blurted
blurting
blurts
blush
blushed
blusher
blusher's
blushers
blushes
blushing
bluster
blustered
blustering
blusters
boa
boa's
boar
boar's
board
board's
boarded
boarder
boarder's
boarders
boarding
boarding's
boardinghouse
boardinghouse's
boardinghouses
boardroom
boardroom's
boardrooms
boards
boardwalk
boardwalk's
boardwalks
boars
boas
boast
boasted
boastful
boastfully
boasting
boasts
boat
boat's
boated
boating
boats
bob
bobbed
bobbin
bobbin's
bobbing
bobbins
bobcat
bobcat's
bobcats
bobs
bobsled
bobsled's
bobsledded
bobsledding
bobsleds
bode
boded
bodes
bodice
bodice's
bodices
bodies
bodily
boding
body
body's
bodybuilding
bodyguard
bodyguard's
bodyguards
bodywork
bodywork's
bog
bog's
bogeyman
bogeyman's
bogeymen
bogged
bogging
boggle
boggled
boggles
boggling
bogs
bogus
bohemian
bohemians
boil
boiled
boiler
boiler's
boilers
boiling
boilings
boils
boisterous
bold
bolder
boldest
boldly
boldness
boldness's
bolds
bologna
bologna's
bolster
bolstered
bolstering
bolsters
bolt
bolt's
bolted
bolting
bolts
bomb
bombard
bombarded
bombarding
bombardment
bombardment's
bombardments
bombards
bombed
bomber
bomber's
bombers
bombing
bombings
bombs
bombshell
bombshell's
bombshells
bonanza
bonanza's
bonanzas
bond
bond's
bondage
bondage's
bonded
bonding
bonds
bone
bone's
boned
bones
boney
boneyer
boneyest
bonfire
bonfire's
bonfires
bongo
bongo's
bongoes
bongos
bonier
boniest
boning
bonkers
bonnet
bonnet's
bonnets
bonus
bonus's
bonuses
bony
boo
boob
boob's
boobed
boobing
boobs
booby
booby's
booed
boogie
boogied
boogieing
boogies
booing
book
book's
bookcase
bookcase's
bookcases
booked
bookend
bookended
bookending
bookends
bookie
bookie's
bookies
booking
booking's
bookings
bookkeeper
bookkeeper's
bookkeepers
bookkeeping
bookkeeping's
booklet
booklet's
booklets
bookmaker
bookmaker's
bookmakers
bookmark
bookmark's
bookmarked
bookmarking
bookmarks
books
bookshelf
bookshelf's
bookshop
bookshops
bookstore
bookstore's
bookstores
bookworm
bookworm's
bookworms
boom
boomed
boomerang
boomerang's
boomeranged
boomeranging
boomerangs
booming
booms
boon
boon's
boondocks
boons
boor
boor's
boorish
boors
boos
boost
boost's
boosted
booster
booster's
boosters
boosting
boosts
boot
boot's
booted
bootee
bootee's
bootees
booth
booth's
booths
bootie
bootie's
booties
booting
bootleg
bootlegged
bootlegger
bootlegger's
bootleggers
bootlegging
bootlegs
boots
bootstrap
bootstrap's
bootstraps
booty
booty's
booze
booze's
boozed
boozer
boozer's
boozers
boozes
boozing
bop
bopped
bopping
bops
border
border's
bordered
bordering
borderline
borderline's
borderlines
borders
bore
bored
boredom
boredom's
bores
boring
boring's
boringly
born
borne
borough
borough's
boroughs
borrow
borrowed
borrower
borrower's
borrowers
borrowing
borrowing's
borrows
bosom
bosom's
bosoms
boss
boss's
bossed
bosser
bosses
bossier
bossiest
bossily
bossiness
bossiness's
bossing
bossy
botanical
botanist
botanist's
botanists
botany
botany's
botch
botched
botches
botching
both
bother
bothered
bothering
bothers
bothersome
bottle
bottle's
bottled
bottleneck
bottleneck's
bottlenecks
bottles
bottling
bottom
bottom's
bottomed
bottoming
bottomless
bottoms
bough
bough's
boughs
bought
boulder
boulder's
bouldered
bouldering
boulders
boulevard
boulevard's
boulevards
bounce
bounced
bouncer
bouncer's
bouncers
bounces
bouncier
bounciest
bouncing
bouncy
bound
boundaries
boundary
boundary's
bounded
bounding
boundless
bounds
bounties
bountiful
bounty
bounty's
bouquet
bouquet's
bouquets
bourbon
bourbon's
bourgeois
bourgeois's
bourgeoisie
bourgeoisie's
bout
bout's
boutique
boutique's
boutiques
bouts
bovine
bovines
bow
bowed
bowel
bowel's
bowels
bowing
bowing's
bowl
bowl's
bowled
bowlegged
bowler
bowler's
bowling
bowling's
bowls
bows
box
box's
boxcar
boxcar's
boxcars
boxed
boxer
boxer's
boxers
boxes
boxing
boxing's
boy
boy's
boycott
boycotted
boycotting
boycotts
boyfriend
boyfriend's
boyfriends
boyhood
boyhood's
boyhoods
boyish
boys
bozo
bozo's
bozos
bra
bra's
brace
brace's
braced
bracelet
bracelet's
bracelets
braces
bracing
bracket
bracket's
bracketed
bracketing
bracketing's
brackets
brackish
brag
braggart
braggart's
braggarts
bragged
bragging
brags
braid
braided
braiding
braids
brain
brain's
brainchild
brainchild's
brainchildren
brained
brainier
brainiest
braining
brainless
brains
brainstorm
brainstorm's
brainstormed
brainstorming
brainstorms
brainwash
brainwashed
brainwashes
brainwashing
brainwashing's
brainy
braise
braised
braises
braising
brake
brake's
braked
brakes
braking
bran
bran's
branch
branch's
branched
branches
branching
branching's
brand
brand's
branded
brandied
brandies
branding
brandish
brandished
brandishes
brandishing
brands
brandy
brandy's
brandying
bras
brash
brasher
brashest
brass
brass's
brassed
brasses
brassier
brassiere
brassiere's
brassieres
brassiest
brassing
brassy
brat
brat's
brats
bravado
bravado's
brave
braved
bravely
braver
bravery
bravery's
braves
bravest
braving
bravo
bravos
brawl
brawl's
brawled
brawling
brawls
brawn
brawn's
brawnier
brawniest
brawny
bray
brayed
braying
brays
brazen
brazened
brazening
brazenly
brazens
brazier
brazier's
braziers
breach
breach's
breached
breaches
breaching
bread
bread's
breadbasket
breadbasket's
breadbaskets
breaded
breading
breads
breadth
breadth's
breadths
breadwinner
breadwinner's
breadwinners
break
breakable
breakables
breakdown
breakdown's
breakdowns
breakfast
breakfast's
breakfasted
breakfasting
breakfasts
breaking
breaking's
breakneck
breakpoints
breaks
breakthrough
breakthrough's
breakthroughs
breakup
breakup's
breakups
breakwater
breakwater's
breakwaters
breast
breast's
breasted
breasting
breasts
breaststroke
breaststroke's
breaststrokes
breath
breath's
breathe
breathed
breather
breather's
breathers
breathes
breathing
breathing's
breathless
breathlessly
breaths
breathtaking
breathtakingly
bred
breded
bredes
breding
breed
breeder
breeder's
breeders
breeding
breeding's
breeds
breeze
breeze's
breezed
breezes
breezier
breeziest
breezing
breezy
brethren
brevity
brevity's
brew
brewed
brewer
brewer's
breweries
brewers
brewery
brewery's
brewing
brewing's
brews
bribe
bribed
bribery
bribery's
bribes
bribing
brick
brick's
bricked
bricking
bricklayer
bricklayer's
bricklayers
bricklaying
bricklaying's
bricks
bridal
bridals
bride
bride's
bridegroom
bridegroom's
bridegrooms
brides
bridesmaid
bridesmaid's
bridesmaids
bridge
bridge's
bridged
bridges
bridging
bridle
bridle's
bridled
bridles
bridling
brief
briefcase
briefcase's
briefcases
briefed
briefer
briefest
briefing
briefing's
briefings
briefly
briefs
brigade
brigade's
brigades
bright
brighten
brightened
brightening
brightens
brighter
brightest
brightly
brightness
brightness's
brights
brilliance
brilliance's
brilliant
brilliantly
brilliants
brim
brim's
brimmed
brimming
brims
brimstone
brimstone's
brine
brine's
bring
bringing
brings
brinier
briniest
brink
brink's
brinks
briny
brisk
brisked
brisker
briskest
brisking
briskly
brisks
bristle
bristle's
bristled
bristles
bristling
britches
brittle
brittler
brittlest
broach
broached
broaches
broaching
broad
broadcast
broadcasted
broadcaster
broadcaster's
broadcasters
broadcasting
broadcasts
broaden
broadened
broadening
broadens
broader
broadest
broadly
broads
broadside
broadside's
broadsided
broadsides
broadsiding
brocade
brocade's
brocaded
brocades
brocading
broccoli
broccoli's
brochure
brochure's
brochures
brogue
brogue's
brogues
broil
broiled
broiler
broiler's
broilers
broiling
broils
broke
broken
brokenhearted
broker
broker's
brokerage
brokerage's
brokerages
brokered
brokering
brokers
bronchitis
bronchitis's
bronco
bronco's
broncos
bronze
bronze's
bronzed
bronzes
bronzing
brooch
brooch's
brooches
brood
brood's
brooded
brooding
broods
brook
brook's
brooked
brooking
brooks
broom
broom's
brooms
broomstick
broomstick's
broomsticks
broth
broth's
brothel
brothel's
brothels
brother
brother's
brothered
brotherhood
brotherhood's
brotherhoods
brothering
brotherly
brothers
broths
brought
brow
brow's
browbeat
browbeaten
browbeating
browbeats
brown
brown's
browned
browner
brownest
brownie
brownie's
brownier
brownies
browniest
browning
browning's
brownish
browns
brownstone
brownstone's
brownstones
brows
browse
browsed
browser
browser's
browsers
browses
browsing
bruise
bruised
bruises
bruising
brunch
brunch's
brunched
brunches
brunching
brunette
brunette's
brunettes
brunt
brunt's
brunted
brunting
brunts
brush
brush's
brushed
brushes
brushing
brusque
brusquer
brusquest
brutal
brutalise
brutalised
brutalises
brutalising
brutalities
brutality
brutality's
brutally
brute
brute's
brutes
brutish
bubble
bubble's
bubbled
bubbles
bubblier
bubbliest
bubbling
bubbly
buck
buck's
bucked
bucket
bucket's
bucketed
bucketing
buckets
bucking
buckle
buckle's
buckled
buckles
buckling
bucks
bucktoothed
bud
bud's
budded
buddies
budding
buddings
buddy
buddy's
budge
budged
budges
budget
budget's
budgeted
budgeting
budgets
budging
buds
buff
buff's
buffalo
buffalo's
buffaloed
buffaloes
buffaloing
buffalos
buffed
buffer
buffer's
buffered
buffering
buffers
buffet
buffet's
buffeted
buffeting
buffets
buffing
buffoon
buffoon's
buffoons
buffs
bug
bug's
bugged
bugger
bugger's
buggers
buggier
buggies
buggiest
bugging
buggy
buggy's
bugle
bugle's
bugled
bugler
bugler's
buglers
bugles
bugling
bugs
build
builder
builder's
builders
building
building's
buildings
builds
buildup
buildups
built
bulb
bulb's
bulbed
bulbing
bulbous
bulbs
bulge
bulge's
bulged
bulges
bulging
bulk
bulk's
bulked
bulkier
bulkiest
bulking
bulks
bulky
bull
bull's
bulldog
bulldog's
bulldogged
bulldogging
bulldogs
bulldoze
bulldozed
bulldozer
bulldozer's
bulldozers
bulldozes
bulldozing
bulled
bullet
bullet's
bulletin
bulletin's
bulletined
bulletining
bulletins
bulletproof
bulletproofed
bulletproofing
bulletproofs
bullets
bullfight
bullfight's
bullfighter
bullfighter's
bullfighters
bullfighting
bullfighting's
bullfights
bullfrog
bullfrog's
bullfrogs
bullied
bullied's
bullier
bullies
bulliest
bulling
bullion
bullion's
bullish
bulls
bullshit
bullshit's
bullshits
bullshitted
bullshitting
bully
bully's
bullying
bullying's
bum
bum's
bumble
bumblebee
bumblebee's
bumblebees
bumbled
bumbles
bumbling
bumblings
bummed
bummer
bummer's
bummers
bummest
bumming
bump
bumped
bumper
bumper's
bumpers
bumpier
bumpiest
bumping
bumps
bumpy
bums
bun
bun's
bunch
bunch's
bunched
bunches
bunching
bundle
bundle's
bundled
bundles
bundling
bung
bung's
bungalow
bungalow's
bungalows
bungle
bungled
bungler
bungler's
bunglers
bungles
bungling
bunion
bunion's
bunions
bunk
bunk's
bunked
bunker
bunker's
bunkers
bunking
bunks
bunnies
bunny
bunny's
buns
buoy
buoy's
buoyancy
buoyancy's
buoyant
buoyantly
buoyed
buoying
buoys
burble
burbled
burbles
burbling
burden
burden's
burdened
burdening
burdens
burdensome
bureau
bureau's
bureaucracies
bureaucracy
bureaucracy's
bureaucrat
bureaucrat's
bureaucratic
bureaucrats
bureaus
bureaux
burger
burger's
burgers
burglar
burglar's
burglaries
burglarise
burglarised
burglarises
burglarising
burglars
burglary
burglary's
burgle
burial
burial's
burials
buried
buries
burlap
burlap's
burlier
burliest
burly
burn
burned
burner
burner's
burners
burning
burnish
burnished
burnishes
burnishing
burns
burnt
burp
burp's
burped
burping
burps
burr
burr's
burred
burring
burro
burro's
burros
burrow
burrow's
burrowed
burrowing
burrows
burrs
bursar
bursar's
bursars
burst
bursted
bursting
bursts
bury
burying
bus
bus's
busboy
busboy's
busboys
bused
buses
bush
bush's
bushed
bushel
bushel's
bushelled
bushelling
bushellings
bushels
bushes
bushier
bushiest
bushing
bushy
busied
busier
busies
busiest
busily
business
business's
businesses
businesslike
businessman
businessman's
businessmen
businesswoman
businesswoman's
businesswomen
busing
buss
bussed
busses
bussing
bust
bust's
busted
buster
buster's
busters
busting
bustle
bustled
bustles
bustling
busts
busy
busybodies
busybody
busybody's
busying
busywork
busywork's
but
butcher
butcher's
butchered
butcheries
butchering
butchers
butchery
butchery's
butler
butler's
butlered
butlering
butlers
buts
butt
butt's
butte
butte's
butted
butter
butter's
buttercup
buttercup's
buttercups
buttered
butterfingers
butterfingers's
butterflied
butterflies
butterfly
butterfly's
butterflying
buttering
buttermilk
buttermilk's
butters
butterscotch
butterscotch's
buttery
buttes
butting
buttock
buttock's
buttocked
buttocking
buttocks
button
button's
buttoned
buttonhole
buttonhole's
buttonholed
buttonholes
buttonholing
buttoning
buttons
buttress
buttress's
buttressed
buttresses
buttressing
butts
buxom
buxomer
buxomest
buy
buyer
buyer's
buyers
buying
buyout
buyouts
buys
buzz
buzz's
buzzard
buzzard's
buzzards
buzzed
buzzer
buzzer's
buzzers
buzzes
buzzing
buzzword
buzzwords
by
bye
bye's
byes
bygone
bygones
bylaw
bylaw's
bylaws
bypass
bypass's
bypassed
bypasses
bypassing
bypast
bystander
bystander's
bystanders
byte
byte's
bytes
byway
byway's
byways
c
cab
cab's
cabaret
cabaret's
cabarets
cabbage
cabbage's
cabbages
cabbed
cabbie
cabbies
cabbing
cabby
cabby's
cabin
cabin's
cabinet
cabinet's
cabinets
cabins
cable
cable's
cabled
cables
cabling
caboose
caboose's
cabooses
cabs
cacao
cacao's
cacaos
cache
cache's
cached
caches
cachet
cachet's
cacheted
cacheting
cachets
caching
cackle
cackled
cackles
cackling
cacti
cactus
cactus's
cactuses
cad
cad's
cadaver
cadaver's
cadavers
caddie
caddie's
caddied
caddieing
caddies
caddy
cadence
cadence's
cadences
cadet
cadet's
cadets
cadre
cadre's
cadres
cafeteria
cafeteria's
cafeterias
caffeine
caffeine's
caf
cafs
cage
cage's
caged
cages
cagey
cagier
cagiest
caging
cagy
cahoot
cahoots
cajole
cajoled
cajoles
cajoling
cake
cake's
caked
cakes
caking
calamities
calamity
calamity's
calcium
calcium's
calculate
calculated
calculates
calculating
calculation
calculation's
calculations
calculator
calculator's
calculators
calculi
calculus
calculus's
calculuses
calendar
calendar's
calendared
calendaring
calendars
calf
calf's
calfs
calibrate
calibrated
calibrates
calibrating
calibration
calibration's
calibrations
calibre
calibre's
calibres
calico
calico's
calicoes
calicos
call
callable
called
caller
caller's
callers
calligraphy
calligraphy's
calling
calling's
callings
callous
calloused
callouses
callousing
callously
callousness
callousness's
callow
calls
callus
callus's
callused
calluses
callusing
calm
calmed
calmer
calmest
calming
calmly
calmness
calmness's
calms
calorie
calorie's
calories
calve
calves
calves's
cam
cam's
camaraderie
camaraderie's
camcorder
camcorders
came
camel
camel's
camellia
camellia's
camellias
camels
cameo
cameo's
cameoed
cameoing
cameos
camera
camera's
camerae
cameraman
cameraman's
cameramen
cameras
camerawoman
camerawomen
camouflage
camouflage's
camouflaged
camouflages
camouflaging
camp
camp's
campaign
campaign's
campaigned
campaigner
campaigner's
campaigners
campaigning
campaigns
camped
camper
camper's
campers
campest
campground
campground's
campgrounds
camping
camps
campsite
campsite's
campsites
campus
campus's
campused
campuses
campusing
can
can's
can't
canal
canal's
canals
canaries
canary
canary's
cancel
cancellation
cancellation's
cancellations
cancelled
cancelling
cancels
cancer
cancer's
cancers
candid
candidacies
candidacy
candidacy's
candidate
candidate's
candidates
candider
candidest
candidly
candied
candies
candle
candle's
candled
candlelight
candlelight's
candles
candlestick
candlestick's
candlesticks
candling
candour
candour's
candy
candy's
candying
cane
cane's
caned
canes
canine
canines
caning
canister
canister's
canistered
canistering
canisters
canker
canker's
cankered
cankering
cankers
cannabis
cannabis's
cannabises
canned
canneries
cannery
cannery's
cannibal
cannibal's
cannibalism
cannibalism's
cannibals
cannier
canniest
canning
cannon
cannon's
cannonball
cannonball's
cannonballed
cannonballing
cannonballs
cannoned
cannoning
cannons
cannot
canny
canoe
canoe's
canoed
canoes
canon
canon's
canonical
canons
canopied
canopies
canopy
canopy's
canopying
cans
cant
cant's
cantaloupe
cantaloupe's
cantaloupes
cantankerous
canteen
canteen's
canteens
canter
canter's
cantered
cantering
canters
canvas
canvas's
canvased
canvases
canvasing
canvass
canvassed
canvasser
canvassers
canvasses
canvassing
canyon
canyon's
canyons
cap
cap's
capabilities
capability
capability's
capable
capabler
capablest
capably
capacitance
capacitance's
capacities
capacitor
capacitor's
capacitors
capacity
capacity's
cape
cape's
caped
caper
caper's
capered
capering
capers
capes
capillaries
capillary
capital
capital's
capitalisation
capitalisation's
capitalise
capitalised
capitalises
capitalising
capitalism
capitalism's
capitalist
capitalist's
capitalists
capitals
capitol
capitols
capitulate
capitulated
capitulates
capitulating
capitulation
capitulation's
capitulations
capped
capping
cappuccino
cappuccino's
cappuccinos
caprice
caprice's
caprices
capricious
capriciously
caps
capsize
capsized
capsizes
capsizing
capsule
capsule's
capsuled
capsules
capsuling
captain
captain's
captained
captaining
captains
caption
caption's
captioned
captioning
captions
captivate
captivated
captivates
captivating
captive
captive's
captives
captivities
captivity
captivity's
captor
captor's
captors
capture
captured
captures
capturing
car
car's
caramel
caramel's
caramels
carat
carat's
carats
caravan
caravan's
caravans
carbohydrate
carbohydrate's
carbohydrates
carbon
carbon's
carbonate
carbonated
carbonates
carbonating
carbons
carburetor
carburetor's
carburetors
carcass
carcass's
carcasses
carcinogenic
card
card's
cardboard
cardboard's
carded
cardiac
cardigan
cardigan's
cardigans
cardinal
cardinal's
cardinals
carding
cardiology
cardiology's
cards
care
cared
careen
careened
careening
careens
career
career's
careered
careering
careers
carefree
careful
carefuller
carefullest
carefully
carefulness
carefulness's
careless
carelessly
carelessness
carelessness's
cares
caress
caress's
caressed
caresses
caressing
caretaker
caretaker's
caretakers
cargo
cargo's
cargoes
cargos
caribou
caribou's
caribous
caricature
caricature's
caricatured
caricatures
caricaturing
caring
carjack
carjacked
carjacker
carjackers
carjacking
carjackings
carjacks
carnage
carnage's
carnal
carnation
carnation's
carnations
carnival
carnival's
carnivals
carnivore
carnivore's
carnivores
carnivorous
carol
carol's
carolled
carolling
carols
carouse
caroused
carousel
carousel's
carousels
carouses
carousing
carp
carp's
carped
carpenter
carpenter's
carpentered
carpentering
carpenters
carpentry
carpentry's
carpet
carpet's
carpeted
carpeting
carpeting's
carpets
carping
carps
carriage
carriage's
carriages
carriageway
carriageway's
carried
carrier
carrier's
carriers
carries
carrion
carrion's
carrot
carrot's
carrots
carry
carrying
carryout
carryouts
cars
cart
cart's
carted
cartel
cartel's
cartels
cartilage
cartilage's
cartilages
carting
cartographer
cartographer's
cartographers
cartography
cartography's
carton
carton's
cartons
cartoon
cartoon's
cartooned
cartooning
cartoonist
cartoonist's
cartoonists
cartoons
cartridge
cartridge's
cartridges
carts
cartwheel
cartwheel's
cartwheeled
cartwheeling
cartwheels
carve
carved
carves
carving
carving's
carvings
cascade
cascade's
cascaded
cascades
cascading
case
case's
cased
cases
casework
casework's
caseworker
caseworker's
caseworkers
cash
cash's
cashed
cashes
cashew
cashew's
cashews
cashier
cashier's
cashiered
cashiering
cashiers
cashing
cashmere
cashmere's
casing
casing's
casings
casino
casino's
casinos
cask
cask's
casket
casket's
caskets
casks
casserole
casserole's
casseroled
casseroles
casseroling
cassette
cassette's
cassettes
cast
castaway
castaway's
castaways
caste
caste's
casted
caster
caster's
casters
castes
castigate
castigated
castigates
castigating
castigation
castigation's
casting
casting's
castings
castle
castle's
castled
castles
castling
castoff
castoffs
castrate
castrated
castrates
castrating
castration
castration's
castrations
casts
casual
casually
casualness
casualness's
casuals
casualties
casualty
casualty's
cat
cat's
cataclysm
cataclysm's
cataclysmic
cataclysms
catalogue
catalogue's
catalogued
catalogues
cataloguing
catalyst
catalyst's
catalysts
catamaran
catamaran's
catamarans
catapult
catapult's
catapulted
catapulting
catapults
cataract
cataract's
cataracts
catastrophe
catastrophe's
catastrophes
catastrophic
catcall
catcall's
catcalled
catcalling
catcalls
catch
catches
catchier
catchiest
catching
catchings
catchment
catchment's
catchy
catechism
catechism's
catechisms
categorical
categorically
categories
categorise
categorised
categorises
categorising
category
category's
cater
catered
caterer
caterer's
caterers
catering
catering's
caterings
caterpillar
caterpillar's
caterpillars
caters
catfish
catfish's
catfishes
cathedral
cathedral's
cathedrals
catholic
catholics
catnap
catnap's
catnapped
catnapping
catnaps
catnip
catnip's
cats
catsup
catsup's
cattier
cattiest
cattle
cattle's
catty
catwalk
catwalk's
catwalks
caucus
caucus's
caucused
caucuses
caucusing
caucussed
caucusses
caucussing
caught
cauliflower
cauliflower's
cauliflowers
caulk
caulked
caulking
caulks
causal
causality
causality's
cause
cause's
caused
causes
causeway
causeway's
causeways
causing
caustic
caustics
caution
caution's
cautionary
cautioned
cautioning
cautions
cautious
cautiously
cavalier
cavaliers
cavalries
cavalry
cavalry's
cave
cave's
caveat
caveat's
caveats
caved
caveman
caveman's
cavemen
cavern
cavern's
caverns
caves
caviar
caviar's
caving
caving's
cavities
cavity
cavity's
cavort
cavorted
cavorting
cavorts
caw
caw's
cawed
cawing
caws
cease
ceased
ceasefire
ceaseless
ceaselessly
ceases
ceasing
cedar
cedar's
cedars
cede
ceded
cedes
ceding
ceiling
ceiling's
ceilings
celebrate
celebrated
celebrates
celebrating
celebration
celebration's
celebrations
celebrities
celebrity
celebrity's
celery
celery's
celestial
celibacy
celibacy's
celibate
celibate's
celibates
cell
cell's
cellar
cellar's
cellars
celled
celli
celling
cellist
cellist's
cellists
cello
cello's
cellophane
cellophane's
cellos
cells
cellular
cellulars
celluloid
celluloid's
cellulose
cellulose's
cement
cement's
cemented
cementing
cements
cemeteries
cemetery
cemetery's
censor
censor's
censored
censoring
censors
censorship
censorship's
censure
censure's
censured
censures
censuring
census
census's
censused
censuses
censusing
cent
cent's
centenaries
centenary
centennial
centennials
centigrade
centimetre
centimetre's
centimetres
centipede
centipede's
centipedes
central
centraler
centralest
centralise
centralised
centralises
centralising
centrally
centrals
centre
centre's
centred
centrepiece
centrepiece's
centrepieces
centres
centrifuge
centrifuge's
centring
cents
centuries
century
century's
ceramic
ceramic's
ceramics
cereal
cereal's
cereals
cerebral
ceremonial
ceremonials
ceremonies
ceremonious
ceremony
ceremony's
certain
certainer
certainest
certainly
certainties
certainty
certainty's
certifiable
certificate
certificate's
certificated
certificates
certificating
certification
certification's
certifications
certified
certifies
certify
certifying
cervical
cervices
cervix
cervix's
cervixes
cesarean
cesareans
cessation
cessation's
cessations
cesspool
cesspool's
cesspools
chafe
chafed
chafes
chaff
chaff's
chaffed
chaffing
chaffs
chafing
chagrin
chagrin's
chagrined
chagrining
chagrinned
chagrinning
chagrins
chain
chain's
chained
chaining
chains
chainsaw
chainsawed
chainsawing
chainsaws
chair
chair's
chaired
chairing
chairman
chairman's
chairmanship
chairmanship's
chairmen
chairperson
chairpersons
chairs
chairwoman
chairwoman's
chairwomen
chalet
chalet's
chalets
chalice
chalice's
chalices
chalk
chalk's
chalkboard
chalkboard's
chalkboards
chalked
chalkier
chalkiest
chalking
chalks
chalky
challenge
challenged
challenger
challenger's
challengers
challenges
challenging
chamber
chamber's
chambers
chameleon
chameleon's
chameleons
champ
champagne
champagne's
champagnes
champed
champing
champion
champion's
championed
championing
champions
championship
championship's
championships
champs
chance
chance's
chanced
chancellor
chancellor's
chancellors
chances
chancing
chandelier
chandelier's
chandeliers
change
changeable
changed
changeover
changeover's
changeovers
changes
changing
channel
channel's
channelled
channelling
channels
chant
chant's
chanted
chanting
chants
chaos
chaos's
chaotic
chap
chapel
chapel's
chapels
chaperon
chaperon's
chaperone
chaperone's
chaperoned
chaperones
chaperoning
chaperons
chaplain
chaplain's
chaplains
chapped
chapping
chaps
chapt
chapter
chapter's
chapters
char
character
character's
characterisation
characterisation's
characterisations
characterise
characterised
characterises
characterising
characteristic
characteristic's
characteristically
characteristics
characters
charade
charade's
charades
charcoal
charcoal's
charcoals
charge
chargeable
charged
charger
charger's
charges
charging
chariot
chariot's
chariots
charisma
charisma's
charismatic
charismatics
charitable
charitably
charities
charity
charity's
charlatan
charlatan's
charlatans
charm
charm's
charmed
charmer
charmer's
charmers
charming
charminger
charmingest
charms
charred
charring
chars
chart
chart's
charted
charter
charter's
chartered
chartering
charters
charting
charts
chase
chased
chases
chasing
chasing's
chasm
chasm's
chasms
chassis
chassis's
chaste
chasten
chastened
chastening
chastens
chaster
chastest
chastise
chastised
chastisement
chastisement's
chastisements
chastises
chastising
chastity
chastity's
chat
chat's
chateaus
chats
chatted
chatter
chatterbox
chatterbox's
chatterboxes
chattered
chattering
chatters
chattier
chattiest
chatting
chatty
chauffeur
chauffeur's
chauffeured
chauffeuring
chauffeurs
chauvinism
chauvinism's
chauvinist
chauvinist's
chauvinistic
chauvinists
cheap
cheapen
cheapened
cheapening
cheapens
cheaper
cheapest
cheaply
cheapness
cheapness's
cheapskate
cheapskate's
cheapskates
cheat
cheated
cheater
cheater's
cheaters
cheating
cheats
check
check's
checked
checker
checker's
checkered
checkering
checkers
checking
checklist
checklists
checkmate
checkmate's
checkmated
checkmates
checkmating
checkout
checkouts
checkpoint
checkpoint's
checkpoints
checks
checkup
checkup's
checkups
cheddar
cheek
cheek's
cheekbone
cheekbone's
cheekbones
cheeked
cheeking
cheeks
cheep
cheep's
cheeped
cheeping
cheeps
cheer
cheered
cheerful
cheerfuller
cheerfullest
cheerfully
cheerfulness
cheerfulness's
cheerier
cheeriest
cheering
cheerleader
cheerleader's
cheerleaders
cheers
cheerses
cheery
cheese
cheese's
cheeseburger
cheeseburger's
cheeseburgers
cheesecake
cheesecake's
cheesecakes
cheesecloth
cheesecloth's
cheesed
cheeses
cheesing
cheetah
cheetah's
cheetahs
chef
chef's
cheffed
cheffing
chefs
chemical
chemical's
chemically
chemicals
chemist
chemist's
chemistry
chemistry's
chemists
chemotherapy
chemotherapy's
cheque
cheque's
chequebook
chequebook's
chequebooks
chequer
chequer's
chequerboard
chequerboard's
chequerboards
chequered
chequering
chequers
cheques
cherish
cherished
cherishes
cherishing
cherries
cherry
cherry's
cherub
cherub's
cherubim
cherubs
chess
chess's
chessboard
chessboard's
chessboards
chest
chest's
chestnut
chestnut's
chestnuts
chests
chew
chewed
chewier
chewiest
chewing
chews
chewy
chi
chi's
chic
chicer
chicest
chick
chick's
chickadee
chickadee's
chickadees
chicken
chicken's
chickened
chickening
chickens
chicks
chid
chidden
chide
chided
chides
chiding
chief
chief's
chiefer
chiefest
chiefly
chiefs
chieftain
chieftain's
chieftains
chiffon
chiffon's
child
child's
childbearing
childbearing's
childbirth
childbirth's
childbirths
childcare
childed
childes
childhood
childhood's
childhoods
childing
childish
childishly
childless
childlike
childproof
childproofed
childproofing
childproofs
children
children's
chili
chili's
chilies
chill
chill's
chilled
chiller
chiller's
chillest
chilli
chillier
chillies
chilliest
chilling
chillings
chills
chilly
chime
chime's
chimed
chimes
chiming
chimney
chimney's
chimneys
chimp
chimp's
chimpanzee
chimpanzee's
chimpanzees
chimps
chin
china
china's
chink
chink's
chinked
chinking
chinks
chinned
chinning
chino
chinos
chins
chintz
chintz's
chip
chip's
chipmunk
chipmunk's
chipmunks
chipped
chipper
chippers
chipping
chips
chiropractor
chiropractor's
chiropractors
chirp
chirped
chirping
chirps
chisel
chisel's
chiseled
chiseling
chiselled
chiselling
chisels
chit
chit's
chitchat
chitchat's
chitchats
chitchatted
chitchatting
chits
chivalrous
chivalry
chivalry's
chive
chives
chlorinate
chlorinated
chlorinates
chlorinating
chlorine
chlorine's
chloroform
chloroform's
chloroformed
chloroforming
chloroforms
chlorophyll
chlorophyll's
chocolate
chocolate's
chocolates
choice
choice's
choicer
choices
choicest
choir
choir's
choirs
choke
choked
chokes
choking
cholera
cholera's
cholesterol
cholesterol's
choose
chooses
choosey
choosier
choosiest
choosing
choosy
chop
chopped
chopper
chopper's
choppered
choppering
choppers
choppier
choppiest
choppiness
choppiness's
chopping
choppy
chops
chopstick
chopsticks
choral
chorals
chord
chord's
chords
chore
chore's
chored
choreograph
choreographed
choreographer
choreographer's
choreographers
choreographing
choreographs
choreography
choreography's
chores
choring
chortle
chortled
chortles
chortling
chorus
chorus's
chorused
choruses
chorusing
chorussed
chorusses
chorussing
chose
chosen
chow
chow's
chowder
chowder's
chowdered
chowdering
chowders
chowed
chowing
chows
christen
christened
christening
christening's
christenings
christens
chrome
chrome's
chromed
chromes
chroming
chromium
chromium's
chromosome
chromosome's
chromosomes
chronic
chronically
chronicle
chronicle's
chronicled
chronicles
chronicling
chronics
chronological
chronologically
chronologies
chronology
chronology's
chrysanthemum
chrysanthemum's
chrysanthemums
chubbier
chubbiest
chubby
chuck
chucked
chucking
chuckle
chuckled
chuckles
chuckling
chucks
chug
chug's
chugged
chugging
chugs
chum
chum's
chummed
chummier
chummies
chummiest
chumming
chummy
chump
chump's
chumps
chums
chunk
chunk's
chunkier
chunkiest
chunks
chunky
church
church's
churches
churchgoer
churchgoer's
churchgoers
churlish
churn
churn's
churned
churning
churning's
churns
chute
chute's
chutes
chutzpah
chutzpah's
chteau
chteau's
chteaux
cider
cider's
ciders
cigar
cigar's
cigarette
cigarette's
cigarettes
cigars
cinch
cinch's
cinched
cinches
cinching
cinder
cinder's
cindered
cindering
cinders
cinema
cinema's
cinemas
cinematographer
cinematographer's
cinematographers
cinnamon
cinnamon's
cipher
cipher's
ciphered
ciphering
ciphers
circa
circle
circle's
circled
circles
circling
circuit
circuit's
circuited
circuiting
circuitous
circuitry
circuitry's
circuits
circular
circulars
circulate
circulated
circulates
circulating
circulation
circulation's
circulations
circulatory
circumcise
circumcised
circumcises
circumcising
circumcision
circumcision's
circumcisions
circumference
circumference's
circumferences
circumflex
circumflex's
circumstance
circumstance's
circumstanced
circumstances
circumstancing
circumstantial
circumstantials
circumvent
circumvented
circumventing
circumvention
circumvention's
circumvents
circus
circus's
circuses
cirrhosis
cirrhosis's
cistern
cistern's
cisterns
citation
citation's
citations
cite
cited
cites
cities
citing
citizen
citizen's
citizens
citizenship
citizenship's
citric
citrus
citrus's
citruses
city
city's
civic
civics
civics's
civil
civilian
civilian's
civilians
civilisation
civilisation's
civilisations
civilise
civilised
civilises
civilising
civilities
civility
civility's
civilly
clack
clacked
clacking
clacks
clad
claim
claimed
claiming
claims
clairvoyance
clairvoyance's
clairvoyant
clairvoyants
clam
clam's
clamber
clambered
clambering
clambers
clammed
clammier
clammiest
clamming
clammy
clamour
clamour's
clamoured
clamouring
clamours
clamp
clamp's
clampdown
clampdown's
clampdowns
clamped
clamping
clamps
clams
clan
clan's
clandestine
clang
clanged
clanging
clangs
clank
clank's
clanked
clanking
clanks
clans
clap
clapboard
clapboard's
clapboarded
clapboarding
clapboards
clapped
clapper
clapper's
clappered
clappering
clappers
clapping
claps
claptrap
claptrap's
claret
claret's
clarification
clarification's
clarifications
clarified
clarifies
clarify
clarifying
clarinet
clarinet's
clarinets
clarity
clarity's
clash
clashed
clashes
clashing
clasp
clasp's
clasped
clasping
clasps
class
class's
classed
classes
classic
classical
classically
classics
classics's
classier
classiest
classification
classification's
classifications
classified
classifieds
classifies
classify
classifying
classing
classmate
classmate's
classmates
classroom
classroom's
classrooms
classy
clatter
clattered
clattering
clatters
clause
clause's
clauses
claustrophobia
claustrophobia's
claustrophobic
claw
claw's
clawed
clawing
claws
clay
clay's
clean
cleaned
cleaner
cleaner's
cleaners
cleanest
cleaning
cleaning's
cleanings
cleanlier
cleanliest
cleanliness
cleanliness's
cleanly
cleans
cleanse
cleansed
cleanser
cleanser's
cleansers
cleanses
cleansing
cleanup
cleanup's
cleanups
clear
clearance
clearance's
clearances
cleared
clearer
clearer's
clearest
clearing
clearing's
clearings
clearly
clearness
clearness's
clears
cleat
cleat's
cleats
cleavage
cleavage's
cleavages
cleave
cleaved
cleaver
cleaver's
cleavers
cleaves
cleaving
clef
clef's
clefs
cleft
clefted
clefting
clefts
clemency
clemency's
clench
clenched
clenches
clenching
clergies
clergy
clergy's
clergyman
clergyman's
clergymen
clergywoman
clergywomen
cleric
cleric's
clerical
clerics
clerk
clerk's
clerked
clerking
clerks
clever
cleverer
cleverest
cleverly
cleverness
cleverness's
cleves
clich
clich's
clichs
click
click's
clicked
clicking
clicks
client
client's
clients
clientle
clientle's
clientles
cliff
cliff's
cliffhanger
cliffhanger's
cliffhangers
cliffs
climactic
climate
climate's
climates
climatic
climax
climax's
climaxed
climaxes
climaxing
climb
climbed
climber
climber's
climbers
climbing
climbs
clime
climes
clinch
clinched
clinches
clinching
cling
clinging
clings
clinic
clinic's
clinical
clinically
clinician
clinician's
clinicians
clinics
clink
clinked
clinking
clinks
clip
clipboard
clipboard's
clipboards
clipped
clipper
clippers
clipping
clipping's
clippings
clips
clipt
clique
clique's
cliques
clitoris
clitoris's
clitorises
cloak
cloak's
cloaked
cloaking
cloakroom
cloakroom's
cloakrooms
cloaks
clobber
clobbered
clobbering
clobbers
clock
clock's
clocked
clocking
clocks
clockwise
clockwork
clockwork's
clockworks
clod
clod's
clodded
clodding
clods
clog
clogged
clogging
clogs
cloister
cloister's
cloistered
cloistering
cloisters
clone
clone's
cloned
clones
cloning
close
closed
closely
closeness
closeness's
closeout
closeout's
closeouts
closer
closer's
closes
closest
closet
closet's
closeted
closeting
closets
closing
closure
closure's
closures
clot
clot's
cloth
cloth's
clothe
clothed
clothes
clothesline
clothesline's
clotheslined
clotheslines
clotheslining
clothespin
clothespin's
clothespins
clothing
clothing's
cloths
clots
clotted
clotting
cloud
cloud's
cloudburst
cloudburst's
cloudbursts
clouded
cloudier
cloudiest
clouding
cloudless
clouds
cloudy
clout
clout's
clouted
clouting
clouts
clove
clove's
cloven
clover
clover's
clovers
cloves
clown
clown's
clowned
clowning
clowns
club
club's
clubbed
clubbing
clubhouse
clubhouse's
clubhouses
clubs
cluck
cluck's
clucked
clucking
clucks
clue
clue's
clued
clueing
clueless
clues
cluing
clump
clump's
clumped
clumping
clumps
clumsier
clumsiest
clumsily
clumsiness
clumsiness's
clumsy
clung
clunk
clunk's
clunked
clunking
clunks
cluster
cluster's
clustered
clustering
clusters
clutch
clutched
clutches
clutching
clutter
cluttered
cluttering
clutters
coach
coach's
coached
coaches
coaching
coagulate
coagulated
coagulates
coagulating
coagulation
coagulation's
coal
coal's
coaled
coalesce
coalesced
coalesces
coalescing
coaling
coalition
coalition's
coalitions
coals
coarse
coarsely
coarsen
coarsened
coarseness
coarseness's
coarsening
coarsens
coarser
coarsest
coast
coast's
coastal
coasted
coaster
coaster's
coasters
coasting
coastline
coastline's
coastlines
coasts
coat
coat's
coated
coater
coating
coating's
coatings
coats
coattest
coax
coaxed
coaxes
coaxing
cob
cob's
cobalt
cobalt's
cobbed
cobbing
cobble
cobble's
cobbler
cobbler's
cobblers
cobblestone
cobblestone's
cobblestones
cobra
cobra's
cobras
cobs
cobweb
cobweb's
cobwebs
cocaine
cocaine's
cock
cock's
cocked
cockeyed
cockier
cockiest
cockiness
cockiness's
cocking
cockpit
cockpit's
cockpits
cockroach
cockroach's
cockroaches
cocks
cocktail
cocktail's
cocktails
cocky
cocoa
cocoa's
cocoas
coconut
coconut's
coconuts
cocoon
cocoon's
cocooned
cocooning
cocoons
cod
cod's
codded
codding
code
code's
coded
codes
coding
coding's
cods
coed
coed's
coeds
coeducational
coefficient
coefficient's
coefficients
coerce
coerced
coerces
coercing
coercion
coercion's
coercive
coexist
coexisted
coexistence
coexistence's
coexisting
coexists
coffee
coffee's
coffeehouse
coffeehouse's
coffeehouses
coffees
coffer
coffer's
coffers
coffin
coffin's
coffined
coffining
coffins
cog
cog's
cogency
cogency's
cogent
cogently
cognac
cognac's
cognacs
cognitive
cogs
cohabit
cohabitation
cohabitation's
cohabited
cohabiting
cohabits
coherence
coherence's
coherent
coherently
cohesion
cohesion's
coil
coiled
coiling
coils
coin
coin's
coinage
coinage's
coinages
coincide
coincided
coincidence
coincidence's
coincidences
coincidental
coincidentally
coincides
coinciding
coined
coining
coins
coke
coke's
coked
cokes
coking
cola
cola's
colander
colander's
colanders
colas
cold
colder
coldest
coldly
coldness
coldness's
colds
coleslaw
coleslaw's
colic
colic's
collaborate
collaborated
collaborates
collaborating
collaboration
collaboration's
collaborations
collaborative
collaborator
collaborator's
collaborators
collage
collage's
collages
collapse
collapsed
collapses
collapsible
collapsing
collar
collar's
collarbone
collarbone's
collarbones
collared
collaring
collars
collate
collated
collateral
collateral's
collates
collating
collation
collation's
colleague
colleague's
colleagued
colleagues
colleaguing
collect
collected
collectible
collectibles
collecting
collection
collection's
collections
collective
collectively
collectives
collector
collector's
collectors
collects
college
college's
colleges
collegiate
collide
collided
collides
colliding
collie
collie's
collied
collies
collision
collision's
collisions
colloquial
colloquialism
colloquialism's
colloquialisms
colloquially
colloquials
collusion
collusion's
collying
cologne
cologne's
colognes
colon
colon's
colonel
colonel's
colonels
colonial
colonialism
colonialism's
colonials
colonies
colonisation
colonisation's
colonise
colonised
colonises
colonising
colonist
colonist's
colonists
colons
colony
colony's
colossal
colour
colour's
colourblind
coloured
coloureds
colourful
colouring
colouring's
colourless
colours
colt
colt's
colts
column
column's
columnist
columnist's
columnists
columns
coma
coma's
comae
comas
comatose
comb
comb's
combat
combat's
combatant
combatant's
combatants
combated
combating
combative
combats
combatted
combatting
combed
combination
combination's
combinations
combine
combined
combines
combing
combining
combs
combustible
combustibles
combustion
combustion's
come
comeback
comeback's
comebacks
comedian
comedian's
comedians
comedies
comedown
comedown's
comedowns
comedy
comedy's
comelier
comeliest
comely
comes
comes's
comestible
comestibles
comet
comet's
comets
comeuppance
comeuppance's
comeuppances
comfier
comfiest
comfort
comfort's
comfortable
comfortably
comforted
comforter
comforter's
comforters
comforting
comforts
comfy
comic
comical
comics
coming
comings
comma
comma's
command
commandant
commandant's
commandants
commanded
commandeer
commandeered
commandeering
commandeers
commander
commander's
commanders
commanding
commandment
commandment's
commandments
commando
commando's
commandoes
commandos
commands
commas
commemorate
commemorated
commemorates
commemorating
commemoration
commemoration's
commemorations
commemorative
commence
commenced
commencement
commencement's
commencements
commences
commencing
commend
commendable
commendation
commendation's
commendations
commended
commending
commends
comment
comment's
commentaries
commentary
commentary's
commentate
commentated
commentates
commentating
commentator
commentator's
commentators
commented
commenting
comments
commerce
commerce's
commerced
commerces
commercial
commercialise
commercialised
commercialises
commercialising
commercialism
commercialism's
commercially
commercials
commercing
commiserate
commiserated
commiserates
commiserating
commiseration
commiseration's
commiserations
commission
commission's
commissioned
commissioner
commissioner's
commissioners
commissioning
commissions
commit
commitment
commitment's
commitments
commits
committed
committee
committee's
committees
committing
commodities
commodity
commodity's
commodore
commodore's
commodores
common
commoner
commoner's
commonest
commonly
commonplace
commonplaces
commons
commons's
commonwealth
commonwealth's
commonwealths
commotion
commotion's
commotions
communal
commune
communed
communes
communicable
communicate
communicated
communicates
communicating
communication
communication's
communications
communicative
communicator
communicator's
communing
communion
communion's
communions
communique
communiques
communism
communism's
communist
communist's
communists
communities
community
community's
commutative
commute
commuted
commuter
commuter's
commuters
commutes
commuting
compact
compacted
compacter
compactest
compacting
compaction
compaction's
compacts
companies
companion
companion's
companionable
companions
companionship
companionship's
company
company's
comparable
comparative
comparatively
comparatives
compare
compared
compares
comparing
comparison
comparison's
comparisons
compartment
compartment's
compartmentalise
compartmentalised
compartmentalises
compartmentalising
compartments
compass
compass's
compassed
compasses
compassing
compassion
compassion's
compassionate
compatibility
compatibility's
compatible
compatibles
compatriot
compatriot's
compatriots
compel
compelled
compelling
compelling's
compels
compensate
compensated
compensates
compensating
compensation
compensation's
compensations
compensatory
compete
competed
competence
competence's
competences
competent
competently
competes
competing
competition
competition's
competitions
competitive
competitively
competitiveness
competitiveness's
competitor
competitor's
competitors
compilation
compilation's
compilations
compile
compiled
compiler
compiler's
compilers
compiles
compiling
complacency
complacency's
complacent
complain
complained
complaining
complains
complaint
complaint's
complaints
complement
complement's
complementary
complemented
complementing
complements
complete
completed
completely
completeness
completeness's
completer
completes
completest
completing
completion
completion's
complex
complexer
complexes
complexest
complexion
complexion's
complexioned
complexions
complexities
complexity
complexity's
compliance
compliance's
compliant
complicate
complicated
complicates
complicating
complication
complication's
complications
complices
complicity
complicity's
complied
complies
compliment
compliment's
complimentary
complimented
complimenting
compliments
comply
complying
component
component's
components
compose
composed
composer
composer's
composers
composes
composing
composite
composites
composition
composition's
compositions
compost
compost's
composted
composting
composts
composure
composure's
compound
compound's
compounded
compounding
compounds
comprehend
comprehended
comprehending
comprehends
comprehensible
comprehension
comprehension's
comprehensions
comprehensive
comprehensively
comprehensives
compress
compressed
compresses
compressing
compression
compression's
comprise
comprised
comprises
comprising
compromise
compromise's
compromised
compromises
compromising
compulsion
compulsion's
compulsions
compulsive
compulsories
compulsory
compunction
compunction's
compunctions
computation
computation's
computational
computations
compute
computed
computer
computer's
computerise
computerised
computerises
computerising
computers
computes
computing
comrade
comrade's
comrades
comradeship
comradeship's
con
con's
concatenate
concatenated
concatenates
concatenating
concatenation
concatenation's
concatenations
concave
conceal
concealed
concealing
concealment
concealment's
conceals
concede
conceded
concedes
conceding
conceit
conceit's
conceited
conceits
conceivable
conceivably
conceive
conceived
conceives
conceiving
concentrate
concentrated
concentrates
concentrating
concentration
concentration's
concentrations
concentric
concept
concept's
conception
conception's
conceptions
concepts
conceptual
conceptually
concern
concerned
concerning
concerns
concert
concert's
concerted
concerti
concerting
concerto
concerto's
concertos
concerts
concession
concession's
concessions
concierge
concierge's
concierges
conciliate
conciliated
conciliates
conciliating
conciliation
conciliation's
conciliatory
concise
concisely
conciseness
conciseness's
conciser
concisest
conclude
concluded
concludes
concluding
conclusion
conclusion's
conclusions
conclusive
conclusively
concoct
concocted
concocting
concoction
concoction's
concoctions
concocts
concord
concord's
concordance
concordance's
concourse
concourse's
concourses
concrete
concrete's
concreted
concretely
concretes
concreting
concur
concurred
concurrence
concurrence's
concurrences
concurrency
concurrent
concurrently
concurring
concurs
concussion
concussion's
concussions
condemn
condemnation
condemnation's
condemnations
condemned
condemning
condemns
condensation
condensation's
condensations
condense
condensed
condenses
condensing
condescend
condescended
condescending
condescends
condescension
condescension's
condiment
condiment's
condiments
condition
condition's
conditional
conditionally
conditionals
conditioned
conditioner
conditioner's
conditioners
conditioning
conditioning's
conditions
condo
condoes
condolence
condolence's
condolences
condom
condom's
condominium
condominium's
condominiums
condoms
condone
condoned
condones
condoning
condor
condor's
condores
condors
condos
conducive
conduct
conduct's
conducted
conducting
conductor
conductor's
conductors
conducts
cone
cone's
cones
confection
confection's
confections
confederacies
confederacy
confederacy's
confederate
confederate's
confederated
confederates
confederating
confederation
confederation's
confederations
confer
conference
conference's
conferences
conferred
conferrer
conferring
confers
confess
confessed
confesses
confessing
confession
confession's
confessions
confetti
confetti's
confidant
confidant's
confidants
confide
confided
confidence
confidence's
confidences
confident
confidential
confidentiality
confidentiality's
confidentially
confidently
confides
confiding
configurable
configuration
configuration's
configurations
configure
configured
configures
configuring
confine
confined
confinement
confinement's
confinements
confines
confining
confirm
confirmation
confirmation's
confirmations
confirmed
confirming
confirms
confiscate
confiscated
confiscates
confiscating
confiscation
confiscation's
confiscations
conflict
conflict's
conflicted
conflicting
conflicts
conform
conformed
conforming
conformist
conformist's
conformists
conformity
conformity's
conforms
confound
confounded
confounding
confounds
confront
confrontation
confrontation's
confrontations
confronted
confronting
confronts
confuse
confused
confuses
confusing
confusion
confusion's
congeal
congealed
congealing
congeals
congenial
congenital
congest
congested
congesting
congestion
congestion's
congests
conglomerate
conglomerate's
conglomerated
conglomerates
conglomerating
congratulate
congratulated
congratulates
congratulating
congratulations
congratulatory
congregate
congregated
congregates
congregating
congregation
congregation's
congregations
congress
congress's
congresses
congressional
congressman
congressman's
congressmen
congresswoman
congresswoman's
congresswomen
congruent
conical
conicals
conifer
conifer's
coniferous
conifers
conjecture
conjecture's
conjectured
conjectures
conjecturing
conjugal
conjugate
conjugated
conjugates
conjugating
conjugation
conjugation's
conjugations
conjunction
conjunction's
conjunctions
conjure
conjured
conjures
conjuring
connect
connected
connecting
connection
connection's
connections
connective
connectivity
connectivity's
connector
connector's
connectors
connects
conned
connexion
connexion's
conning
connivance
connivance's
connive
connived
connives
conniving
connoisseur
connoisseur's
connoisseurs
connotation
connotation's
connotations
connote
connoted
connotes
connoting
conquer
conquered
conquering
conqueror
conqueror's
conquerors
conquers
conquest
conquest's
conquests
cons
conscience
conscience's
consciences
conscientious
conscientiously
conscious
consciouses
consciously
consciousness
consciousness's
consciousnesses
consecrate
consecrated
consecrates
consecrating
consecration
consecration's
consecrations
consecutive
consecutively
consensus
consensus's
consensuses
consent
consented
consenting
consents
consequence
consequence's
consequences
consequent
consequential
consequently
conservation
conservation's
conservationist
conservationist's
conservationists
conservatism
conservatism's
conservative
conservatively
conservatives
conservator
conservator's
conservatories
conservators
conservatory
conservatory's
conserve
conserved
conserves
conserving
consider
considerable
considerably
considerate
considerately
consideration
consideration's
considerations
considered
considering
considerings
considers
consign
consigned
consigning
consignment
consignment's
consignments
consigns
consist
consisted
consistencies
consistency
consistency's
consistent
consistently
consisting
consists
consolation
consolation's
consolations
console
consoled
consoles
consolidate
consolidated
consolidates
consolidating
consolidation
consolidation's
consolidations
consoling
consomm
consonant
consonant's
consonants
consort
consorted
consortia
consorting
consortium
consortium's
consortiums
consorts
conspicuous
conspicuously
conspiracies
conspiracy
conspiracy's
conspirator
conspirator's
conspiratorial
conspirators
conspire
conspired
conspires
conspiring
constancy
constancy's
constant
constantly
constants
constellation
constellation's
constellations
consternation
consternation's
constipate
constipated
constipates
constipating
constipation
constipation's
constituencies
constituency
constituency's
constituent
constituents
constitute
constituted
constitutes
constituting
constitution
constitution's
constitutional
constitutionally
constitutionals
constitutions
constrain
constrained
constraining
constrains
constraint
constraint's
constraints
constrict
constricted
constricting
constriction
constriction's
constrictions
constricts
construct
constructed
constructing
construction
construction's
constructions
constructive
constructively
constructs
construe
construed
construes
construing
consul
consul's
consular
consulars
consulate
consulate's
consulates
consuls
consult
consultancy
consultant
consultant's
consultants
consultation
consultation's
consultations
consulted
consulting
consults
consumable
consumables
consume
consumed
consumer
consumer's
consumerism
consumerism's
consumers
consumes
consuming
consumings
consummate
consummated
consummates
consummating
consummation
consummation's
consummations
consumption
consumption's
contact
contact's
contacted
contacting
contacts
contagion
contagion's
contagions
contagious
contain
contained
container
container's
containers
containing
contains
contaminate
contaminated
contaminates
contaminating
contamination
contamination's
contemplate
contemplated
contemplates
contemplating
contemplation
contemplation's
contemplative
contemplatives
contemporaries
contemporary
contempt
contempt's
contemptible
contemptuous
contend
contended
contender
contenders
contending
contends
content
content's
contented
contentedly
contenting
contention
contention's
contentions
contentious
contentment
contentment's
contents
contest
contest's
contestant
contestant's
contestants
contested
contesting
contests
context
context's
contexts
contextual
contiguous
continent
continent's
continental
continentals
continents
contingencies
contingency
contingency's
contingent
contingents
continual
continually
continuation
continuation's
continuations
continue
continued
continues
continuing
continuity
continuity's
continuous
continuously
continuum
continuum's
contort
contorted
contorting
contortion
contortion's
contortions
contorts
contour
contour's
contoured
contouring
contours
contraband
contraband's
contraception
contraception's
contraceptive
contraceptives
contract
contracted
contracting
contraction
contraction's
contractions
contractor
contractor's
contractors
contracts
contractual
contradict
contradicted
contradicting
contradiction
contradiction's
contradictions
contradictory
contradicts
contraption
contraption's
contraptions
contraries
contrary
contrast
contrasted
contrasting
contrasts
contravene
contravened
contravenes
contravening
contravention
contravention's
contraventions
contribute
contributed
contributes
contributing
contribution
contribution's
contributions
contributor
contributor's
contributors
contributory
contrite
contrition
contrition's
contrive
contrived
contrives
contriving
control
controllable
controlled
controller
controller's
controllers
controlling
controls
controversial
controversies
controversy
controversy's
convalesce
convalesced
convalescence
convalescence's
convalescences
convalescent
convalescents
convalesces
convalescing
convection
convection's
convene
convened
convenes
convenience
convenience's
conveniences
convenient
conveniently
convening
convent
convent's
convented
conventing
convention
convention's
conventional
conventionally
conventions
convents
converge
converged
convergence
convergence's
converges
converging
conversant
conversation
conversation's
conversational
conversations
converse
conversed
conversely
converses
conversing
conversion
conversion's
conversions
convert
converted
converter
converter's
converters
convertible
convertibles
converting
converts
convex
convexed
convexes
convexing
convey
conveyance
conveyance's
conveyances
conveyed
conveying
conveys
convict
convicted
convicting
conviction
conviction's
convictions
convicts
convince
convinced
convinces
convincing
convincingly
convivial
convoluted
convoy
convoy's
convoyed
convoying
convoys
convulse
convulsed
convulses
convulsing
convulsion
convulsion's
convulsions
convulsive
coo
cooed
cooing
cook
cook's
cookbook
cookbook's
cookbooks
cooked
cooker
cooker's
cookie
cookie's
cookies
cooking
cooking's
cookout
cookout's
cookouts
cooks
cooky
cool
cooled
cooler
cooler's
coolers
coolest
cooling
coolly
coolness
coolness's
cools
coop
coop's
cooped
cooper
cooper's
cooperate
cooperated
cooperates
cooperating
cooperation
cooperation's
cooperative
cooperatives
cooping
coops
coordinate
coordinated
coordinates
coordinating
coordination
coordination's
coordinator
coordinator's
coordinators
coos
cop
cop's
cope
coped
copes
copied
copier
copier's
copiers
copies
copilot
copilot's
copilots
coping
coping's
copious
copiously
copped
copper
copper's
copperhead
copperhead's
copperheads
coppers
copping
cops
copter
copter's
copters
copulate
copulated
copulates
copulating
copulation
copulation's
copy
copy's
copying
copyright
copyright's
copyrighted
copyrighting
copyrights
coral
coral's
corals
cord
cord's
corded
cordial
cordiality
cordiality's
cordially
cordials
cording
cordless
cordon
cordon's
cordoned
cordoning
cordons
cords
corduroy
corduroy's
core
core's
cored
cores
coring
cork
cork's
corked
corking
corks
corkscrew
corkscrew's
corkscrewed
corkscrewing
corkscrews
corn
corn's
cornbread
cornea
cornea's
corneas
corned
corner
corner's
cornered
cornering
corners
cornerstone
cornerstone's
cornerstones
cornet
cornet's
cornets
cornflakes
cornier
corniest
corning
cornmeal
corns
cornstarch
cornstarch's
corny
corollary
corollary's
coronaries
coronary
coronation
coronation's
coronations
coroner
coroner's
coroners
corporal
corporals
corporate
corporation
corporation's
corporations
corps
corps's
corpse
corpse's
corpses
corpulent
corpus
corpus's
corpuscle
corpuscle's
corpuscles
corral
corral's
corralled
corralling
corrals
correct
corrected
correcter
correctest
correcting
correction
correction's
corrections
corrective
correctives
correctly
correctness
correctness's
corrector
corrector's
corrects
correlate
correlated
correlates
correlating
correlation
correlation's
correlations
correspond
corresponded
correspondence
correspondence's
correspondences
correspondent
correspondent's
correspondents
corresponding
correspondingly
corresponds
corridor
corridor's
corridors
corroborate
corroborated
corroborates
corroborating
corroboration
corroboration's
corroborations
corrode
corroded
corrodes
corroding
corrosion
corrosion's
corrosive
corrosives
corrugate
corrugated
corrugates
corrugating
corrupt
corrupted
corrupter
corruptest
corruptible
corrupting
corruption
corruption's
corruptions
corrupts
corsage
corsage's
corsages
corset
corset's
corseted
corseting
corsets
cortex
cortex's
cosier
cosies
cosiest
cosmetic
cosmetic's
cosmetics
cosmic
cosmology
cosmology's
cosmonaut
cosmonaut's
cosmonauts
cosmopolitan
cosmopolitan's
cosmopolitans
cosmos
cosmos's
cosmoses
cost
cost's
costar
costarred
costarring
costars
costing
costings
costlier
costliest
costly
costs
costume
costume's
costumed
costumes
costuming
cosy
cot
cot's
coting
cots
cottage
cottage's
cottaged
cottages
cottaging
cotted
cotton
cotton's
cottoned
cottoning
cottons
cottontail
cottontail's
cottontails
cottonwood
cottonwood's
cottonwoods
couch
couch's
couched
couches
couching
cougar
cougar's
cougars
cough
coughed
coughing
coughs
could
couldn't
council
council's
councillor
councillor's
councillors
councils
counsel
counsel's
counselings
counselled
counselling
counsellor
counsellor's
counsellors
counsels
count
countable
countdown
countdown's
countdowns
counted
countenance
countenance's
countenanced
countenances
countenancing
counter
counter's
counteract
counteracted
counteracting
counteracts
counterattack
counterattack's
counterattacked
counterattacking
counterattacks
counterbalance
counterbalance's
counterbalanced
counterbalances
counterbalancing
counterclockwise
countered
counterexample
counterfeit
counterfeited
counterfeiter
counterfeiter's
counterfeiters
counterfeiting
counterfeits
countering
counterpart
counterpart's
counterparts
counterproductive
counters
countersign
countersigned
countersigning
countersigns
countess
countess's
countesses
counties
counting
countless
countries
country
country's
countryman
countryman's
countrymen
countryside
countryside's
countrysides
countrywoman
countrywoman's
countrywomen
counts
county
county's
coup
coup's
couple
couple's
coupled
couples
coupling
coupling's
coupon
coupon's
coupons
coups
courage
courage's
courageous
courageously
courier
courier's
couriered
couriering
couriers
course
course's
coursed
courser
courses
coursing
court
court's
courted
courteous
courteously
courtesies
courtesy
courtesy's
courthouse
courthouse's
courthouses
courting
courtroom
courtroom's
courtrooms
courts
courtship
courtship's
courtships
courtyard
courtyard's
courtyards
cousin
cousin's
cousins
cove
cove's
covenant
covenant's
covenanted
covenanting
covenants
cover
coverage
coverage's
coverall
coveralls
covered
covering
covering's
coverings
covers
covers's
covert
covertly
coverts
coves
covet
coveted
coveting
covetous
covets
cow
cow's
coward
coward's
cowardice
cowardice's
cowardly
cowards
cowboy
cowboy's
cowboys
cowed
cower
cowered
cowering
cowers
cowgirl
cowgirl's
cowgirls
cowhide
cowhide's
cowhides
cowing
coworker
coworkers
cows
cox
cox's
coy
coyer
coyest
coyote
coyote's
coyotes
cozily
coziness
coziness's
crab
crab's
crabbed
crabbier
crabbiest
crabbing
crabby
crabs
crack
crackdown
crackdown's
crackdowns
cracked
cracker
cracker's
crackers
cracking
crackle
crackled
crackles
crackling
crackpot
crackpot's
crackpots
cracks
cradle
cradle's
cradled
cradles
cradling
craft
craft's
crafted
craftier
craftiest
craftily
crafting
crafts
craftsman
craftsman's
craftsmanship
craftsmanship's
craftsmen
crafty
crag
crag's
craggier
craggiest
craggy
crags
cram
crammed
cramming
cramp
cramp's
cramped
cramping
cramps
crams
cranberries
cranberry
cranberry's
crane
crane's
craned
cranes
crania
craning
cranium
cranium's
craniums
crank
crank's
cranked
cranker
crankest
crankier
crankiest
cranking
cranks
cranky
crannied
crannies
cranny
cranny's
crannying
crap
crap's
crapped
crappie
crappier
crappies
crappiest
crapping
crappy
craps
crash
crashed
crashes
crashing
crass
crasser
crassest
crate
crate's
crated
crater
crater's
cratered
cratering
craters
crates
crating
cravat
cravat's
cravats
cravatted
cravatting
crave
craved
craves
craving
craving's
cravings
crawfish
crawfish's
crawfishes
crawl
crawled
crawling
crawls
crayfish
crayfish's
crayfishes
crayon
crayon's
crayoned
crayoning
crayons
craze
craze's
crazed
crazes
crazier
crazies
craziest
crazily
craziness
craziness's
crazing
crazy
creak
creaked
creakier
creakiest
creaking
creaks
creaky
cream
cream's
creamed
creamier
creamiest
creaming
creams
creamy
crease
crease's
creased
creases
creasing
create
created
creates
creating
creation
creation's
creations
creative
creatively
creativity
creativity's
creator
creator's
creators
creature
creature's
creatures
credence
credence's
credential
credentials
credibility
credibility's
credible
credibly
credit
credit's
creditable
credited
crediting
creditor
creditor's
creditors
credits
credo
credo's
credos
credulous
creed
creed's
creeds
creek
creek's
creeks
creep
creepier
creepies
creepiest
creeping
creeps
creepy
cremate
cremated
cremates
cremating
cremation
cremation's
cremations
crematoria
crematorium
crematorium's
crematoriums
creole
creole's
creoles
crepe
crepe's
crepes
crept
crescendi
crescendo
crescendo's
crescendos
crescent
crescent's
crescents
crest
crest's
crested
crestfallen
cresting
crests
cretin
cretin's
cretinous
cretins
crevasse
crevasse's
crevasses
crevice
crevice's
crevices
crew
crew's
crewed
crewing
crews
crib
crib's
cribbed
cribbing
cribs
crick
crick's
cricked
cricket
cricket's
crickets
cricking
cricks
cried
cries
crime
crime's
crimed
crimes
criminal
criminal's
criminally
criminals
criming
crimp
crimped
crimping
crimps
crimson
crimson's
crimsoned
crimsoning
crimsons
cringe
cringed
cringes
cringing
crinkle
crinkled
crinkles
crinklier
crinklies
crinkliest
crinkling
crinkly
cripple
cripple's
crippled
cripples
crippling
crises
crisis
crisis's
crisp
crisped
crisper
crispest
crispier
crispiest
crisping
crisply
crisps
crispy
crisscross
crisscrossed
crisscrosses
crisscrossing
criteria
criterion
criterion's
criterions
critic
critic's
critical
critically
criticise
criticised
criticises
criticising
criticism
criticism's
criticisms
critics
critique
critique's
critiqued
critiques
critiquing
critter
critter's
critters
croak
croaked
croaking
croaks
crochet
crocheted
crocheting
crochets
croci
crock
crock's
crockery
crockery's
crocks
crocodile
crocodile's
crocodiles
crocus
crocus's
crocuses
crofts
croissant
croissant's
croissants
cronies
crony
crony's
crook
crook's
crooked
crookeder
crookedest
crooking
crooks
croon
crooned
crooner
crooner's
crooners
crooning
croons
crop
crop's
cropped
cropping
crops
croquet
croquet's
cross
cross's
crossbow
crossbow's
crossbows
crosscheck
crosschecked
crosschecking
crosschecks
crossed
crosser
crosses
crossest
crossfire
crossfire's
crossfires
crossing
crossing's
crossings
crossover
crossover's
crossovers
crossroad
crossroads
crossroads's
crosstown
crosswalk
crosswalk's
crosswalks
crossword
crosswords
crotch
crotch's
crotches
crouch
crouched
crouches
crouching
crow
crow's
crowbar
crowbar's
crowbars
crowd
crowd's
crowded
crowding
crowds
crowed
crowing
crown
crown's
crowned
crowning
crowns
crows
crucial
crucially
crucified
crucifies
crucifix
crucifix's
crucifixes
crucifixion
crucifixion's
crucifixions
crucify
crucifying
crud
crud's
cruddier
cruddiest
cruddy
crude
crudely
cruder
crudest
crudity
crudity's
cruel
crueler
cruelest
crueller
cruellest
cruelly
cruels
cruelties
cruelty
cruelty's
cruise
cruised
cruiser
cruiser's
cruisers
cruises
cruising
crumb
crumb's
crumbed
crumbing
crumble
crumbled
crumbles
crumblier
crumblies
crumbliest
crumbling
crumbly
crumbs
crummier
crummiest
crummy
crumple
crumpled
crumples
crumpling
crunch
crunched
crunches
crunchier
crunchiest
crunching
crunchy
crusade
crusade's
crusaded
crusader
crusader's
crusaders
crusades
crusading
crush
crushed
crushes
crushing
crust
crust's
crustacean
crustacean's
crustaceans
crusted
crustier
crusties
crustiest
crusting
crusts
crusty
crutch
crutch's
crutches
crux
crux's
cruxes
cry
crybabies
crybaby
crybaby's
crying
cryings
crypt
crypt's
cryptic
cryptically
crypts
crystal
crystal's
crystallisation
crystallisation's
crystallise
crystallised
crystallises
crystallising
crystals
cs
cs's
cub
cub's
cube
cube's
cubed
cubes
cubic
cubicle
cubicle's
cubicles
cubing
cubs
cuckoo
cuckoo's
cuckoos
cucumber
cucumber's
cucumbers
cuddle
cuddled
cuddles
cuddlier
cuddliest
cuddling
cuddly
cue
cue's
cued
cueing
cues
cuff
cuff's
cuffed
cuffing
cuffs
cuing
cuisine
cuisine's
cuisines
culinary
cull
culled
culling
culls
culminate
culminated
culminates
culminating
culmination
culmination's
culminations
culpability
culpability's
culpable
culprit
culprit's
culprits
cult
cult's
cultivate
cultivated
cultivates
cultivating
cultivation
cultivation's
cults
cultural
culturally
culture
culture's
cultured
cultures
culturing
cumbersome
cumming
cums
cumulative
cunning
cunninger
cunningest
cunningly
cup
cup's
cupboard
cupboard's
cupboards
cupcake
cupcake's
cupcakes
cupful
cupful's
cupfuls
cupped
cupping
cups
cupsful
cur
cur's
curable
curator
curator's
curators
curb
curb's
curbed
curbing
curbs
curd
curd's
curdle
curdled
curdles
curdling
curds
cure
cured
cures
curfew
curfew's
curfews
curing
curio
curio's
curios
curiosities
curiosity
curiosity's
curious
curiouser
curiousest
curiously
curl
curled
curler
curler's
curlers
curlier
curliest
curling
curling's
curls
curly
currant
currant's
currants
currencies
currency
currency's
current
currently
currents
curricula
curriculum
curriculum's
curriculums
curried
curries
curry
curry's
currying
curse
curse's
cursed
curseder
cursedest
curses
cursing
cursor
cursor's
cursored
cursores
cursoring
cursors
cursory
curst
curt
curtail
curtailed
curtailing
curtails
curtain
curtain's
curtained
curtaining
curtains
curter
curtest
curtsied
curtsies
curtsy
curtsy's
curtsying
curvature
curvature's
curvatures
curve
curve's
curved
curved's
curves
curvier
curviest
curving
curvy
cushion
cushion's
cushioned
cushioning
cushions
cuss
cuss's
cussed
cusses
cussing
custard
custard's
custards
custodial
custodian
custodian's
custodians
custody
custody's
custom
custom's
customarily
customary
customer
customer's
customers
customisation
customise
customised
customises
customising
customs
cut
cutback
cutback's
cutbacks
cute
cutely
cuteness
cuteness's
cuter
cutes
cutest
cuticle
cuticle's
cuticles
cutlery
cutlery's
cutlet
cutlet's
cutlets
cutoff
cutoff's
cutoffs
cuts
cutter
cutter's
cutters
cutthroat
cutthroat's
cutthroats
cutting
cutting's
cuttings
cyanide
cyanide's
cybernetics
cybernetics's
cyberspace
cycle
cycle's
cycled
cycles
cyclic
cyclical
cycling
cycling's
cyclist
cyclist's
cyclists
cyclone
cyclone's
cyclones
cylinder
cylinder's
cylinders
cylindrical
cymbal
cymbal's
cymbals
cynic
cynic's
cynical
cynically
cynicism
cynicism's
cynics
cypress
cypress's
cypresses
cyst
cyst's
cysts
d
dab
dabbed
dabbing
dabble
dabbled
dabbles
dabbling
dabs
dachshund
dachshund's
dachshunds
dad
dad's
daddies
daddy
daddy's
dads
daemon
daemon's
daffodil
daffodil's
daffodils
daft
dagger
dagger's
daggers
dailies
daily
daintier
dainties
daintiest
daintily
dainty
dairies
dairy
dairy's
dais
dais's
daises
daisies
daisy
daisy's
dallied
dallies
dally
dallying
dam
dam's
damage
damage's
damaged
damages
damaging
dame
dame's
dames
dammed
damming
damn
damnation
damnation's
damndest
damned
damneder
damnedest
damning
damns
damp
damped
dampen
dampened
dampening
dampens
damper
damper's
dampers
dampest
damping
dampness
dampness's
damps
dams
damsel
damsel's
damsels
dance
danced
dancer
dancer's
dancers
dances
dancing
dandelion
dandelion's
dandelions
dandier
dandies
dandiest
dandruff
dandruff's
dandy
dandy's
danger
danger's
dangered
dangering
dangerous
dangerously
dangers
dangle
dangled
dangles
dangling
dank
danker
dankest
dapper
dapperer
dapperest
dappers
dare
dared
daredevil
daredevil's
daredevils
dares
daring
dark
darken
darkened
darkening
darkens
darker
darkest
darklier
darkliest
darkly
darkness
darkness's
darkroom
darkroom's
darkrooms
darling
darling's
darlings
darn
darned
darneder
darnedest
darning
darns
dart
dart's
darted
darting
darts
dash
dashboard
dashboard's
dashboards
dashed
dashes
dashing
dastardly
data
data's
database
databased
databases
databasing
date
date's
dated
dates
dating
datum
datum's
daub
daubed
daubing
daubs
daughter
daughter's
daughters
daunt
daunted
daunting
dauntless
daunts
dawdle
dawdled
dawdles
dawdling
dawn
dawn's
dawned
dawning
dawns
day
day's
daybreak
daybreak's
daydream
daydream's
daydreamed
daydreamer
daydreamer's
daydreamers
daydreaming
daydreams
daydreamt
daylight
daylight's
days
daytime
daytime's
daze
dazed
dazes
dazing
dazzle
dazzled
dazzles
dazzling
dazzlings
deacon
deacon's
deaconess
deaconess's
deaconesses
deacons
dead
deaden
deadened
deadening
deadens
deader
deadest
deadlier
deadliest
deadline
deadline's
deadlined
deadlines
deadlining
deadlock
deadlock's
deadlocked
deadlocking
deadlocks
deadly
deadpan
deadpanned
deadpanning
deadpans
deaf
deafen
deafened
deafening
deafening's
deafens
deafer
deafest
deafness
deafness's
deal
dealer
dealer's
dealers
dealership
dealership's
dealerships
dealing
dealing's
dealings
deals
dealt
dean
dean's
deaned
deaning
deans
dear
dearer
dearest
dearly
dears
dearth
dearth's
dearths
death
death's
deathbed
deathbed's
deathbeds
deaths
deathtrap
deathtrap's
deathtraps
deaves
debase
debased
debasement
debasement's
debasements
debases
debasing
debatable
debate
debate's
debated
debates
debating
debaucheries
debauchery
debauchery's
debilitate
debilitated
debilitates
debilitating
debilities
debility
debility's
debit
debit's
debited
debiting
debits
debonair
debrief
debriefed
debriefing
debriefings
debriefs
debris
debris's
debt
debt's
debtor
debtor's
debtors
debts
debug
debugged
debugger
debugging
debugs
debunk
debunked
debunking
debunks
debut
debut's
debuted
debuting
debuts
decade
decade's
decadence
decadence's
decadent
decadents
decades
decaf
decaffeinate
decaffeinated
decaffeinates
decaffeinating
decal
decal's
decals
decanter
decanter's
decanters
decapitate
decapitated
decapitates
decapitating
decathlon
decathlon's
decathlons
decay
decayed
decaying
decays
decease
deceased
deceases
deceasing
deceit
deceit's
deceitful
deceitfully
deceitfulness
deceitfulness's
deceits
deceive
deceived
deceives
deceiving
decencies
decency
decency's
decent
decenter
decentest
decently
decentralisation
decentralisation's
decentralise
decentralised
decentralises
decentralising
deception
deception's
deceptions
deceptive
deceptively
decibel
decibel's
decibels
decide
decided
decidedly
decides
deciding
deciduous
decimal
decimal's
decimals
decimate
decimated
decimates
decimating
decipher
deciphered
deciphering
deciphers
decision
decision's
decisions
decisive
decisively
deck
deck's
decked
decking
decks
declaration
declaration's
declarations
declare
declared
declares
declaring
declension
declension's
decline
declined
declines
declining
decode
decoded
decoder
decoder's
decodes
decoding
decompose
decomposed
decomposes
decomposing
decomposition
decomposition's
decor
decorate
decorated
decorates
decorating
decoration
decoration's
decorations
decorative
decorator
decorator's
decorators
decorous
decors
decorum
decorum's
decoy
decoy's
decoyed
decoying
decoys
decrease
decreased
decreases
decreasing
decree
decree's
decreed
decreeing
decrees
decrepit
decried
decries
decriminalise
decriminalised
decriminalises
decriminalising
decry
decrying
dedicate
dedicated
dedicates
dedicating
dedication
dedication's
dedications
deduce
deduced
deduces
deducing
deduct
deducted
deductible
deductibles
deducting
deduction
deduction's
deductions
deductive
deducts
deed
deed's
deeded
deeding
deeds
deem
deemed
deeming
deems
deep
deepen
deepened
deepening
deepens
deeper
deepest
deeply
deeps
deer
deer's
deers
deface
defaced
defaces
defacing
defamation
defamation's
defamatory
defame
defamed
defames
defaming
default
default's
defaulted
defaulting
defaults
defeat
defeated
defeating
defeatist
defeatist's
defeatists
defeats
defecate
defecated
defecates
defecating
defect
defect's
defected
defecting
defection
defection's
defections
defective
defectives
defector
defector's
defectors
defects
defence
defence's
defenced
defenceless
defences
defencing
defencive
defend
defendant
defendant's
defendants
defended
defender
defender's
defenders
defending
defends
defensible
defensively
defer
deference
deference's
deferential
deferred
deferring
defers
defiance
defiance's
defiant
defiantly
deficiencies
deficiency
deficiency's
deficient
deficit
deficit's
deficits
defied
defies
defile
defiled
defiles
defiling
definable
define
defined
defines
defining
definite
definitely
definition
definition's
definitions
definitive
definitively
deflate
deflated
deflates
deflating
deflation
deflation's
deflect
deflected
deflecting
deflection
deflection's
deflections
deflects
deforestation
deforestation's
deform
deformation
deformation's
deformations
deformed
deforming
deformities
deformity
deformity's
deforms
defraud
defrauded
defrauding
defrauds
defrost
defrosted
defrosting
defrosts
deft
defter
deftest
deftly
defunct
defuncts
defuse
defused
defuses
defusing
defy
defying
degenerate
degenerated
degenerates
degenerating
degeneration
degeneration's
degradation
degradation's
degrade
degraded
degrades
degrading
degree
degree's
degrees
dehydrate
dehydrated
dehydrates
dehydrating
dehydration
dehydration's
deified
deifies
deify
deifying
deign
deigned
deigning
deigns
deities
deity
deity's
deject
dejected
dejectedly
dejecting
dejection
dejection's
dejects
delay
delayed
delaying
delays
delectable
delegate
delegate's
delegated
delegates
delegating
delegation
delegation's
delegations
delete
deleted
deleterious
deletes
deleting
deletion
deletion's
deletions
deli
deli's
deliberate
deliberated
deliberately
deliberates
deliberating
deliberation
deliberation's
deliberations
delicacies
delicacy
delicacy's
delicate
delicately
delicatessen
delicatessen's
delicatessens
delicious
deliciously
delight
delighted
delightful
delightfully
delighting
delights
delimit
delimited
delimiter
delimiters
delimiting
delimits
delineate
delineated
delineates
delineating
delinquencies
delinquency
delinquency's
delinquent
delinquent's
delinquents
deliria
delirious
deliriously
delirium
delirium's
deliriums
delis
deliver
deliverance
deliverance's
delivered
deliveries
delivering
delivers
delivery
delivery's
delta
delta's
deltas
delude
deluded
deludes
deluding
deluge
deluge's
deluged
deluges
deluging
delusion
delusion's
delusions
deluxe
delve
delved
delves
delving
demagogic
demagogue
demagogue's
demagogues
demand
demanded
demanding
demands
demean
demeaned
demeaning
demeanour
demeanour's
demeans
demented
dementia
dementia's
demerit
demerit's
demerited
demeriting
demerits
demise
demise's
demised
demises
demising
demo
demo's
democracies
democracy
democracy's
democrat
democrat's
democratic
democratically
democrats
demoed
demographic
demographics
demoing
demolish
demolished
demolishes
demolishing
demolition
demolition's
demolitions
demon
demon's
demonic
demons
demonstrably
demonstrate
demonstrated
demonstrates
demonstrating
demonstration
demonstration's
demonstrations
demonstrative
demonstratives
demonstrator
demonstrator's
demonstrators
demoralise
demoralised
demoralises
demoralising
demos
demote
demoted
demotes
demoting
demotion
demotion's
demotions
demount
demure
demurely
demurer
demurest
den
den's
denial
denial's
denials
denied
denies
denigrate
denigrated
denigrates
denigrating
denim
denim's
denims
denomination
denomination's
denominations
denominator
denominator's
denominators
denote
denoted
denotes
denoting
denounce
denounced
denounces
denouncing
dens
dense
densely
denser
densest
densities
density
density's
dent
dent's
dental
dented
denting
dentist
dentist's
dentistry
dentistry's
dentists
dents
denture
dentures
denunciation
denunciation's
denunciations
deny
denying
deodorant
deodorant's
deodorants
deodorise
deodorised
deodorises
deodorising
depart
departed
departing
department
department's
departmental
departments
departs
departure
departure's
departures
depend
dependable
dependant
dependant's
dependants
depended
dependence
dependence's
dependencies
dependency
dependency's
dependent
dependent's
dependents
depending
depends
depict
depicted
depicting
depiction
depiction's
depicts
deplete
depleted
depletes
depleting
depletion
depletion's
deplorable
deplorably
deplore
deplored
deplores
deploring
deploy
deployed
deploying
deployment
deployment's
deployments
deploys
deport
deportation
deportation's
deportations
deported
deporting
deportment
deportment's
deports
depose
deposed
deposes
deposing
deposit
deposited
depositing
deposits
depot
depot's
depots
deprave
depraved
depraves
depraving
depravities
depravity
depravity's
deprecate
deprecated
deprecates
deprecating
depreciate
depreciated
depreciates
depreciating
depreciation
depreciation's
depress
depressed
depresses
depressing
depressingly
depression
depression's
depressions
deprivation
deprivation's
deprivations
deprive
deprived
deprives
depriving
depth
depth's
depths
deputies
deputy
deputy's
derail
derailed
derailing
derailment
derailment's
derailments
derails
derange
deranged
deranges
deranging
derbies
derby
derby's
derelict
derelicts
deres
deride
derided
derides
deriding
derision
derision's
derivation
derivation's
derivations
derivative
derivatives
derive
derived
derives
deriving
derogatory
derrick
derrick's
derricks
descend
descendant
descendant's
descendants
descended
descending
descends
descent
descent's
descents
describable
describe
described
describes
describing
description
description's
descriptions
descriptive
descriptor
descriptors
desecrate
desecrated
desecrates
desecrating
desecration
desecration's
desegregate
desegregated
desegregates
desegregating
desegregation
desegregation's
desert
desert's
deserted
deserter
deserter's
deserters
deserting
deserts
deserve
deserved
deserves
deserving
deservings
design
designate
designated
designates
designating
designation
designation's
designations
designed
designer
designer's
designers
designing
designs
desirability
desirability's
desirable
desire
desired
desires
desiring
desirous
desist
desisted
desisting
desists
desk
desk's
desks
desktop
desktops
desolate
desolated
desolates
desolating
desolation
desolation's
despair
despaired
despairing
despairs
despatch
despatched
despatches
despatching
desperate
desperately
desperation
desperation's
despicable
despise
despised
despises
despising
despite
despondent
despondently
despot
despot's
despotic
despots
dessert
dessert's
desserts
destabilise
destination
destination's
destinations
destine
destined
destines
destinies
destining
destiny
destiny's
destitute
destitution
destitution's
destroy
destroyed
destroyer
destroyer's
destroyers
destroying
destroys
destruction
destruction's
destructive
detach
detachable
detached
detaches
detaching
detachment
detachment's
detachments
detail
detail's
detailed
detailing
details
detain
detained
detaining
detains
detect
detectable
detected
detecting
detection
detection's
detective
detective's
detectives
detector
detector's
detectors
detects
detentes
detention
detention's
detentions
deter
detergent
detergent's
detergents
deteriorate
deteriorated
deteriorates
deteriorating
deterioration
deterioration's
determinable
determination
determination's
determinations
determine
determined
determiner
determiner's
determiners
determines
determining
determinism
determinism's
deterministic
deterred
deterrence
deterrence's
deterrent
deterrent's
deterrents
deterring
deters
detest
detested
detesting
detests
dethrone
dethroned
dethrones
dethroning
detonate
detonated
detonates
detonating
detonation
detonation's
detonations
detonator
detonator's
detonators
detour
detour's
detoured
detouring
detours
detox
detoxed
detoxes
detoxing
detract
detracted
detracting
detracts
detriment
detriment's
detrimental
detriments
devaluation
devaluation's
devaluations
devalue
devalued
devalues
devaluing
devastate
devastated
devastates
devastating
devastation
devastation's
develop
developed
developer
developer's
developers
developing
development
development's
developments
develops
deviant
deviants
deviate
deviated
deviates
deviating
deviation
deviation's
deviations
device
device's
devices
devil
devil's
devilish
devilled
devilling
devils
devious
devise
devised
devises
devising
devoid
devolution
devolution's
devolve
devolved
devolves
devolving
devote
devoted
devotedly
devotee
devotee's
devotees
devotes
devoting
devotion
devotion's
devotions
devour
devoured
devouring
devours
devout
devouter
devoutest
devoutly
dew
dew's
dexterity
dexterity's
dexterous
diabetes
diabetes's
diabetic
diabetics
diabolical
diagnose
diagnosed
diagnoses
diagnosing
diagnosis
diagnosis's
diagnostic
diagnostics
diagnostics's
diagonal
diagonally
diagonals
diagram
diagram's
diagramed
diagraming
diagrammed
diagramming
diagrams
dial
dial's
dialect
dialect's
dialects
dialled
dialling
diallings
dialog
dialogs
dialogue
dialogue's
dialogues
dials
diameter
diameter's
diameters
diametrically
diamond
diamond's
diamonds
diaper
diaper's
diapered
diapering
diapers
diaphragm
diaphragm's
diaphragms
diaries
diarrhoea
diarrhoea's
diary
diary's
diatribe
diatribe's
dice
diced
dices
dicey
dichotomies
dichotomy
dichotomy's
dicier
diciest
dicing
dick
dick's
dicks
dictate
dictated
dictates
dictating
dictation
dictation's
dictations
dictator
dictator's
dictatorial
dictators
dictatorship
dictatorship's
dictatorships
diction
diction's
dictionaries
dictionary
dictionary's
did
didn't
die
died
diehard
diehards
dieing
dies
dies's
diesel
diesel's
dieseled
dieseling
diesels
diet
diet's
dietaries
dietary
dieted
dieting
diets
differ
differed
difference
difference's
differences
different
differential
differentiate
differentiated
differentiates
differentiating
differentiation
differentiation's
differently
differing
differs
difficult
difficulties
difficulty
difficulty's
diffuse
diffused
diffuses
diffusing
diffusion
diffusion's
dig
digest
digested
digestible
digesting
digestion
digestion's
digestions
digestive
digests
digger
digging
digit
digit's
digital
digitally
digitise
digitised
digitises
digitising
digits
dignified
dignifies
dignify
dignifying
dignitaries
dignitary
dignitary's
dignities
dignity
dignity's
digress
digressed
digresses
digressing
digression
digression's
digressions
digs
dike
dike's
dikes
dilapidated
dilapidation
dilapidation's
dilate
dilated
dilates
dilating
dilation
dilation's
dilemma
dilemma's
dilemmas
diligence
diligence's
diligent
diligently
dill
dill's
dilled
dilling
dills
dilute
diluted
dilutes
diluting
dilution
dilution's
dim
dime
dime's
dimension
dimension's
dimensional
dimensions
dimer
dimes
diminish
diminished
diminishes
diminishing
diminutive
diminutives
dimly
dimmed
dimmer
dimmest
dimming
dimple
dimple's
dimpled
dimples
dimpling
dims
din
din's
dine
dined
diner
diner's
diners
dines
dinghies
dinghy
dinghy's
dingier
dingies
dingiest
dingy
dining
dinned
dinner
dinner's
dinnered
dinnering
dinners
dinning
dinosaur
dinosaur's
dinosaurs
dins
diocese
diocese's
dioceses
dioxide
dioxide's
dip
diphtheria
diphtheria's
diphthong
diphthong's
diphthongs
diploma
diploma's
diplomacy
diplomacy's
diplomas
diplomat
diplomat's
diplomata
diplomatic
diplomatically
diplomatics
diplomats
dipped
dipping
dips
dipstick
dipstick's
dipsticks
dire
direct
directed
directer
directest
directing
direction
direction's
directions
directive
directive's
directives
directly
directness
directness's
director
director's
directories
directors
directory
directory's
directs
direr
direst
dirge
dirge's
dirges
dirt
dirt's
dirtied
dirtier
dirties
dirtiest
dirty
dirtying
dis
dis's
disabilities
disability
disability's
disable
disabled
disables
disabling
disadvantage
disadvantage's
disadvantaged
disadvantageous
disadvantages
disadvantaging
disaffect
disaffected
disaffecting
disaffects
disagree
disagreeable
disagreeably
disagreed
disagreeing
disagreement
disagreement's
disagreements
disagrees
disallow
disallowed
disallowing
disallows
disambiguate
disappear
disappearance
disappearance's
disappearances
disappeared
disappearing
disappears
disappoint
disappointed
disappointing
disappointingly
disappointment
disappointment's
disappointments
disappoints
disapproval
disapproval's
disapprove
disapproved
disapproves
disapproving
disapprovingly
disarm
disarmament
disarmament's
disarmed
disarming
disarms
disarray
disarray's
disarrayed
disarraying
disarrays
disaster
disaster's
disasters
disastrous
disastrously
disavow
disavowal
disavowal's
disavowals
disavowed
disavowing
disavows
disband
disbanded
disbanding
disbands
disbelief
disbelief's
disbelieve
disbelieved
disbelieves
disbelieving
disburse
disbursed
disbursement
disbursement's
disbursements
disburses
disbursing
disc
disc's
discard
discarded
discarding
discards
discern
discerned
discernible
discerning
discerns
discharge
discharged
discharges
discharging
disciple
disciple's
disciples
disciplinarian
disciplinarian's
disciplinarians
disciplinary
discipline
discipline's
disciplined
disciplines
disciplining
disclaim
disclaimed
disclaimer
disclaimer's
disclaimers
disclaiming
disclaims
disclose
disclosed
discloses
disclosing
disclosure
disclosure's
disclosures
disco
disco's
discoed
discoing
discolour
discolouration
discolouration's
discolourations
discoloured
discolouring
discolours
discomfort
discomfort's
discomforted
discomforting
discomforts
disconcert
disconcerted
disconcerting
disconcerts
disconnect
disconnected
disconnecting
disconnection
disconnection's
disconnections
disconnects
disconsolate
disconsolately
discontent
discontent's
discontented
discontenting
discontents
discontinuation
discontinuation's
discontinuations
discontinue
discontinued
discontinues
discontinuing
discontinuity
discontinuity's
discord
discord's
discordant
discorded
discording
discords
discos
discount
discounted
discounting
discounts
discourage
discouraged
discouragement
discouragement's
discouragements
discourages
discouraging
discourse
discourse's
discoursed
discourses
discoursing
discourteous
discourtesies
discourtesy
discourtesy's
discover
discovered
discoverer
discoverer's
discoverers
discoveries
discovering
discovers
discovery
discovery's
discredit
discredited
discrediting
discredits
discreet
discreeter
discreetest
discreetly
discrepancies
discrepancy
discrepancy's
discrete
discretion
discretion's
discretionary
discriminate
discriminated
discriminates
discriminating
discrimination
discrimination's
discriminatory
discs
discus
discus's
discuses
discuss
discussed
discusses
discussing
discussion
discussion's
discussions
disdain
disdain's
disdained
disdainful
disdaining
disdains
disease
disease's
diseased
diseases
disembark
disembarkation
disembarkation's
disembarked
disembarking
disembarks
disenchant
disenchanted
disenchanting
disenchantment
disenchantment's
disenchants
disenfranchise
disenfranchised
disenfranchises
disenfranchising
disengage
disengaged
disengages
disengaging
disentangle
disentangled
disentangles
disentangling
disfavour
disfavour's
disfavoured
disfavouring
disfavours
disfigure
disfigured
disfigurement
disfigurement's
disfigurements
disfigures
disfiguring
disgrace
disgrace's
disgraced
disgraceful
disgracefully
disgraces
disgracing
disgruntle
disgruntled
disgruntles
disgruntling
disguise
disguised
disguises
disguising
disgust
disgusted
disgusting
disgustingly
disgusts
dish
dish's
dishearten
disheartened
disheartening
disheartens
dished
dishes
dishevel
dishevelled
dishevelling
dishevels
dishing
dishonest
dishonestly
dishonesty
dishonesty's
dishonour
dishonourable
dishonourably
dishonoured
dishonouring
dishonours
dishtowel
dishtowel's
dishtowels
dishwasher
dishwasher's
dishwashers
disillusion
disillusioned
disillusioning
disillusionment
disillusionment's
disillusions
disincentive
disincentive's
disinfect
disinfectant
disinfectant's
disinfectants
disinfected
disinfecting
disinfects
disingenuous
disinherit
disinherited
disinheriting
disinherits
disintegrate
disintegrated
disintegrates
disintegrating
disintegration
disintegration's
disinterest
disinterest's
disinterested
disinterests
disjoint
disjointed
disjointing
disjoints
disk
disk's
diskette
diskettes
disks
dislike
disliked
dislikes
disliking
dislocate
dislocated
dislocates
dislocating
dislocation
dislocation's
dislocations
dislodge
dislodged
dislodges
dislodging
disloyal
disloyalty
disloyalty's
dismal
dismaler
dismalest
dismaller
dismallest
dismally
dismantle
dismantled
dismantles
dismantling
dismay
dismayed
dismaying
dismays
dismember
dismembered
dismembering
dismembers
dismiss
dismissal
dismissal's
dismissals
dismissed
dismisses
dismissing
dismissive
dismount
dismounted
dismounting
dismounts
disobedience
disobedience's
disobedient
disobey
disobeyed
disobeying
disobeys
disorder
disorder's
disordered
disordering
disorderly
disorders
disorganisation
disorganisation's
disorganise
disorganised
disorganises
disorganising
disorient
disorientation
disorientation's
disoriented
disorienting
disorients
disown
disowned
disowning
disowns
disparage
disparaged
disparages
disparaging
disparate
disparates
disparities
disparity
disparity's
dispassionate
dispassionately
dispatch
dispatched
dispatches
dispatching
dispel
dispelled
dispelling
dispels
dispensable
dispensaries
dispensary
dispensary's
dispensation
dispensation's
dispensations
dispense
dispensed
dispenser
dispenser's
dispensers
dispenses
dispensing
dispersal
dispersal's
disperse
dispersed
disperses
dispersing
dispersion
dispersion's
dispirit
dispirited
dispiriting
dispirits
displace
displaced
displacement
displacement's
displacements
displaces
displacing
display
displayed
displaying
displays
displease
displeased
displeases
displeasing
displeasure
displeasure's
disposable
disposables
disposal
disposal's
disposals
dispose
disposed
disposes
disposing
disposition
disposition's
dispositions
dispossess
dispossessed
dispossesses
dispossessing
disproportionate
disproportionated
disproportionately
disproportionates
disproportionating
disprove
disproved
disproven
disproves
disproving
dispute
disputed
disputes
disputing
disqualification
disqualification's
disqualifications
disqualified
disqualifies
disqualify
disqualifying
disquiet
disquiet's
disquieted
disquieting
disquiets
disregard
disregarded
disregarding
disregards
disrepair
disrepair's
disreputable
disrepute
disrepute's
disrespect
disrespect's
disrespected
disrespectful
disrespectfully
disrespecting
disrespects
disrupt
disrupted
disrupting
disruption
disruption's
disruptions
disruptive
disrupts
diss
dissatisfaction
dissatisfaction's
dissatisfied
dissatisfies
dissatisfy
dissatisfying
dissect
dissected
dissecting
dissection
dissection's
dissections
dissects
dissed
disseminate
disseminated
disseminates
disseminating
dissemination
dissemination's
dissension
dissension's
dissensions
dissent
dissented
dissenter
dissenter's
dissenters
dissenting
dissents
dissertation
dissertation's
dissertations
disservice
disservice's
disservices
disses
dissidence
dissidence's
dissident
dissidents
dissimilar
dissimilarities
dissimilarity
dissimilarity's
dissimilars
dissing
dissipate
dissipated
dissipates
dissipating
dissipation
dissipation's
dissociate
dissociated
dissociates
dissociating
dissociation
dissociation's
dissolute
dissolutes
dissolution
dissolution's
dissolve
dissolved
dissolves
dissolving
dissonance
dissonance's
dissonances
dissuade
dissuaded
dissuades
dissuading
distance
distance's
distanced
distances
distancing
distant
distantly
distaste
distaste's
distasteful
distastefully
distastes
distend
distended
distending
distends
distention
distention's
distentions
distil
distill
distillation
distillation's
distillations
distilled
distiller
distiller's
distilleries
distillers
distillery
distillery's
distilling
distills
distils
distinct
distincter
distinctest
distinction
distinction's
distinctions
distinctive
distinctively
distinctly
distinguish
distinguishable
distinguished
distinguishes
distinguishing
distort
distorted
distorter
distorter's
distorting
distortion
distortion's
distortions
distorts
distract
distracted
distracting
distraction
distraction's
distractions
distracts
distraught
distress
distressed
distresses
distressing
distressingly
distribute
distributed
distributes
distributing
distribution
distribution's
distributions
distributor
distributor's
distributors
district
district's
districts
distrust
distrusted
distrustful
distrustfully
distrusting
distrusts
disturb
disturbance
disturbance's
disturbances
disturbed
disturbing
disturbs
disuse
disuse's
disused
disuses
disusing
ditch
ditch's
ditched
ditches
ditching
dither
dithered
dithering
dithers
ditties
ditto
ditto's
dittoed
dittoes
dittoing
dittos
ditty
ditty's
dive
dived
dived's
diver
diver's
diverge
diverged
divergence
divergence's
divergences
divergent
diverges
diverging
divers
diverse
diversification
diversification's
diversified
diversifies
diversify
diversifying
diversion
diversion's
diversions
diversities
diversity
diversity's
divert
diverted
diverting
diverts
dives
divest
divested
divesting
divests
divide
divided
dividend
dividend's
dividends
divider
divider's
dividers
divides
dividing
divine
divined
divinely
diviner
divines
divinest
diving
divining
divinities
divinity
divinity's
divisible
division
division's
divisions
divisive
divisor
divisor's
divisors
divorce
divorce's
divorced
divorces
divorcing
divorce
divorce's
divorces
divulge
divulged
divulges
divulging
dizzied
dizzier
dizzies
dizziest
dizziness
dizziness's
dizzy
dizzying
do
docile
dock
dock's
docked
docket
docket's
docketed
docketing
dockets
docking
docks
doctor
doctor's
doctorate
doctorate's
doctorates
doctored
doctoring
doctors
doctrine
doctrine's
doctrines
document
document's
documentaries
documentary
documentation
documentation's
documented
documenting
documents
dodge
dodged
dodges
dodging
dodo
dodo's
doe
doe's
doer
doer's
doers
does
doesn't
doest
dog
dog's
dogged
doggedly
doggerel
doggerel's
dogging
doggone
doggoned
doggoner
doggones
doggonest
doggoning
doghouse
doghouse's
doghouses
dogma
dogma's
dogmas
dogmata
dogmatic
dogmatics
dogs
dogwood
dogwood's
dogwoods
doilies
doily
doily's
doing
doing's
doldrums
doldrums's
dole
dole's
doled
doleful
dolefuller
dolefullest
dolefully
doles
doling
doll
doll's
dollar
dollar's
dollars
dolled
dollhouse
dollhouse's
dollhouses
dollies
dolling
dollop
dollop's
dolloped
dolloping
dollops
dolls
dolly
dolly's
dolphin
dolphin's
dolphins
domain
domain's
domains
dome
dome's
domed
domes
domestic
domesticate
domesticated
domesticates
domesticating
domesticity
domesticity's
domestics
domicile
domicile's
domiciled
domiciles
domiciling
dominance
dominance's
dominant
dominants
dominate
dominated
dominates
dominating
domination
domination's
domineer
domineered
domineering
domineers
doming
dominion
dominion's
dominions
domino
domino's
dominoes
dominos
don
don't
donate
donated
donates
donating
donation
donation's
donations
done
donkey
donkey's
donkeys
donor
donor's
donors
dons
donut
donuts
doodad
doodad's
doodads
doodle
doodled
doodles
doodling
doohickey
doohickey's
doohickeys
doom
doom's
doomed
dooming
dooms
doomsday
doomsday's
door
door's
doorbell
doorbell's
doorbells
doored
dooring
doorknob
doorknob's
doorknobs
doorman
doorman's
doormat
doormat's
doormats
doormen
doors
doorstep
doorstep's
doorstepped
doorstepping
doorsteps
doorway
doorway's
doorways
dope
dope's
doped
dopes
dopey
dopier
dopiest
doping
dopy
dork
dorkier
dorkiest
dorks
dorky
dorm
dorm's
dormant
dormants
dormitories
dormitory
dormitory's
dorms
dorsal
dorsals
dos
dosage
dosage's
dosages
dose
dose's
dosed
doses
dosing
dosses
dossier
dossier's
dossiers
dot
dot's
dote
doted
dotes
doting
dotings
dots
dotted
dotting
double
doubled
doubles
doubles's
doubling
doubly
doubt
doubt's
doubted
doubtful
doubtfully
doubting
doubtless
doubts
dough
dough's
doughnut
doughnut's
doughnuts
doughnutted
doughnutting
dour
dourer
dourest
douse
doused
douses
dousing
dove
dove's
doves
dowdier
dowdies
dowdiest
dowdy
down
downcast
downed
downer
downer's
downers
downfall
downfall's
downfalls
downgrade
downgraded
downgrades
downgrading
downhearted
downhill
downhills
downier
downiest
downing
download
downloaded
downloading
downloads
downplay
downplayed
downplaying
downplays
downpour
downpour's
downpours
downright
downs
downsize
downsized
downsizes
downsizing
downstairs
downstate
downstream
downtime
downtime's
downtown
downtown's
downtrodden
downturn
downturn's
downturns
downward
downwards
downwind
downy
dowries
dowry
dowry's
doze
dozed
dozen
dozens
dozes
dozing
drab
drabber
drabbest
drabs
draconian
draft
draft's
drafted
drafting
drafts
drag
drag's
dragged
dragging
dragon
dragon's
dragonflies
dragonfly
dragonfly's
dragons
drags
drain
drain's
drainage
drainage's
drained
draining
drains
drake
drake's
drakes
drama
drama's
dramas
dramatic
dramatically
dramatics
dramatics's
dramatisation
dramatisation's
dramatisations
dramatise
dramatised
dramatises
dramatising
dramatist
dramatist's
dramatists
drank
drape
draped
draperies
drapery
drapery's
drapes
draping
drastic
drastically
draught
draught's
draughted
draughtier
draughtiest
draughting
draughts
draughtsman
draughtsman's
draughtsmen
draughty
draw
drawback
drawback's
drawbacks
drawbridge
drawbridge's
drawbridges
drawer
drawer's
drawers
drawing
drawing's
drawings
drawl
drawled
drawling
drawls
drawn
draws
dread
dreaded
dreadful
dreadfully
dreading
dreadlocks
dreads
dream
dream's
dreamer
dreamer's
dreamers
dreamier
dreamiest
dreaming
dreams
dreamt
dreamy
drearier
drearies
dreariest
dreary
dredge
dredge's
dredged
dredges
dredging
drees
dregs
drench
drenched
drenches
drenching
dress
dressed
dresser
dresser's
dressers
dresses
dressier
dressiest
dressing
dressing's
dressings
dressmaker
dressmaker's
dressmakers
dressy
drew
dribble
dribbled
dribbles
dribbling
dried
drier
driers
dries
driest
drift
drifted
drifter
drifter's
drifters
drifting
drifts
driftwood
driftwood's
drill
drill's
drilled
drilling
drills
drink
drinkable
drinker
drinker's
drinkers
drinking
drinkings
drinks
drip
dripped
dripping
dripping's
drips
drive
drivel
drivelled
drivelling
drivels
driven
driver
driver's
drivers
drives
driveway
driveway's
driveways
driving
drivings
drizzle
drizzle's
drizzled
drizzles
drizzling
droll
droller
drollest
drone
drone's
droned
drones
droning
drool
drooled
drooling
drools
droop
drooped
drooping
droops
drop
drop's
dropout
dropout's
dropouts
dropped
dropping
dropping's
droppings
drops
dross
dross's
drought
drought's
droughts
drove
droves
drown
drowned
drowning
drownings
drowns
drowse
drowsed
drowses
drowsier
drowsiest
drowsily
drowsiness
drowsiness's
drowsing
drowsy
drudge
drudge's
drudged
drudgery
drudgery's
drudges
drudging
drug
drug's
drugged
drugging
druggist
druggist's
druggists
drugs
drugstore
drugstore's
drugstores
drum
drum's
drummed
drummer
drummer's
drummers
drumming
drums
drumstick
drumstick's
drumsticks
drunk
drunkard
drunkard's
drunkards
drunken
drunkenly
drunkenness
drunkenness's
drunker
drunkest
drunks
dry
dryer
dryer's
dryers
drying
dryly
dryness
dryness's
drys
dual
dualism
dualism's
dub
dubbed
dubbing
dubious
dubiously
dubs
duchess
duchess's
duchesses
duck
duck's
ducked
ducking
duckling
duckling's
ducks
duct
duct's
ducts
dud
dud's
dude
dude's
duded
dudes
duding
duds
due
due's
duel
duel's
duelled
duelling
duellings
duels
dues
duet
duet's
duets
duff
duff's
dug
dugout
dugout's
dugouts
duke
duke's
duked
dukes
duking
dull
dulled
duller
dullest
dulling
dullness
dullness's
dulls
dully
duly
dumb
dumbbell
dumbbell's
dumbbells
dumbed
dumber
dumbest
dumbfound
dumbfounded
dumbfounding
dumbfounds
dumbing
dumbs
dummies
dummy
dummy's
dump
dumped
dumpier
dumpies
dumpiest
dumping
dumpling
dumpling's
dumps
dumpster
dumpy
dunce
dunce's
dunces
dune
dune's
dunes
dung
dung's
dunged
dungeon
dungeon's
dungeoned
dungeoning
dungeons
dunging
dungs
dunk
dunked
dunking
dunks
dunno
dunno's
duo
duo's
duos
dupe
dupe's
duped
dupes
duping
duplex
duplex's
duplexes
duplicate
duplicated
duplicates
duplicating
duplication
duplication's
duplicity
duplicity's
durability
durability's
durable
duration
duration's
duress
duress's
during
dusk
dusk's
duskier
duskiest
dusky
dust
dust's
dustbin
dustbin's
dusted
dustier
dustiest
dusting
dustmen
dustpan
dustpan's
dustpans
dusts
dusty
duties
dutiful
dutifully
duty
duty's
duvet
duvet's
dwarf
dwarf's
dwarfed
dwarfer
dwarfest
dwarfing
dwarfs
dwarves
dwell
dwelled
dweller
dweller's
dwellers
dwelling
dwelling's
dwellings
dwells
dwelt
dwindle
dwindled
dwindles
dwindling
dye
dye's
dyed
dyeing
dyes
dying
dyke
dyke's
dykes
dynamic
dynamical
dynamically
dynamics
dynamics's
dynamism
dynamism's
dynamite
dynamite's
dynamited
dynamites
dynamiting
dynamo
dynamo's
dynamos
dynasties
dynasty
dynasty's
dysentery
dysentery's
dysfunction
dysfunction's
dysfunctional
dysfunctions
dyslexia
dyslexia's
dyslexic
dyslexics
dbutante
dbutante's
dbutantes
dtente
e
each
eager
eager's
eagerer
eagerest
eagerly
eagerness
eagerness's
eagle
eagle's
eagles
ear
ear's
earache
earache's
earaches
eardrum
eardrum's
eardrums
earl
earl's
earlier
earliest
earlobe
earlobes
earls
early
earmark
earmarked
earmarking
earmarks
earmuff
earmuffs
earn
earned
earner
earner's
earners
earnest
earnestly
earnestness
earnestness's
earnests
earning
earning's
earnings
earns
earphone
earphones
earplug
earplug's
earplugs
earring
earring's
earrings
ears
earshot
earshot's
earsplitting
earth
earth's
earthed
earthier
earthiest
earthiness
earthiness's
earthing
earthlier
earthliest
earthly
earthquake
earthquake's
earthquaked
earthquakes
earthquaking
earths
earthshaking
earthworm
earthworm's
earthworms
earthy
earwax
earwax's
ease
ease's
eased
easel
easel's
easels
eases
easier
easies
easiest
easily
easing
east
east's
eastbound
easterlies
easterly
eastern
easterner
easterner's
easterners
eastward
eastwards
easy
easygoing
eat
eaten
eater
eater's
eateries
eaters
eatery
eatery's
eating
eating's
eats
eave
eaves
eavesdrop
eavesdropped
eavesdropper
eavesdropper's
eavesdroppers
eavesdropping
eavesdrops
ebb
ebbed
ebbing
ebbs
ebonies
ebony
ebony's
ebullience
ebullience's
ebullient
eccentric
eccentricities
eccentricity
eccentricity's
eccentrics
ecclesiastical
echo
echo's
echoed
echoes
echoing
echos
eclectic
eclipse
eclipse's
eclipsed
eclipses
eclipsing
ecological
ecologically
ecologist
ecologist's
ecologists
ecology
ecology's
economic
economical
economically
economics
economics's
economies
economise
economised
economises
economising
economist
economist's
economists
economy
economy's
ecosystem
ecosystem's
ecosystems
ecstasies
ecstasy
ecstasy's
ecstatic
ecumenical
eczema
eczema's
eddied
eddies
eddy
eddy's
eddying
edge
edge's
edged
edger
edges
edgeways
edgewise
edgier
edgiest
edging
edgy
edible
edibles
edict
edict's
edicts
edification
edification's
edifice
edifice's
edifices
edified
edifies
edify
edifying
edit
edited
editing
edition
edition's
editions
editor
editor's
editorial
editorials
editors
editorship
editorship's
edits
educate
educated
educates
educating
education
education's
educational
educationally
educations
educator
educator's
educators
eel
eel's
eels
eerie
eerier
eeriest
eerily
eery
effect
effect's
effected
effecting
effective
effectively
effectiveness
effectiveness's
effects
effectual
effeminate
effervescence
effervescence's
effervescent
efficiency
efficiency's
efficient
efficiently
efficients
effigies
effigy
effigy's
effort
effort's
effortless
effortlessly
efforts
effusive
effusively
egalitarian
egalitarianism
egalitarianism's
egalitarians
egg
egg's
egged
egghead
egghead's
eggheads
egging
eggplant
eggplant's
eggplants
eggs
eggshell
eggshell's
eggshells
ego
ego's
egocentric
egocentrics
egoism
egoism's
egos
egotism
egotism's
egotist
egotist's
egotistical
egotists
egregious
egregiously
eh
eigenvalue
eigenvalue's
eight
eight's
eighteen
eighteen's
eighteens
eighteenth
eighteenths
eighth
eighths
eighties
eightieth
eightieths
eights
eighty
eighty's
either
ejaculate
ejaculated
ejaculates
ejaculating
ejaculation
ejaculation's
ejaculations
eject
ejected
ejecting
ejection
ejection's
ejections
ejects
eke
eked
ekes
eking
elaborate
elaborated
elaborately
elaborates
elaborating
elaboration
elaboration's
elaborations
elapse
elapsed
elapses
elapsing
elastic
elasticity
elasticity's
elastics
elate
elated
elates
elating
elation
elation's
elbow
elbow's
elbowed
elbowing
elbowroom
elbowroom's
elbows
elder
elderly
elders
eldest
elect
elected
electing
election
election's
elections
elective
electives
elector
elector's
electoral
electorate
electorate's
electorates
electors
electric
electrical
electrically
electrician
electrician's
electricians
electricity
electricity's
electrified
electrifies
electrify
electrifying
electrocute
electrocuted
electrocutes
electrocuting
electrocution
electrocution's
electrocutions
electrode
electrode's
electrodes
electrolysis
electrolysis's
electromagnetic
electron
electron's
electronic
electronically
electronics
electronics's
electrons
electrostatic
elects
elegance
elegance's
elegant
elegantly
elegies
elegy
elegy's
element
element's
elemental
elementary
elements
elephant
elephant's
elephants
elevate
elevated
elevates
elevating
elevation
elevation's
elevations
elevator
elevator's
elevators
eleven
eleven's
elevens
eleventh
elevenths
elf
elf's
elfin
elicit
elicited
eliciting
elicits
eligibility
eligibility's
eligible
eliminate
eliminated
eliminates
eliminating
elimination
elimination's
eliminations
elite
elite's
elites
elitism
elitism's
elitist
elitist's
elitists
elk
elk's
elks
ellipse
ellipse's
ellipses
ellipsis
elliptic
elliptical
elm
elm's
elms
elongate
elongated
elongates
elongating
elope
eloped
elopement
elopement's
elopements
elopes
eloping
eloquence
eloquence's
eloquent
eloquently
else
elsewhere
elucidate
elucidated
elucidates
elucidating
elude
eluded
eludes
eluding
elusive
elves
elves's
em
em's
emaciate
emaciated
emaciates
emaciating
email
email's
emailed
emailing
emails
emanate
emanated
emanates
emanating
emancipate
emancipated
emancipates
emancipating
emancipation
emancipation's
embalm
embalmed
embalming
embalms
embankment
embankment's
embankments
embargo
embargo's
embargoed
embargoes
embargoing
embark
embarked
embarking
embarks
embarrass
embarrassed
embarrasses
embarrassing
embarrassingly
embarrassment
embarrassment's
embarrassments
embassies
embassy
embassy's
embattled
embed
embedded
embedding
embeds
embellish
embellished
embellishes
embellishing
embellishment
embellishment's
embellishments
ember
ember's
embers
embezzle
embezzled
embezzlement
embezzlement's
embezzler
embezzler's
embezzlers
embezzles
embezzling
embitter
embittered
embittering
embitters
emblazon
emblazoned
emblazoning
emblazons
emblem
emblem's
emblems
embodied
embodies
embodiment
embodiment's
embody
embodying
emboss
embossed
embosses
embossing
embrace
embraced
embraces
embracing
embroider
embroidered
embroideries
embroidering
embroiders
embroidery
embroidery's
embroil
embroiled
embroiling
embroils
embryo
embryo's
embryonic
embryos
emcee
emcee's
emceed
emceeing
emcees
emerald
emerald's
emeralds
emerge
emerged
emergence
emergence's
emergencies
emergency
emergency's
emergent
emerges
emerging
emeritus
emigrant
emigrant's
emigrants
emigrate
emigrated
emigrates
emigrating
emigration
emigration's
emigrations
eminence
eminence's
eminences
eminent
eminently
emir
emir's
emirate
emirate's
emirates
emirs
emissaries
emissary
emissary's
emission
emission's
emissions
emit
emits
emitted
emitting
emotion
emotion's
emotional
emotionally
emotions
emotive
empathise
empathised
empathises
empathising
empathy
empathy's
emperor
emperor's
emperors
emphases
emphasis
emphasis's
emphasise
emphasised
emphasises
emphasising
emphatic
emphatically
emphysema
emphysema's
empire
empire's
empires
empirical
employ
employed
employee
employee's
employees
employer
employer's
employers
employing
employment
employment's
employments
employs
emporia
emporium
emporium's
emporiums
empower
empowered
empowering
empowerment
empowerment's
empowers
empress
empress's
empresses
emptied
emptier
empties
emptiest
emptiness
emptiness's
empty
emptying
emulate
emulated
emulates
emulating
emulation
emulation's
emulations
emulator
emulator's
emulators
emulsion
emulsion's
emulsions
enable
enabled
enables
enabling
enact
enacted
enacting
enactment
enactment's
enactments
enacts
enamel
enamel's
enamelled
enamelling
enamellings
enamels
enamour
enamoured
enamouring
enamours
encapsulate
encapsulated
encapsulates
encapsulating
encase
encased
encases
encasing
enchant
enchanted
enchanting
enchantment
enchantment's
enchantments
enchants
enchilada
enchilada's
enchiladas
encircle
encircled
encircles
encircling
enclave
enclave's
enclaves
enclose
enclosed
encloses
enclosing
enclosure
enclosure's
enclosures
encode
encoded
encodes
encoding
encompass
encompassed
encompasses
encompassing
encore
encored
encores
encoring
encounter
encountered
encountering
encounters
encourage
encouraged
encouragement
encouragement's
encouragements
encourages
encouraging
encroach
encroached
encroaches
encroaching
encrypted
encryption
encryption's
encumber
encumbered
encumbering
encumbers
encumbrance
encumbrance's
encumbrances
encyclopaedia
encyclopaedias
encyclopedia
encyclopedia's
encyclopedias
end
end's
endanger
endangered
endangering
endangers
endear
endeared
endearing
endearment
endearment's
endearments
endears
endeavour
endeavoured
endeavouring
endeavours
ended
endemic
endemics
ending
ending's
endings
endive
endive's
endives
endless
endlessly
endorse
endorsed
endorsement
endorsement's
endorsements
endorses
endorsing
endow
endowed
endowing
endowment
endowment's
endowments
endows
ends
endurance
endurance's
endure
endured
endures
enduring
endways
enema
enema's
enemas
enemata
enemies
enemy
enemy's
energetic
energetically
energetics
energies
energise
energised
energises
energising
energy
energy's
enforce
enforceable
enforced
enforcement
enforcement's
enforces
enforcing
enfranchise
enfranchised
enfranchises
enfranchising
engage
engaged
engagement
engagement's
engagements
engages
engaging
engender
engendered
engendering
engenders
engine
engine's
engined
engineer
engineer's
engineered
engineering
engineering's
engineers
engines
engining
engrave
engraved
engraver
engraver's
engravers
engraves
engraving
engraving's
engravings
engross
engrossed
engrosses
engrossing
engulf
engulfed
engulfing
engulfs
enhance
enhanced
enhancement
enhancement's
enhancements
enhances
enhancing
enigma
enigma's
enigmas
enigmatic
enjoy
enjoyable
enjoyed
enjoying
enjoyment
enjoyment's
enjoyments
enjoys
enlarge
enlarged
enlargement
enlargement's
enlargements
enlarges
enlarging
enlighten
enlightened
enlightening
enlightenment
enlightenment's
enlightens
enlist
enlisted
enlisting
enlistment
enlistment's
enlistments
enlists
enliven
enlivened
enlivening
enlivens
enmities
enmity
enmity's
enormities
enormity
enormity's
enormous
enormously
enough
enquire
enquired
enquires
enquiries
enquiring
enquiry
enquiry's
enrage
enraged
enrages
enraging
enrich
enriched
enriches
enriching
enrichment
enrichment's
enrol
enrolled
enrolling
enrolment
enrolment's
enrolments
enrols
ensconce
ensconced
ensconces
ensconcing
ensemble
ensemble's
ensembles
enshrine
enshrined
enshrines
enshrining
ensign
ensign's
ensigns
enslave
enslaved
enslaves
enslaving
ensue
ensued
ensues
ensuing
ensure
ensured
ensures
ensuring
entail
entailed
entailing
entails
entangle
entangled
entanglement
entanglement's
entanglements
entangles
entangling
enter
entered
entering
enterprise
enterprise's
enterprises
enterprising
enters
entertain
entertained
entertainer
entertainer's
entertainers
entertaining
entertainment
entertainment's
entertainments
entertains
enthral
enthralled
enthralling
enthrals
enthuse
enthused
enthuses
enthusiasm
enthusiasm's
enthusiasms
enthusiast
enthusiast's
enthusiastic
enthusiastically
enthusiasts
enthusing
entice
enticed
enticement
enticement's
enticements
entices
enticing
enticings
entire
entirely
entirety
entirety's
entities
entitle
entitled
entitlement
entitlement's
entitlements
entitles
entitling
entity
entity's
entomologist
entomologists
entomology
entomology's
entourage
entourage's
entourages
entrails
entrance
entrance's
entranced
entrances
entrancing
entrant
entrant's
entrants
entrap
entrapment
entrapment's
entrapped
entrapping
entraps
entreat
entreated
entreaties
entreating
entreats
entreaty
entreaty's
entrench
entrenched
entrenches
entrenching
entrepreneur
entrepreneur's
entrepreneurial
entrepreneurs
entries
entropy
entropy's
entrust
entrusted
entrusting
entrusts
entry
entry's
entryway
entryway's
entryways
entre
entres
entwine
entwined
entwines
entwining
enumerate
enumerated
enumerates
enumerating
enumeration
enumeration's
enunciate
enunciated
enunciates
enunciating
enunciation
enunciation's
envelop
envelope
envelope's
enveloped
envelopes
enveloping
envelops
enviable
envied
envies
envious
enviously
environment
environment's
environmental
environmentalist
environmentalist's
environmentalists
environmentally
environments
environs
envisage
envisaged
envisages
envisaging
envision
envisioned
envisioning
envisions
envoy
envoy's
envoys
envy
envy's
envying
enzyme
enzyme's
enzymes
eon
eon's
eons
epaulet
epaulet's
epaulets
ephemeral
epic
epic's
epicentre
epicentre's
epicentres
epics
epidemic
epidemics
epidermis
epidermis's
epidermises
epigram
epigram's
epigrams
epilepsy
epilepsy's
epileptic
epileptics
epilogue
epilogue's
epilogued
epilogues
epiloguing
episode
episode's
episodes
episodic
epistle
epistle's
epistles
epitaph
epitaph's
epitaphs
epithet
epithet's
epithets
epitome
epitome's
epitomes
epitomise
epitomised
epitomises
epitomising
epoch
epoch's
epochs
epsilon
epsilon's
equal
equalise
equalised
equalises
equalising
equality
equality's
equalled
equalling
equally
equals
equanimity
equanimity's
equate
equated
equates
equating
equation
equation's
equations
equator
equator's
equatorial
equators
equestrian
equestrians
equilateral
equilaterals
equilibrium
equilibrium's
equine
equines
equinox
equinox's
equinoxes
equip
equipment
equipment's
equipped
equipping
equips
equitable
equities
equity
equity's
equivalence
equivalence's
equivalences
equivalent
equivalently
equivalents
equivocal
era
era's
eradicate
eradicated
eradicates
eradicating
eradication
eradication's
eras
erase
erased
eraser
eraser's
erasers
erases
erasing
erasure
erasure's
erect
erected
erecting
erection
erection's
erections
erects
ergo
ergonomic
erode
eroded
erodes
eroding
erosion
erosion's
erotic
erotically
eroticism
eroticism's
err
errand
errand's
errands
errant
errants
erratic
erratically
erratics
erred
erring
erroneous
erroneously
error
error's
errors
errs
erstwhile
erudite
erudition
erudition's
erupt
erupted
erupting
eruption
eruption's
eruptions
erupts
es
escalate
escalated
escalates
escalating
escalation
escalation's
escalations
escalator
escalator's
escalators
escapade
escapade's
escapades
escape
escaped
escapes
escaping
escapism
escapism's
escapist
escapists
eschew
eschewed
eschewing
eschews
escort
escort's
escorted
escorting
escorts
esoteric
especial
especially
espionage
espionage's
espouse
espoused
espouses
espousing
espresso
espresso's
espressos
essay
essay's
essayed
essaying
essays
essence
essence's
essences
essential
essentially
essentials
establish
established
establishes
establishing
establishment
establishment's
establishments
estate
estate's
estates
esteem
esteemed
esteeming
esteems
esthetic
esthetically
estimable
estimate
estimated
estimates
estimating
estimation
estimation's
estimations
estrange
estranged
estrangement
estrangement's
estrangements
estranges
estranging
estuaries
estuary
estuary's
etch
etched
etches
etching
etching's
etchings
eternal
eternally
eternities
eternity
eternity's
ether
ether's
ethereal
ethic
ethic's
ethical
ethically
ethicals
ethics
ethnic
ethnics
ethos
ethos's
etiquette
etiquette's
etymological
etymologies
etymology
etymology's
eulogies
eulogise
eulogised
eulogises
eulogising
eulogy
eulogy's
eunuch
eunuch's
eunuchs
euphemism
euphemism's
euphemisms
euphemistic
euphemistically
euphoria
euphoria's
euphoric
eureka
euthanasia
euthanasia's
evacuate
evacuated
evacuates
evacuating
evacuation
evacuation's
evacuations
evacuee
evacuee's
evacuees
evade
evaded
evades
evading
evaluate
evaluated
evaluates
evaluating
evaluation
evaluation's
evaluations
evangelical
evangelicals
evangelism
evangelism's
evangelist
evangelist's
evangelistic
evangelists
evaporate
evaporated
evaporates
evaporating
evaporation
evaporation's
evasion
evasion's
evasions
evasive
eve
eve's
even
evened
evener
evenest
evenhanded
evening
evening's
evenings
evenly
evenness
evenness's
evens
event
event's
eventful
events
eventual
eventualities
eventuality
eventuality's
eventually
ever
evergreen
evergreens
everlasting
everlastings
evermore
every
everybody
everyday
everyone
everyplace
everything
everywhere
eves
evict
evicted
evicting
eviction
eviction's
evictions
evicts
evidence
evidence's
evidenced
evidences
evidencing
evident
evidently
evidents
evil
eviller
evillest
evils
evocative
evoke
evoked
evokes
evoking
evolution
evolution's
evolutionary
evolve
evolved
evolves
evolving
ewe
ewe's
ewes
ex
exacerbate
exacerbated
exacerbates
exacerbating
exact
exacted
exacter
exactest
exacting
exactly
exacts
exaggerate
exaggerated
exaggerates
exaggerating
exaggeration
exaggeration's
exaggerations
exalt
exaltation
exaltation's
exalted
exalting
exalts
exam
exam's
examination
examination's
examinations
examine
examined
examiner
examiner's
examiners
examines
examining
example
example's
exampled
examples
exampling
exams
exasperate
exasperated
exasperates
exasperating
exasperation
exasperation's
excavate
excavated
excavates
excavating
excavation
excavation's
excavations
exceed
exceeded
exceeding
exceedingly
exceeds
excel
excelled
excellence
excellence's
excellent
excellently
excelling
excels
except
excepted
excepting
exception
exception's
exceptional
exceptionally
exceptions
excepts
excerpt
excerpt's
excerpted
excerpting
excerpts
excess
excess's
excesses
excessive
excessively
exchange
exchanged
exchanges
exchanging
excise
excise's
excised
excises
excising
excision
excision's
excisions
excitable
excite
excited
excitedly
excitement
excitement's
excitements
excites
exciting
exclaim
exclaimed
exclaiming
exclaims
exclamation
exclamation's
exclamations
exclude
excluded
excludes
excluding
exclusion
exclusion's
exclusive
exclusively
exclusives
excommunicate
excommunicated
excommunicates
excommunicating
excommunication
excommunication's
excommunications
excrement
excrement's
excrete
excreted
excretes
excreting
excruciating
excruciatingly
excursion
excursion's
excursions
excusable
excuse
excused
excuses
excusing
exec
exec's
execs
executable
execute
executed
executes
executing
execution
execution's
executioner
executioner's
executioners
executions
executive
executive's
executives
executor
executor's
executors
exemplary
exemplified
exemplifies
exemplify
exemplifying
exempt
exempted
exempting
exemption
exemption's
exemptions
exempts
exercise
exercised
exercises
exercising
exert
exerted
exerting
exertion
exertion's
exertions
exerts
exes
exhale
exhaled
exhales
exhaling
exhaust
exhausted
exhausting
exhaustion
exhaustion's
exhaustive
exhaustively
exhausts
exhibit
exhibited
exhibiting
exhibition
exhibition's
exhibitionism
exhibitionism's
exhibitionist
exhibitionist's
exhibitionists
exhibitions
exhibitor
exhibitor's
exhibitors
exhibits
exhilarate
exhilarated
exhilarates
exhilarating
exhilaration
exhilaration's
exhort
exhortation
exhortation's
exhortations
exhorted
exhorting
exhorts
exhumation
exhumation's
exhumations
exhume
exhumed
exhumes
exhuming
exile
exile's
exiled
exiles
exiling
exist
existed
existence
existence's
existences
existent
existential
existentially
existing
exists
exit
exit's
exited
exiting
exits
exodus
exodus's
exoduses
exonerate
exonerated
exonerates
exonerating
exoneration
exoneration's
exorbitant
exorcism
exorcism's
exorcisms
exorcist
exorcist's
exorcists
exotic
exotics
expand
expandable
expanded
expanding
expands
expanse
expanse's
expanses
expansion
expansion's
expansionist
expansionist's
expansionists
expansions
expansive
expatriate
expatriated
expatriates
expatriating
expect
expectancy
expectancy's
expectant
expectantly
expectation
expectation's
expectations
expected
expecting
expects
expediencies
expediency
expediency's
expedient
expedients
expedite
expedited
expedites
expediting
expedition
expedition's
expeditions
expel
expelled
expelling
expels
expend
expendable
expendables
expended
expending
expenditure
expenditure's
expenditures
expends
expense
expense's
expenses
expensive
expensively
experience
experience's
experienced
experiences
experiencing
experiment
experiment's
experimental
experimentally
experimentation
experimentation's
experimented
experimenting
experiments
expert
expert's
expertise
expertise's
expertly
experts
expiration
expiration's
expire
expired
expires
expiring
expiry
expiry's
explain
explained
explaining
explains
explanation
explanation's
explanations
explanatory
expletive
expletive's
expletives
explicable
explicit
explicitly
explicits
explode
exploded
explodes
exploding
exploit
exploit's
exploitation
exploitation's
exploited
exploiting
exploits
exploration
exploration's
explorations
exploratory
explore
explored
explorer
explorer's
explorers
explores
exploring
explosion
explosion's
explosions
explosive
explosives
expo
expo's
exponent
exponent's
exponential
exponentially
exponents
export
export's
exportation
exportation's
exported
exporter
exporter's
exporters
exporting
exports
expos
expose
exposed
exposes
exposing
exposition
exposition's
expositions
exposure
exposure's
exposures
expound
expounded
expounding
expounds
express
expressed
expresses
expressing
expression
expression's
expressions
expressive
expressively
expressly
expressway
expressway's
expressways
expropriate
expropriated
expropriates
expropriating
expropriation
expropriation's
expropriations
expulsion
expulsion's
expulsions
exquisite
exquisitely
extant
extemporaneous
extend
extended
extending
extends
extension
extension's
extensions
extensive
extensively
extent
extent's
extents
exterior
exterior's
exteriors
exterminate
exterminated
exterminates
exterminating
extermination
extermination's
exterminations
exterminator
exterminator's
exterminators
external
externally
externals
extinct
extincted
extincting
extinction
extinction's
extinctions
extincts
extinguish
extinguished
extinguisher
extinguisher's
extinguishers
extinguishes
extinguishing
extol
extoll
extolled
extolling
extolls
extols
extort
extorted
extorting
extortion
extortion's
extortionate
extorts
extra
extract
extracted
extracting
extraction
extraction's
extractions
extracts
extracurricular
extracurriculars
extradite
extradited
extradites
extraditing
extradition
extradition's
extraditions
extraneous
extraordinaries
extraordinarily
extraordinary
extrapolate
extrapolated
extrapolates
extrapolating
extrapolation
extrapolation's
extrapolations
extras
extraterrestrial
extraterrestrials
extravagance
extravagance's
extravagances
extravagant
extravagantly
extreme
extremely
extremer
extremes
extremest
extremism
extremism's
extremist
extremist's
extremists
extremities
extremity
extremity's
extricate
extricated
extricates
extricating
extrovert
extrovert's
extroverted
extroverts
exuberance
exuberance's
exuberant
exude
exuded
exudes
exuding
exult
exultant
exultation
exultation's
exulted
exulting
exults
eye
eye's
eyeball
eyeball's
eyeballed
eyeballing
eyeballs
eyebrow
eyebrow's
eyebrows
eyed
eyeglass
eyeglasses
eyeing
eyelash
eyelash's
eyelashes
eyelid
eyelid's
eyelids
eyeliner
eyeliner's
eyeliners
eyes
eyesight
eyesight's
eyesore
eyesore's
eyesores
eyewitness
eyewitness's
eyewitnesses
eying
f
fable
fable's
fables
fabric
fabric's
fabricate
fabricated
fabricates
fabricating
fabrication
fabrication's
fabrications
fabrics
fabulous
facade
facade's
facades
face
face's
faced
faceless
faces
facet
facet's
faceted
faceting
facetious
facetiously
facets
facetted
facetting
facial
facials
facile
facilitate
facilitated
facilitates
facilitating
facilities
facility
facility's
facing
facing's
facsimile
facsimile's
facsimiled
facsimileing
facsimiles
fact
fact's
faction
faction's
factions
factor
factor's
factored
factorial
factorial's
factories
factoring
factorisation
factors
factory
factory's
facts
factual
factually
faculties
faculty
faculty's
fad
fad's
fade
faded
fades
fading
fading's
fads
fag
fag's
fagged
fagging
faggot
faggot's
faggoted
faggoting
faggots
fags
fail
failed
failing
failing's
failings
fails
failure
failure's
failures
faint
fainted
fainter
faintest
fainting
faintly
faints
fair
fairer
fairest
fairground
fairground's
fairgrounds
fairies
fairly
fairness
fairness's
fairs
fairy
fairy's
faith
faith's
faithed
faithful
faithfully
faithfulness
faithfulness's
faithfuls
faithing
faithless
faiths
fake
faked
fakes
faking
falcon
falcon's
falconry
falconry's
falcons
fall
fall's
fallacies
fallacious
fallacy
fallacy's
fallen
fallible
falling
fallout
fallout's
falls
false
falsehood
falsehood's
falsehoods
falsely
falser
falsest
falsetto
falsetto's
falsettos
falsification
falsification's
falsifications
falsified
falsifies
falsify
falsifying
falsities
falsity
falsity's
falter
faltered
faltering
falterings
falters
fame
fame's
famed
familiar
familiarise
familiarised
familiarises
familiarising
familiarity
familiarity's
familiarly
familiars
families
family
family's
famine
famine's
famines
famish
famished
famishes
famishing
famous
famously
fan
fan's
fanatic
fanatic's
fanatical
fanatically
fanaticism
fanaticism's
fanatics
fancied
fancier
fancies
fanciest
fanciful
fancy
fancying
fanfare
fanfare's
fanfares
fang
fang's
fangs
fanned
fannies
fanning
fanny
fanny's
fans
fantasied
fantasies
fantasise
fantasised
fantasises
fantasising
fantastic
fantastically
fantasy
fantasy's
fantasying
far
faraway
farce
farce's
farces
farcical
fare
fare's
fared
fares
farewell
farewell's
farewells
faring
farm
farm's
farmed
farmer
farmer's
farmers
farmhouse
farmhouse's
farmhouses
farming
farming's
farmland
farmland's
farms
farmyard
farmyard's
farmyards
farsighted
fart
fart's
farted
farther
farthest
farting
farts
fascinate
fascinated
fascinates
fascinating
fascination
fascination's
fascinations
fascism
fascism's
fascist
fascist's
fascists
fashion
fashion's
fashionable
fashionably
fashioned
fashioning
fashions
fast
fasted
fasten
fastened
fastener
fastener's
fasteners
fastening
fastening's
fastenings
fastens
faster
fastest
fastidious
fasting
fasts
fat
fat's
fatal
fatalism
fatalism's
fatalistic
fatalities
fatality
fatality's
fatally
fate
fate's
fated
fateful
fates
father
father's
fathered
fatherhood
fatherhood's
fathering
fatherland
fatherland's
fatherlands
fatherly
fathers
fathom
fathom's
fathomed
fathoming
fathoms
fatigue
fatigue's
fatigued
fatigues
fatiguing
fating
fats
fatten
fattened
fattening
fattenings
fattens
fatter
fattest
fattier
fatties
fattiest
fatty
fatuous
faucet
faucet's
faucets
fault
fault's
faulted
faultier
faultiest
faulting
faultless
faults
faulty
fauna
fauna's
faunae
faunas
favour
favour's
favourable
favourably
favoured
favouring
favourite
favourite's
favourites
favouritism
favouritism's
favours
fawn
fawn's
fawned
fawning
fawns
fax
faxed
faxes
faxing
faze
fazed
fazes
fazing
fear
fear's
feared
fearful
fearfuller
fearfullest
fearfully
fearing
fearless
fearlessly
fearlessness
fearlessness's
fears
fearsome
feasibility
feasibility's
feasible
feast
feast's
feasted
feasting
feasts
feat
feat's
feather
feather's
feathered
featherier
featheriest
feathering
feathers
feathery
feats
feature
feature's
featured
features
featuring
fecal
feces
fed
federal
federalism
federalism's
federalist
federalist's
federalists
federals
federate
federated
federates
federating
federation
federation's
federations
feds
fee
fee's
feeble
feebler
feeblest
feed
feedback
feedback's
feedbag
feedbag's
feedbags
feeder
feeder's
feeders
feeding
feeding's
feedings
feeds
feel
feeler
feeler's
feelers
feeling
feeling's
feelings
feels
fees
feet
feet's
feign
feigned
feigning
feigns
feint
feint's
feinted
feinting
feints
feistier
feistiest
feisty
feline
felines
fell
felled
feller
fellest
felling
fellow
fellow's
fellows
fellowship
fellowship's
fellowships
fells
felon
felon's
felonies
felons
felony
felony's
felt
felted
felting
felts
female
females
feminine
feminines
femininity
femininity's
feminism
feminism's
feminist
feminist's
feminists
fems
fen
fen's
fence
fence's
fenced
fences
fencing
fencing's
fend
fended
fender
fender's
fenders
fending
fends
fer
ferment
ferment's
fermentation
fermentation's
fermented
fermenting
ferments
fern
fern's
ferns
ferocious
ferociously
ferocity
ferocity's
ferret
ferret's
ferreted
ferreting
ferrets
ferried
ferries
ferry
ferry's
ferrying
fertile
fertilisation
fertilisation's
fertilise
fertilised
fertiliser
fertiliser's
fertilisers
fertilises
fertilising
fertility
fertility's
fervent
fervently
fervour
fervour's
fest
fester
festered
festering
festers
festival
festival's
festivals
festive
festivities
festivity
festivity's
festoon
festoon's
festooned
festooning
festoons
fests
fetch
fetched
fetches
fetching
feted
fetid
feting
fetish
fetish's
fetishes
fetter
fetter's
fettered
fettering
fetters
feud
feud's
feudal
feudalism
feudalism's
feuded
feuding
feuds
fever
fever's
feverish
feverishly
fevers
few
fewer
fewest
fez
fez's
fezes
fezzes
fianc
fianc's
fiance
fiances
fiancs
fiasco
fiasco's
fiascoes
fiascos
fiat
fiat's
fiats
fib
fib's
fibbed
fibber
fibber's
fibbers
fibbing
fibre
fibre's
fibreglass
fibreglass's
fibres
fibrous
fibs
fices
fiche
fiche's
fickle
fickler
ficklest
ficoes
fiction
fiction's
fictional
fictions
fictitious
fiddle
fiddle's
fiddled
fiddler
fiddler's
fiddlers
fiddles
fiddling
fiddly
fidelity
fidelity's
fidget
fidgeted
fidgeting
fidgets
fidgety
field
field's
fielded
fielding
fields
fieldwork
fieldwork's
fiend
fiend's
fiendish
fiendishly
fiends
fierce
fiercely
fierceness
fierceness's
fiercer
fiercest
fierier
fieriest
fiery
fiesta
fiesta's
fiestas
fifteen
fifteen's
fifteens
fifteenth
fifteenths
fifth
fifths
fifties
fiftieth
fiftieths
fifty
fifty's
fig
fig's
figged
figging
fight
fighter
fighter's
fighters
fighting
fights
figment
figment's
figments
figs
figurative
figuratively
figure
figure's
figured
figurehead
figurehead's
figureheads
figures
figuring
filament
filament's
filaments
filch
filched
filches
filching
file
file's
filed
files
filibuster
filibuster's
filibustered
filibustering
filibusters
filigree
filigree's
filigreed
filigreeing
filigrees
filing
fill
filled
filler
filler's
fillet
fillet's
filleted
filleting
fillets
fillies
filling
filling's
fills
filly
filly's
film
film's
filmed
filmier
filmiest
filming
filming's
filmmaker
filmmakers
films
filmy
filter
filter's
filtered
filtering
filters
filth
filth's
filthier
filthiest
filthy
fin
fin's
finagle
finagled
finagles
finagling
final
finale
finale's
finales
finalise
finalised
finalises
finalising
finalist
finalist's
finalists
finality
finality's
finally
finals
finance
finance's
financed
finances
financial
financially
financier
financier's
financiers
financing
finch
finch's
finches
find
finder
finder's
finders
finding
finding's
findings
finds
fine
fine's
fined
finely
finer
fines
finesse
finesse's
finessed
finesses
finessing
finest
finger
finger's
fingered
fingering
fingernail
fingernail's
fingernails
fingerprint
fingerprint's
fingerprinted
fingerprinting
fingerprints
fingers
fingertip
fingertip's
fingertips
finickier
finickiest
finicky
fining
finish
finished
finishes
finishing
finite
finner
fins
fir
fir's
fire
fire's
firearm
firearm's
firearms
firebrand
firebrand's
firebrands
firecracker
firecracker's
firecrackers
fired
firefighter
firefighters
fireflies
firefly
firefly's
fireman
fireman's
firemen
fireplace
fireplace's
fireplaces
fireproof
fireproofed
fireproofing
fireproofs
fires
fireside
fireside's
firesides
firewall
firewalled
firewalling
firewalls
firewood
firewood's
firework
firework's
fireworks
firing
firing's
firm
firmed
firmer
firmest
firming
firmly
firmness
firmness's
firms
firmware
firmware's
firring
firs
first
firsthand
firstly
firsts
fiscal
fiscals
fish
fish's
fishbowl
fishbowl's
fishbowls
fished
fisher
fisher's
fisheries
fisherman
fisherman's
fishermen
fishery
fishery's
fishes
fishier
fishiest
fishing
fishing's
fishnet
fishnet's
fishnets
fishtail
fishtail's
fishtailed
fishtailing
fishtails
fishy
fission
fission's
fissure
fissure's
fissures
fist
fist's
fists
fit
fit's
fitful
fitness
fitness's
fits
fitted
fitter
fittest
fitting
fittings
five
five's
fiver
fiver's
fives
fix
fixable
fixation
fixation's
fixations
fixed
fixes
fixing
fixing's
fixture
fixture's
fixtures
fizz
fizzed
fizzes
fizzier
fizziest
fizzing
fizzle
fizzled
fizzles
fizzling
fizzy
fjord
fjord's
fjords
flab
flab's
flabbergast
flabbergasted
flabbergasting
flabbergasts
flabbier
flabbiest
flabby
flaccid
flag
flag's
flagged
flagging
flagging's
flagpole
flagpole's
flagpoles
flagrant
flagrantly
flags
flagship
flagship's
flagships
flagstone
flagstone's
flagstones
flail
flail's
flailed
flailing
flails
flair
flair's
flairs
flak
flak's
flake
flake's
flaked
flakes
flakier
flakiest
flaking
flaks
flaky
flamboyance
flamboyance's
flamboyant
flamboyantly
flame
flame's
flamed
flamenco
flamenco's
flamencos
flames
flaming
flamingo
flamingo's
flamingoes
flamingos
flamings
flammable
flammables
flank
flank's
flanked
flanking
flanks
flannel
flannel's
flannelled
flannelling
flannels
flap
flapjack
flapjack's
flapjacks
flapped
flapping
flaps
flare
flared
flares
flaring
flash
flash's
flashback
flashback's
flashbacks
flashed
flasher
flasher's
flashers
flashes
flashest
flashier
flashiest
flashing
flashing's
flashlight
flashlight's
flashlights
flashy
flask
flask's
flasks
flat
flat's
flatly
flatness
flatness's
flats
flatted
flatten
flattened
flattening
flattens
flatter
flattered
flatterer
flatterer's
flatterers
flattering
flatters
flattery
flattery's
flattest
flatting
flatulence
flatulence's
flaunt
flaunted
flaunting
flaunts
flavour
flavour's
flavoured
flavouring
flavouring's
flavourings
flavours
flaw
flaw's
flawed
flawing
flawless
flawlessly
flaws
flea
flea's
fleas
fleck
fleck's
flecked
flecking
flecks
fled
fledged
fledgling
fledgling's
fledglings
flee
fleece
fleece's
fleeced
fleeces
fleecier
fleeciest
fleecing
fleecy
fleeing
flees
fleet
fleet's
fleeted
fleeter
fleetest
fleeting
fleets
flesh
flesh's
fleshed
fleshes
fleshier
fleshiest
fleshing
fleshy
flew
flex
flex's
flexed
flexes
flexibility
flexibility's
flexible
flexibly
flexing
flextime
flick
flicked
flicker
flickered
flickering
flickers
flicking
flicks
flied
flier
flier's
fliers
flies
fliest
flight
flight's
flightier
flightiest
flightless
flights
flighty
flimsier
flimsiest
flimsiness
flimsiness's
flimsy
flinch
flinched
flinches
flinching
fling
flinging
flings
flint
flint's
flints
flip
flippant
flipped
flipper
flipper's
flippers
flippest
flipping
flips
flirt
flirtation
flirtation's
flirtations
flirtatious
flirted
flirting
flirts
flit
flits
flitted
flitting
float
floated
floating
floats
flock
flock's
flocked
flocking
flocks
flog
flogged
flogging
flogging's
floggings
flogs
flood
flood's
flooded
flooder
floodgate
floodgate's
floodgates
flooding
floodlight
floodlight's
floodlighted
floodlighting
floodlights
floodlit
floods
floor
floor's
floored
flooring
flooring's
floors
floozie
floozies
floozy
floozy's
flop
flophouse
flophouse's
flophouses
flopped
floppier
floppies
floppiest
flopping
floppy
flops
flora
flora's
florae
floral
floras
florid
florist
florist's
florists
floss
floss's
flossed
flosses
flossing
flotilla
flotilla's
flotillas
flounce
flounced
flounces
flouncing
flounder
floundered
floundering
flounders
flour
flour's
floured
flouring
flourish
flourished
flourishes
flourishing
flours
flout
flouted
flouting
flouts
flow
flowed
flower
flower's
flowerbed
flowerbed's
flowerbeds
flowered
flowerier
floweriest
flowering
flowerpot
flowerpot's
flowerpots
flowers
flowery
flowing
flown
flows
flu
flu's
flub
flubbed
flubbing
flubs
fluctuate
fluctuated
fluctuates
fluctuating
fluctuation
fluctuation's
fluctuations
flue
flue's
fluency
fluency's
fluent
fluently
fluents
flues
fluff
fluff's
fluffed
fluffier
fluffiest
fluffing
fluffs
fluffy
fluid
fluid's
fluidity
fluidity's
fluids
fluke
fluke's
fluked
flukes
fluking
flung
flunk
flunked
flunkies
flunking
flunks
flunky
flunky's
fluorescent
fluoride
fluoride's
fluorides
flurried
flurries
flurry
flurry's
flurrying
flush
flushed
flusher
flushes
flushest
flushing
fluster
flustered
flustering
flusters
flute
flute's
fluted
flutes
fluting
flutist
flutist's
flutists
flutter
fluttered
fluttering
flutters
flux
flux's
fluxed
fluxes
fluxing
fly
flyer
flyer's
flyers
flying
flyover
flyover's
flyovers
flyswatter
flyswatters
foal
foal's
foaled
foaling
foals
foam
foam's
foamed
foamier
foamiest
foaming
foams
foamy
focal
foci
foci's
focus
focus's
focused
focuses
focusing
focussed
focusses
focussing
fodder
fodder's
fodders
foe
foe's
foes
foetal
foetus
foetus's
foetuses
fog
fog's
fogbound
fogey
fogey's
fogeys
fogged
foggier
foggiest
fogging
foggy
foghorn
foghorn's
foghorns
fogs
foible
foible's
foibles
foil
foiled
foiling
foils
foist
foisted
foisting
foists
fold
folded
folder
folder's
folders
folding
folds
foliage
foliage's
folk
folk's
folklore
folklore's
folks
folksier
folksiest
folksy
follicle
follicle's
follicles
follies
follow
followed
follower
follower's
followers
following
followings
follows
folly
folly's
foment
fomented
fomenting
foments
fond
fond's
fonded
fonder
fondest
fonding
fondle
fondled
fondles
fondling
fondly
fondness
fondness's
fonds
font
font's
fonts
food
food's
foods
foodstuff
foodstuff's
foodstuffs
fool
fool's
fooled
foolhardier
foolhardiest
foolhardy
fooling
foolish
foolisher
foolishest
foolishly
foolishness
foolishness's
foolproof
fools
foot
foot's
footage
footage's
football
football's
footballs
footbridge
footbridge's
footbridges
footed
foothill
foothill's
foothills
foothold
foothold's
footholds
footing
footing's
footings
footlights
footlocker
footlocker's
footlockers
footloose
footnote
footnote's
footnoted
footnotes
footnoting
footpath
footpath's
footpaths
footprint
footprint's
footprints
foots
footsie
footsie's
footsies
footstep
footstep's
footsteps
footstool
footstool's
footstools
footwear
footwear's
footwork
footwork's
for
fora
forage
forage's
foraged
forages
foraging
foray
foray's
forayed
foraying
forays
forbad
forbade
forbear
forbearance
forbearance's
forbearing
forbears
forbid
forbidden
forbidding
forbiddings
forbids
forbore
forborne
force
force's
forced
forceful
forcefully
forceps
forceps's
forces
forcible
forcibly
forcing
ford
ford's
forded
fording
fords
fore
forearm
forearm's
forearmed
forearming
forearms
forebode
foreboded
forebodes
foreboding
foreboding's
forebodings
forecast
forecasted
forecasting
forecasts
foreclose
foreclosed
forecloses
foreclosing
foreclosure
foreclosure's
foreclosures
forefather
forefather's
forefathers
forefinger
forefinger's
forefingers
forefront
forefront's
forefronts
forego
foregoes
foregoing
foregoings
foregone
foreground
foreground's
foregrounded
foregrounding
foregrounds
forehand
forehands
forehead
forehead's
foreheads
foreign
foreigner
foreigner's
foreigners
foreleg
foreleg's
forelegs
foreman
foreman's
foremen
foremost
forensic
forensics
foreplay
foreplay's
forerunner
forerunner's
forerunners
fores
foresaw
foresee
foreseeable
foreseeing
foreseen
foresees
foreshadow
foreshadowed
foreshadowing
foreshadows
foresight
foresight's
foreskin
foreskin's
foreskins
forest
forest's
forestall
forestalled
forestalling
forestalls
forested
foresting
forestry
forestry's
forests
foretaste
foretaste's
foretasted
foretastes
foretasting
foretell
foretelling
foretells
forethought
forethought's
foretold
forever
forewarn
forewarned
forewarning
forewarns
forewent
foreword
foreword's
forewords
forfeit
forfeit's
forfeited
forfeiting
forfeits
forgave
forge
forge's
forged
forger
forger's
forgeries
forgers
forgery
forgery's
forges
forget
forgetful
forgetfulness
forgetfulness's
forgets
forgetting
forging
forgivable
forgive
forgiven
forgiveness
forgiveness's
forgives
forgiving
forgo
forgoes
forgoing
forgone
forgot
forgotten
fork
fork's
forked
forking
forklift
forklift's
forklifts
forks
forlorn
forlorner
forlornest
form
form's
formal
formaldehyde
formaldehyde's
formalise
formalised
formalises
formalising
formalities
formality
formality's
formally
formals
format
format's
formation
formation's
formations
formative
formats
formatted
formatting
formed
former
formerly
formidable
formidably
forming
formless
forms
formula
formula's
formulae
formulate
formulated
formulates
formulating
formulation
formulation's
formulations
fornicate
fornicated
fornicates
fornicating
fornication
fornication's
forsake
forsaken
forsakes
forsaking
forsook
forswear
forswearing
forswears
forswore
forsworn
fort
fort's
forte
forte's
fortes
forth
forthcoming
forthright
forthwith
forties
fortieth
fortieths
fortification
fortification's
fortifications
fortified
fortifies
fortify
fortifying
fortitude
fortitude's
fortnight
fortnight's
fortnightly
fortress
fortress's
fortressed
fortresses
fortressing
forts
fortuitous
fortunate
fortunately
fortune
fortune's
fortunes
forty
forty's
forum
forum's
forums
forward
forwarded
forwarder
forwardest
forwarding
forwarding's
forwards
forwent
fossil
fossil's
fossilise
fossilised
fossilises
fossilising
fossils
foster
fostered
fostering
fosters
fought
foul
fouled
fouler
foulest
fouling
fouls
found
foundation
foundation's
foundations
founded
founder
founder's
foundered
foundering
founders
founding
foundling
foundling's
foundries
foundry
foundry's
founds
fount
fount's
fountain
fountain's
fountained
fountaining
fountains
founts
four
four's
fours
fourteen
fourteen's
fourteens
fourteenth
fourteenths
fourth
fourthly
fourths
fowl
fowl's
fowled
fowling
fowls
fox
fox's
foxed
foxes
foxhole
foxhole's
foxholes
foxier
foxiest
foxing
foxtrot
foxtrot's
foxtrots
foxtrotted
foxtrotting
foxy
foyer
foyer's
foyers
fracas
fracas's
fracases
fractal
fraction
fraction's
fractional
fractionally
fractions
fractious
fracture
fracture's
fractured
fractures
fracturing
fragile
fragility
fragility's
fragment
fragment's
fragmentary
fragmentation
fragmentation's
fragmented
fragmenting
fragments
fragrance
fragrance's
fragrances
fragrant
frail
frailer
frailest
frailties
frailty
frailty's
frame
frame's
framed
frames
framework
framework's
frameworks
framing
franc
franc's
franchise
franchise's
franchised
franchises
franchising
francs
frank
franked
franker
frankest
frankfurter
frankfurter's
frankfurters
franking
frankly
frankness
frankness's
franks
frantic
frantically
frat
frat's
fraternal
fraternise
fraternised
fraternises
fraternising
fraternities
fraternity
fraternity's
frats
fraud
fraud's
frauds
fraudulent
fraudulently
fraught
fraughted
fraughting
fraughts
fray
fray's
frayed
fraying
frays
freak
freak's
freaked
freaking
freaks
freckle
freckle's
freckled
freckles
freckling
free
freebie
freebie's
freebies
freed
freedom
freedom's
freedoms
freehand
freeing
freelance
freelance's
freelanced
freelancer
freelancers
freelances
freelancing
freeload
freeloaded
freeloader
freeloader's
freeloaders
freeloading
freeloads
freely
freer
frees
freest
freethinker
freethinker's
freethinkers
freethinking
freeway
freeway's
freeways
freewheel
freewheeled
freewheeling
freewheels
freeze
freezer
freezer's
freezers
freezes
freezing
freight
freight's
freighted
freighter
freighter's
freighters
freighting
freights
french
frenetic
frenzied
frenzies
frenzy
frenzy's
frequencies
frequency
frequency's
frequent
frequented
frequenter
frequentest
frequenting
frequently
frequents
fresh
freshen
freshened
freshening
freshens
fresher
fresher's
freshest
freshly
freshman
freshman's
freshmen
freshness
freshness's
freshwater
freshwater's
fret
fretful
fretfully
frets
fretted
fretting
friar
friar's
friars
friction
friction's
fridge
fridge's
fridges
fried
friend
friend's
friendless
friendlier
friendlies
friendliest
friendliness
friendliness's
friendly
friends
friendship
friendship's
friendships
fries
fries's
frieze
frieze's
friezed
friezes
friezing
frigate
frigate's
frigates
fright
fright's
frighted
frighten
frightened
frightening
frighteningly
frightens
frightful
frightfully
frighting
frights
frigid
frigidity
frigidity's
frill
frill's
frillier
frillies
frilliest
frills
frilly
fringe
fringe's
fringed
fringes
fringing
frisk
frisked
friskier
friskiest
frisking
frisks
frisky
fritter
frittered
frittering
fritters
frivolities
frivolity
frivolity's
frivolous
frivolously
friz
frizz
frizzed
frizzes
frizzier
frizziest
frizzing
frizzy
fro
frock
frock's
frocks
frog
frog's
frogs
frolic
frolic's
frolicked
frolicking
frolics
from
frond
frond's
fronds
front
front's
frontage
frontage's
frontages
frontal
fronted
frontier
frontier's
frontiers
fronting
fronts
frost
frost's
frostbit
frostbite
frostbite's
frostbites
frostbiting
frostbitten
frosted
frostier
frostiest
frosting
frosting's
frosts
frosty
froth
froth's
frothed
frothier
frothiest
frothing
froths
frothy
frown
frowned
frowning
frowns
froze
frozen
frugal
frugality
frugality's
frugally
fruit
fruit's
fruitcake
fruitcake's
fruitcakes
fruited
fruitful
fruitfuller
fruitfullest
fruitier
fruitiest
fruiting
fruition
fruition's
fruitless
fruitlessly
fruits
fruity
frumpier
frumpiest
frumpy
frustrate
frustrated
frustrates
frustrating
frustration
frustration's
frustrations
fry
frying
fuck
fucked
fucker
fucker's
fuckers
fucking
fucks
fudge
fudge's
fudged
fudges
fudging
fuel
fuel's
fuelled
fuelling
fuels
fugitive
fugitive's
fugitives
fulcra
fulcrum
fulcrum's
fulcrums
fulfil
fulfilled
fulfilling
fulfilment
fulfilment's
fulfils
full
fulled
fuller
fuller's
fullest
fulling
fullness
fullness's
fulls
fully
fumble
fumbled
fumbles
fumbling
fume
fumed
fumes
fumigate
fumigated
fumigates
fumigating
fumigation
fumigation's
fuming
fun
fun's
function
function's
functional
functionality
functionally
functioned
functioning
functions
fund
fund's
fundamental
fundamentalism
fundamentalism's
fundamentalist
fundamentalist's
fundamentalists
fundamentally
fundamentals
funded
funding
funds
funeral
funeral's
funerals
fungal
fungals
fungi
fungi's
fungicide
fungicide's
fungicides
fungus
fungus's
funguses
funk
funk's
funked
funkier
funkiest
funking
funks
funky
funnel
funnel's
funnelled
funnelling
funnels
funner
funnest
funnier
funnies
funniest
funnily
funny
fur
fur's
furies
furious
furiously
furl
furled
furling
furlong
furlong's
furlongs
furlough
furlough's
furloughed
furloughing
furloughs
furls
furnace
furnace's
furnaces
furnish
furnished
furnishes
furnishing
furnishings
furniture
furniture's
furor
furor's
furors
furred
furrier
furriest
furring
furrow
furrow's
furrowed
furrowing
furrows
furry
furs
further
furthered
furthering
furthermore
furthers
furthest
furtive
furtively
furtiveness
furtiveness's
fury
fury's
fuse
fuse's
fused
fuselage
fuselage's
fuselages
fuses
fusing
fusion
fusion's
fuss
fuss's
fussed
fusses
fussier
fussiest
fussing
fussy
futile
futilely
futility
futility's
future
future's
futures
futuristic
futuristics
fuzz
fuzz's
fuzzed
fuzzes
fuzzier
fuzziest
fuzzing
fuzzy
fte
fte's
ftes
g
gab
gabbed
gabbier
gabbiest
gabbing
gabby
gable
gable's
gabled
gables
gabling
gabs
gadget
gadget's
gadgets
gaff
gaffe
gaffe's
gaffed
gaffes
gaffing
gaffs
gag
gage
gaged
gages
gagged
gagging
gaggle
gaggles
gaging
gags
gaiety
gaiety's
gaily
gain
gained
gainful
gaining
gains
gait
gait's
gaits
gal
gal's
gala
gala's
galactic
galas
galaxies
galaxy
galaxy's
gale
gale's
gales
gall
gall's
gallant
gallantly
gallantry
gallantry's
gallants
gallbladder
gallbladder's
gallbladders
galled
galleried
galleries
gallery
gallery's
gallerying
galley
galley's
galleys
galling
gallivant
gallivanted
gallivanting
gallivants
gallon
gallon's
gallons
gallop
galloped
galloping
gallops
gallows
gallows's
gallowses
galls
galore
galores
galosh
galoshe
galoshes
gals
galvanise
galvanised
galvanises
galvanising
gambit
gambit's
gambits
gamble
gambled
gambler
gambler's
gamblers
gambles
gambling
game
game's
gamed
gamer
games
gamest
gaming
gaming's
gamma
gamma's
gamut
gamut's
gamuts
gander
gander's
ganders
gang
gang's
ganged
ganging
gangland
gangland's
gangling
gangplank
gangplank's
gangplanks
gangrene
gangrene's
gangrened
gangrenes
gangrening
gangs
gangster
gangster's
gangsters
gangway
gangway's
gangways
gaol
gaol's
gap
gap's
gape
gaped
gapes
gaping
gapings
gaps
garage
garage's
garaged
garages
garaging
garb
garb's
garbage
garbage's
garbed
garbing
garble
garbled
garbles
garbling
garbs
garden
garden's
gardened
gardener
gardener's
gardeners
gardenia
gardenia's
gardenias
gardening
gardening's
gardens
gargantuan
gargle
gargled
gargles
gargling
gargoyle
gargoyle's
gargoyles
garish
garland
garland's
garlanded
garlanding
garlands
garlic
garlic's
garlicked
garlicking
garlics
garment
garment's
garments
garnet
garnet's
garnets
garnish
garnished
garnishes
garnishing
garret
garret's
garrets
garrison
garrison's
garrisoned
garrisoning
garrisons
garrulous
garter
garter's
garters
gas
gas's
gaseous
gases
gash
gashed
gashes
gashing
gasket
gasket's
gaskets
gasoline
gasoline's
gasp
gasped
gasping
gasps
gassed
gasses
gassier
gassiest
gassing
gassy
gastric
gastronomic
gasworks
gasworks's
gate
gate's
gatecrasher
gatecrashers
gated
gates
gateway
gateway's
gateways
gather
gathered
gathering
gathering's
gatherings
gathers
gating
gauche
gaucher
gauchest
gaudier
gaudiest
gaudy
gauge
gauge's
gauged
gauges
gauging
gaunt
gaunted
gaunter
gauntest
gaunting
gauntlet
gauntlet's
gauntlets
gaunts
gauze
gauze's
gave
gavel
gavel's
gavels
gawk
gawk's
gawked
gawkier
gawkies
gawkiest
gawking
gawks
gawky
gay
gayer
gayest
gays
gaze
gazebo
gazebo's
gazeboes
gazebos
gazed
gazelle
gazelle's
gazelles
gazes
gazette
gazette's
gazetted
gazettes
gazetting
gazing
gear
gear's
geared
gearing
gearing's
gears
gearshift
gearshift's
gearshifts
gee
geed
geeing
geek
geek's
geekier
geekiest
geeks
geeky
gees
geese
geese's
geezer
geezer's
geezers
geisha
geisha's
geishas
gel
gel's
gelatin
gelatin's
geld
gelded
gelding
gelding's
geldings
gelds
gelled
gelling
gels
gelt
gem
gem's
gems
gender
gender's
genders
gene
gene's
genealogical
genealogies
genealogist
genealogist's
genealogists
genealogy
genealogy's
genera
genera's
general
generalisation
generalisation's
generalisations
generalise
generalised
generalises
generalising
generality
generality's
generally
generals
generate
generated
generates
generating
generation
generation's
generations
generator
generator's
generators
generic
generically
generics
generosities
generosity
generosity's
generous
generously
genes
geneses
genesis
genesis's
genetic
genetically
geneticist
geneticist's
geneticists
genetics
genetics's
genial
genially
genie
genie's
genies
genii
genital
genitalia
genitals
genius
genius's
geniuses
genocide
genocide's
genre
genre's
genres
gent
gent's
genteel
genteeler
genteelest
gentile
gentiles
gentility
gentility's
gentle
gentled
gentleman
gentleman's
gentlemen
gentleness
gentleness's
gentler
gentles
gentlest
gentling
gently
gentries
gentrification
gentrification's
gentry
gentry's
gents
genuflect
genuflected
genuflecting
genuflects
genuine
genuinely
genuineness
genuineness's
genus
genuses
geographer
geographer's
geographers
geographic
geographical
geographically
geographies
geography
geography's
geologic
geological
geologies
geologist
geologists
geology
geology's
geometric
geometrically
geometries
geometry
geometry's
geranium
geranium's
geraniums
gerbil
gerbil's
gerbils
geriatric
geriatrics
geriatrics's
germ
germ's
germicide
germicide's
germicides
germinate
germinated
germinates
germinating
germination
germination's
germs
gerrymander
gerrymandered
gerrymandering
gerrymanders
gerund
gerund's
gerunds
gestation
gestation's
gesticulate
gesticulated
gesticulates
gesticulating
gesture
gesture's
gestured
gestures
gesturing
get
getaway
getaway's
getaways
gets
getting
getup
getup's
geyser
geyser's
geysers
ghastlier
ghastliest
ghastly
ghetto
ghetto's
ghettoes
ghettos
ghost
ghost's
ghosted
ghosting
ghostlier
ghostliest
ghostly
ghosts
ghostwriter
ghostwriters
ghoul
ghoul's
ghoulish
ghouls
giant
giant's
giants
gibber
gibbered
gibbering
gibberish
gibberish's
gibbers
gibe
gibed
gibes
gibing
giblet
giblets
giddier
giddiest
giddiness
giddiness's
giddy
gift
gift's
gifted
gifting
gifts
gig
gig's
gigabyte
gigabytes
gigantic
gigged
gigging
giggle
giggled
giggles
giggling
gigs
gild
gilded
gilding
gilds
gill
gill's
gills
gilt
gilts
gimme
gimmick
gimmick's
gimmicks
gimmicky
gin
gin's
ginger
ginger's
gingerbread
gingerbread's
gingerly
gingham
gingham's
ginned
ginning
gins
giraffe
giraffe's
giraffes
girder
girder's
girders
girdle
girdle's
girdled
girdles
girdling
girl
girl's
girlfriend
girlfriend's
girlfriends
girlhood
girlhood's
girlhoods
girlish
girls
girth
girth's
girths
gist
gist's
give
giveaway
giveaway's
giveaways
given
givens
gives
giving
gizmo
gizmo's
gizmos
gizzard
gizzard's
gizzards
glacial
glacier
glacier's
glaciers
glad
gladden
gladdened
gladdening
gladdens
gladder
gladdest
glade
glade's
glades
gladiator
gladiator's
gladiators
gladlier
gladliest
gladly
glads
glamor
glamorise
glamorised
glamorises
glamorising
glamorous
glamorously
glamors
glamour
glamour's
glamoured
glamouring
glamours
glance
glanced
glances
glancing
gland
gland's
glands
glandular
glare
glared
glares
glaring
glass
glass's
glassed
glasses
glassier
glassiest
glassing
glassware
glassware's
glassy
glaze
glazed
glazes
glazing
glazing's
gleam
gleam's
gleamed
gleaming
gleamings
gleams
glean
gleaned
gleaning
gleans
glee
glee's
gleeful
gleefully
glen
glen's
glens
glib
glibber
glibbest
glibly
glide
glided
glider
glider's
gliders
glides
gliding
glimmer
glimmered
glimmering
glimmers
glimpse
glimpse's
glimpsed
glimpses
glimpsing
glint
glinted
glinting
glints
glisten
glistened
glistening
glistens
glitch
glitches
glitter
glittered
glittering
glitterings
glitters
glitz
glitzier
glitziest
glitzy
gloat
gloated
gloating
gloats
glob
glob's
global
globally
globe
globe's
globed
globes
globetrotter
globetrotter's
globetrotters
globing
globs
globular
globule
globule's
globules
gloom
gloom's
gloomier
gloomiest
gloomily
gloominess
gloominess's
gloomy
gloried
glories
glorification
glorification's
glorified
glorifies
glorify
glorifying
glorious
gloriously
glory
glory's
glorying
gloss
gloss's
glossaries
glossary
glossary's
glossed
glosses
glossier
glossies
glossiest
glossing
glossy
glove
glove's
gloved
gloves
gloving
glow
glow's
glowed
glower
glowered
glowering
glowers
glowing
glowingly
glows
glowworm
glowworm's
glowworms
glucose
glucose's
glue
glue's
glued
glueing
glues
gluing
glum
glumly
glummer
glummest
glums
glut
glut's
gluts
glutted
glutting
glutton
glutton's
gluttons
gluttony
gluttony's
glycerin
glycerin's
glycerine
gnarl
gnarled
gnarlier
gnarliest
gnarling
gnarls
gnarly
gnash
gnashed
gnashes
gnashing
gnat
gnat's
gnats
gnaw
gnawed
gnawing
gnawing's
gnawn
gnaws
gnome
gnome's
gnomes
gnu
gnu's
gnus
go
go's
goad
goad's
goaded
goading
goads
goal
goal's
goaled
goalie
goalie's
goalies
goaling
goalkeeper
goalkeeper's
goalkeepers
goalpost
goalposts
goals
goat
goat's
goatee
goatee's
goatees
goats
gob
gob's
gobbed
gobbing
gobble
gobbled
gobbledygook
gobbles
gobbling
goblet
goblet's
goblets
goblin
goblin's
goblins
gobs
god
god's
godchild
godchild's
godchildren
goddamn
goddamned
goddess
goddess's
goddesses
godfather
godfather's
godfathers
godforsaken
godless
godlier
godliest
godlike
godly
godmother
godmother's
godmothers
godparent
godparent's
godparents
gods
godsend
godsend's
godsends
goes
gofer
gofer's
gofers
goggle
goggles
going
going's
goings
gold
gold's
golden
goldener
goldenest
golder
goldest
goldfish
goldfish's
goldfishes
golds
goldsmith
goldsmith's
goldsmiths
golf
golf's
golfed
golfer
golfer's
golfers
golfing
golfs
gollies
golly
gondola
gondola's
gondolas
gone
goner
goner's
goners
gong
gong's
gonged
gonging
gongs
gonna
gonorrhoea
gonorrhoea's
goo
goo's
good
goodbye
goodbye's
goodie
goodies
goodness
goodness's
goodnight
goods
goodwill
goodwill's
goody
gooey
goof
goof's
goofed
goofier
goofiest
goofing
goofs
goofy
gooier
gooiest
goon
goon's
goons
goose
goose's
goosed
gooses
goosing
gopher
gopher's
gophers
gore
gore's
gored
gores
gorge
gorge's
gorged
gorgeous
gorgeously
gorges
gorging
gorier
goriest
gorilla
gorilla's
gorillas
goring
gory
gos
gosh
goshes
gosling
gosling's
gospel
gospel's
gospels
gossamer
gossamer's
gossip
gossip's
gossipped
gossipping
gossips
got
gotta
gotten
gouge
gouged
gouges
gouging
goulash
goulash's
goulashes
gourd
gourd's
gourds
gourmet
gourmet's
gourmets
gout
gout's
govern
governed
governess
governess's
governesses
governing
government
government's
governmental
governments
governor
governor's
governors
governorship
governorship's
governs
gown
gown's
gowned
gowning
gowns
grab
grabbed
grabber
grabbing
grabs
grace
grace's
graced
graceful
gracefuller
gracefullest
gracefully
gracefulness
gracefulness's
graceless
graces
gracing
gracious
graciously
graciousness
graciousness's
grad
grad's
gradation
gradation's
gradations
grade
grade's
graded
grader
grader's
graders
grades
gradient
gradient's
gradients
grading
grads
gradual
gradually
graduate
graduate's
graduated
graduates
graduating
graduation
graduation's
graduations
graffiti
graffito
graft
graft's
grafted
grafting
grafts
grain
grain's
grainier
grainiest
grains
grainy
gram
gram's
grammar
grammar's
grammars
grammatical
grammatically
gramophone
gramophone's
grams
grand
grandchild
grandchild's
grandchildren
granddad
granddad's
granddads
granddaughter
granddaughter's
granddaughters
grander
grandest
grandeur
grandeur's
grandfather
grandfather's
grandfathered
grandfathering
grandfathers
grandiose
grandly
grandma
grandma's
grandmas
grandmother
grandmother's
grandmothers
grandpa
grandpa's
grandparent
grandparent's
grandparents
grandpas
grands
grandson
grandson's
grandsons
grandstand
grandstand's
grandstanded
grandstanding
grandstands
granite
granite's
grannie
grannies
granny
granny's
granola
grant
granted
granting
grants
granular
granulate
granulated
granulates
granulating
granule
granule's
granules
grape
grape's
graped
grapefruit
grapefruit's
grapefruits
grapes
grapevine
grapevine's
grapevines
graph
graph's
graphed
graphic
graphical
graphically
graphics
graphics's
graphing
graphite
graphite's
graphs
graping
grapple
grappled
grapples
grappling
grasp
grasped
grasping
grasps
grass
grass's
grassed
grasses
grasshopper
grasshopper's
grasshoppers
grassier
grassiest
grassing
grassland
grassland's
grassy
grate
grated
grateful
gratefuller
gratefullest
gratefully
grater
grater's
graters
grates
gratification
gratification's
gratifications
gratified
gratifies
gratify
gratifying
grating
grating's
gratings
gratis
gratitude
gratitude's
gratuities
gratuitous
gratuitously
gratuity
gratuity's
grave
grave's
graved
gravel
gravel's
gravelled
gravelling
gravels
gravely
graven
graver
graves
gravest
gravestone
gravestone's
gravestones
graveyard
graveyard's
graveyards
gravies
graving
gravitate
gravitated
gravitates
gravitating
gravitation
gravitation's
gravitational
gravity
gravity's
gravy
gravy's
grayish
graze
grazed
grazes
grazing
grease
grease's
greased
greases
greasier
greasiest
greasing
greasy
great
greater
greatest
greatly
greatness
greatness's
greats
greed
greed's
greedier
greediest
greedily
greediness
greediness's
greedy
green
green's
greenback
greenback's
greenbacks
greened
greener
greenery
greenery's
greenest
greenhorn
greenhorn's
greenhorns
greenhouse
greenhouse's
greenhouses
greening
greenish
greens
greet
greeted
greeting
greeting's
greetings
greets
gregarious
gremlin
gremlin's
gremlins
grenade
grenade's
grenades
grew
grey
greyed
greyer
greyest
greyhound
greyhound's
greyhounds
greying
greys
grid
grid's
gridded
griddle
griddle's
griddles
griding
gridiron
gridiron's
gridirons
gridlock
gridlocked
gridlocking
gridlocks
grids
grief
grief's
griefs
grievance
grievance's
grievances
grieve
grieved
grieves
grieving
grievous
grill
grille
grille's
grilled
grilles
grilling
grills
grim
grimace
grimace's
grimaced
grimaces
grimacing
grime
grime's
grimed
grimes
grimier
grimiest
griming
grimly
grimmer
grimmest
grimy
grin
grind
grinder
grinder's
grinders
grinding
grinds
grindstone
grindstone's
grindstones
gringo
gringo's
gringos
grinned
grinning
grins
grip
grip's
gripe
griped
gripes
griping
gripped
gripping
grips
grislier
grisliest
grisly
gristle
gristle's
grit
grit's
grits
gritted
grittier
grittiest
gritting
gritty
grizzled
grizzlier
grizzlies
grizzliest
grizzly
groan
groan's
groaned
groaning
groans
grocer
grocer's
groceries
grocers
grocery
grocery's
groggier
groggiest
groggy
groin
groin's
groins
groom
groom's
groomed
grooming
grooms
groove
groove's
grooved
grooves
groovier
grooviest
grooving
groovy
grope
groped
gropes
groping
gross
grossed
grosser
grosses
grossest
grossing
grossly
grotesque
grotesques
grotto
grotto's
grottoes
grottos
grouch
grouched
grouches
grouchier
grouchiest
grouching
grouchy
ground
ground's
grounded
groundhog
groundhogs
grounding
groundings
groundless
groundlessly
grounds
groundswell
groundswells
groundwork
groundwork's
group
group's
grouped
grouper
groupers
groupie
groupie's
groupies
grouping
grouping's
groupings
groups
grouse
grouse's
groused
grouses
grousing
grove
grove's
grovel
grovelled
grovelling
grovels
groves
grow
grower
grower's
growers
growing
growl
growled
growling
growls
grown
grows
growth
growth's
growths
grub
grubbed
grubbier
grubbiest
grubbing
grubby
grubs
grudge
grudge's
grudged
grudges
grudging
grudgings
gruel
gruel's
gruelled
gruelling
gruellings
gruels
gruesome
gruesomer
gruesomest
gruff
gruffed
gruffer
gruffest
gruffing
gruffly
gruffs
grumble
grumbled
grumbles
grumbling
grumpier
grumpiest
grumpy
grunge
grungier
grungiest
grungy
grunt
grunted
grunting
grunts
gs
guacamole
guacamole's
guarantee
guarantee's
guaranteed
guaranteeing
guarantees
guarantied
guaranties
guarantor
guarantor's
guarantors
guaranty
guaranty's
guarantying
guard
guarded
guardedly
guardian
guardian's
guardians
guarding
guardrail
guardrail's
guardrails
guards
gubernatorial
guerilla
guerrilla
guerrilla's
guerrillas
guess
guessable
guessed
guesses
guessing
guesstimate
guesstimate's
guesstimated
guesstimates
guesstimating
guesswork
guesswork's
guest
guest's
guested
guesting
guests
guff
guff's
guffaw
guffaw's
guffawed
guffawing
guffaws
guidance
guidance's
guide
guidebook
guidebook's
guidebooks
guided
guideline
guideline's
guidelines
guides
guiding
guild
guild's
guilds
guile
guile's
guiled
guileless
guiles
guiling
guillotine
guillotine's
guillotined
guillotines
guillotining
guilt
guilt's
guiltier
guiltiest
guiltily
guiltless
guilty
guinea
guinea's
guise
guise's
guises
guitar
guitar's
guitarist
guitarist's
guitarists
guitars
gulch
gulch's
gulches
gulf
gulf's
gulfs
gull
gull's
gulled
gullet
gullet's
gullets
gullibility
gullibility's
gullible
gullies
gulling
gulls
gully
gully's
gulp
gulped
gulping
gulps
gum
gum's
gumbo
gumbo's
gumbos
gumdrop
gumdrop's
gumdrops
gummed
gummier
gummiest
gumming
gummy
gumption
gumption's
gums
gun
gun's
gunboat
gunboat's
gunboats
gunfire
gunfire's
gunk
gunk's
gunman
gunman's
gunmen
gunned
gunner
gunner's
gunners
gunning
gunnysack
gunnysack's
gunnysacks
gunpoint
gunpoint's
gunpowder
gunpowder's
gunrunner
gunrunner's
gunrunners
gunrunning
gunrunning's
guns
gunshot
gunshot's
gunshots
guppies
guppy
guppy's
gurgle
gurgled
gurgles
gurgling
guru
guru's
gurus
gush
gushed
gusher
gusher's
gushers
gushes
gushier
gushiest
gushing
gushy
gust
gust's
gusted
gustier
gustiest
gusting
gusto
gusto's
gusts
gusty
gut
gut's
guts
gutsier
gutsiest
gutsy
gutted
gutter
gutter's
guttered
guttering
gutters
gutting
guttural
gutturals
guy
guy's
guyed
guying
guys
guzzle
guzzled
guzzler
guzzler's
guzzlers
guzzles
guzzling
gybe
gybed
gybes
gybing
gym
gym's
gymnasia
gymnasium
gymnasium's
gymnasiums
gymnast
gymnast's
gymnastics
gymnastics's
gymnasts
gyms
gynaecological
gynaecologist
gynaecologist's
gynaecologists
gynaecology
gynaecology's
gyp
gypped
gypping
gyps
gypsies
gypsy
gyrate
gyrated
gyrates
gyrating
gyration
gyration's
gyrations
gyroscope
gyroscope's
gyroscopes
h
h'm
ha
haberdasheries
haberdashery
haberdashery's
habit
habit's
habitable
habitat
habitat's
habitation
habitation's
habitations
habitats
habits
habitual
habitually
habituals
hack
hacked
hacker
hacker's
hackers
hacking
hackney
hackneyed
hackneying
hackneys
hacks
hacksaw
hacksaw's
hacksawed
hacksawing
hacksaws
had
haddock
haddock's
haddocks
haded
hades
hading
hadn't
haemoglobin
haemophiliac
haemophiliac's
haemophiliacs
hag
hag's
haggard
hagged
hagging
haggle
haggled
haggles
haggling
hags
hail
hail's
hailed
hailing
hails
hailstone
hailstone's
hailstones
hair
hair's
hairbrush
hairbrush's
hairbrushes
haircut
haircut's
haircuts
haircutting
hairdo
hairdo's
hairdos
hairdresser
hairdresser's
hairdressers
haired
hairier
hairiest
hairline
hairline's
hairlines
hairnet
hairnet's
hairnets
hairpiece
hairpiece's
hairpieces
hairs
hairsplitting
hairsplitting's
hairstyle
hairstyle's
hairstyles
hairstylist
hairstylists
hairy
hale
haled
haler
hales
halest
half
half's
halfhearted
halfheartedly
halftime
halftimes
halfway
halibut
halibut's
halibuts
haling
hall
hall's
hallelujah
hallelujahs
hallmark
hallmark's
hallmarked
hallmarking
hallmarks
hallow
hallowed
hallowing
hallows
halls
hallucinate
hallucinated
hallucinates
hallucinating
hallucination
hallucination's
hallucinations
hallucinogenic
hallucinogenics
hallway
hallway's
hallways
halo
halo's
haloed
haloes
haloing
halon
halos
halt
halt's
halted
halter
halter's
haltered
haltering
halters
halting
haltings
halts
halve
halved
halves
halves's
halving
ham
ham's
hamburger
hamburger's
hamburgers
hamlet
hamlet's
hamlets
hammed
hammer
hammer's
hammered
hammering
hammering's
hammerings
hammers
hamming
hammock
hammock's
hammocks
hamper
hampered
hampering
hampers
hams
hamster
hamster's
hamsters
hamstring
hamstring's
hamstringing
hamstrings
hamstrung
hand
hand's
handbag
handbag's
handbagged
handbagging
handbags
handbook
handbook's
handbooks
handcuff
handcuffed
handcuffing
handcuffs
handcuffs's
handed
handedness
handedness's
handful
handful's
handfuls
handgun
handgun's
handguns
handicap
handicap's
handicapped
handicapping
handicaps
handicraft
handicraft's
handicrafts
handier
handiest
handing
handiwork
handiwork's
handkerchief
handkerchief's
handkerchiefs
handkerchieves
handle
handle's
handlebar
handlebar's
handlebars
handled
handler
handler's
handlers
handles
handling
handling's
handmade
handout
handout's
handouts
handpick
handpicked
handpicking
handpicks
handrail
handrail's
handrails
hands
handsful
handshake
handshake's
handsome
handsomely
handsomer
handsomest
handstand
handstand's
handstands
handwriting
handwriting's
handwritten
handy
handyman
handyman's
handymen
hang
hangar
hangar's
hangars
hanged
hanger
hanger's
hangers
hanging
hanging's
hangings
hangout
hangout's
hangouts
hangover
hangover's
hangovers
hangs
hanker
hankered
hankering
hankering's
hankerings
hankers
hankie
hankie's
hankies
hanky
haphazard
haphazardly
hapless
happen
happened
happening
happening's
happenings
happens
happier
happiest
happily
happiness
happiness's
happy
harangue
harangued
harangues
haranguing
harass
harassed
harasses
harassing
harassment
harassment's
harbour
harbour's
harboured
harbouring
harbours
hard
hardback
hardback's
hardball
hardball's
hardcover
hardcover's
hardcovers
harden
hardened
hardening
hardens
harder
hardest
hardheaded
hardhearted
hardier
hardiest
hardline
hardliner
hardliners
hardly
hardship
hardship's
hardships
hardware
hardware's
hardwood
hardwood's
hardwoods
hardy
hare
hare's
harebrained
hared
harelip
harelip's
harelips
harem
harem's
harems
hares
haring
hark
harked
harking
harks
harlot
harlot's
harlots
harm
harm's
harmed
harmful
harmfully
harming
harmless
harmlessly
harmonic
harmonica
harmonica's
harmonicas
harmonies
harmonious
harmoniously
harmonisation
harmonisation's
harmonise
harmonised
harmonises
harmonising
harmony
harmony's
harms
harness
harness's
harnessed
harnesses
harnessing
harp
harp's
harped
harping
harping's
harpist
harpist's
harpists
harpoon
harpoon's
harpooned
harpooning
harpoons
harps
harpsichord
harpsichord's
harpsichords
harried
harries
harrow
harrowed
harrowing
harrows
harry
harrying
harsh
harsher
harshest
harshly
harshness
harshness's
hart
hart's
harts
harvest
harvest's
harvested
harvester
harvester's
harvesters
harvesting
harvests
has
hash
hash's
hashed
hashes
hashing
hashish
hashish's
hasn't
hassle
hassle's
hassled
hassles
hassling
haste
haste's
hasted
hasten
hastened
hastening
hastens
hastes
hastier
hastiest
hastily
hasting
hasty
hat
hat's
hatch
hatchback
hatchback's
hatchbacks
hatched
hatches
hatchet
hatchet's
hatchets
hatching
hate
hated
hateful
hatefully
hates
hating
hatred
hatred's
hatreds
hats
hatted
hatting
haughtier
haughtiest
haughtily
haughtiness
haughtiness's
haughty
haul
hauled
hauling
hauls
haunch
haunches
haunt
haunted
haunting
haunts
have
haven
haven's
haven't
havens
haves
having
havoc
havoc's
hawk
hawk's
hawked
hawking
hawks
hay
hay's
hayed
haying
hays
haystack
haystack's
haystacks
haywire
haywire's
hazard
hazard's
hazarded
hazarding
hazardous
hazards
haze
haze's
hazed
hazel
hazel's
hazelnut
hazelnut's
hazelnuts
hazels
hazes
hazier
haziest
hazing
hazing's
hazings
hazy
he
he'd
he'll
he's
head
head's
headache
headache's
headaches
headband
headband's
headbands
headed
header
header's
headers
headfirst
headgear
headgear's
headhunter
headhunter's
headhunters
headier
headiest
heading
heading's
headings
headland
headland's
headlands
headlight
headlight's
headlights
headline
headline's
headlined
headlines
headlining
headlong
headmaster
headmaster's
headmasters
headmistress
headmistress's
headmistresses
headphone
headphones
headquarter
headquarters
headrest
headrest's
headrests
headroom
headroom's
heads
headstone
headstone's
headstones
headstrong
headway
headway's
headwind
headwind's
headwinds
heady
heal
healed
healer
healer's
healers
healing
heals
health
health's
healthful
healthier
healthiest
healthily
healthy
heap
heap's
heaped
heaping
heaps
hear
heard
hearing
hearing's
hearings
hears
hearsay
hearsay's
hearse
hearse's
hearsed
hearses
hearsing
heart
heart's
heartache
heartache's
heartaches
heartbeat
heartbeat's
heartbeats
heartbreak
heartbreak's
heartbreaking
heartbreaks
heartbroke
heartbroken
heartburn
heartburn's
hearted
hearten
heartened
heartening
heartens
heartfelt
hearth
hearth's
hearths
heartier
hearties
heartiest
heartily
hearting
heartland
heartland's
heartlands
heartless
hearts
heartthrob
heartthrob's
heartthrobs
heartwarming
hearty
heat
heat's
heated
heatedly
heater
heater's
heaters
heath
heath's
heathen
heathen's
heathens
heather
heather's
heating
heats
heave
heaved
heaven
heaven's
heavenlier
heavenliest
heavenly
heavens
heaves
heavier
heavies
heaviest
heavily
heaviness
heaviness's
heaving
heavy
heavyweight
heavyweight's
heavyweights
heck
heckle
heckled
heckler
heckler's
hecklers
heckles
heckling
hectic
hectics
hedge
hedge's
hedged
hedgehog
hedgehog's
hedgehogs
hedges
hedging
hedonism
hedonism's
hedonist
hedonist's
hedonistic
hedonists
heed
heed's
heeded
heeding
heedless
heeds
heel
heel's
heeled
heeling
heels
heftier
heftiest
hefty
heifer
heifer's
heifers
height
height's
heighten
heightened
heightening
heightens
heights
heinous
heir
heir's
heiress
heiress's
heiresses
heirloom
heirloom's
heirlooms
heirs
heist
heist's
heisted
heisting
heists
held
helicopter
helicopter's
helicoptered
helicoptering
helicopters
heliport
heliport's
heliports
helium
helium's
hell
hell's
helling
hellish
hello
hello's
helloed
hellos
hells
helm
helm's
helmet
helmet's
helmeted
helmeting
helmets
helms
help
helped
helper
helper's
helpers
helpful
helpfully
helpfulness
helpfulness's
helping
helping's
helpings
helpless
helplessly
helplessness
helplessness's
helps
hem
hem's
hemisphere
hemisphere's
hemispheres
hemline
hemline's
hemlines
hemlock
hemlock's
hemlocks
hemmed
hemming
hemoglobin's
hemophilia
hemophilia's
hemorrhage
hemorrhage's
hemorrhaged
hemorrhages
hemorrhaging
hemorrhoid
hemorrhoids
hemp
hemp's
hems
hen
hen's
hence
henceforth
hences
henchman
henchman's
henchmen
hens
hepatitis
hepatitis's
her
herald
herald's
heralded
heralding
heralds
herb
herb's
herbal
herbivore
herbivore's
herbivores
herbivorous
herbs
herd
herd's
herded
herding
herds
here
hereabouts
hereafter
hereafters
hereby
hereditary
heredity
heredity's
herein
heresies
heresy
heresy's
heretic
heretic's
heretical
heretics
herewith
heritage
heritage's
heritages
hermaphrodite
hermaphrodite's
hermetic
hermetics
hermit
hermit's
hermits
hernia
hernia's
herniae
hernias
hero
hero's
heroes
heroic
heroically
heroin
heroin's
heroine
heroine's
heroins
heroism
heroism's
heron
heron's
herons
heros
herpes
herpes's
herring
herring's
herrings
hers
herself
hertz
hertz's
hertzes
hes
hesitancy
hesitancy's
hesitant
hesitantly
hesitate
hesitated
hesitates
hesitating
hesitation
hesitation's
hesitations
heterogeneous
heterosexual
heterosexual's
heterosexuality
heterosexuality's
heterosexuals
heuristic
hew
hewed
hewing
hewn
hews
hexadecimal
hexagon
hexagon's
hexagonal
hexagons
hey
heyday
heyday's
heydays
hi
hiatus
hiatus's
hiatuses
hibernate
hibernated
hibernates
hibernating
hibernation
hibernation's
hiccough
hiccough's
hiccoughed
hiccoughing
hiccoughs
hiccupped
hiccupping
hick
hick's
hickey
hickey's
hickeys
hickories
hickory
hickory's
hicks
hid
hidden
hide
hideaway
hideaway's
hideaways
hided
hideous
hideously
hideout
hideout's
hideouts
hides
hiding
hiding's
hierarchical
hierarchies
hierarchy
hierarchy's
hieroglyphic
hieroglyphics
hieroglyphics's
high
highbrow
highbrow's
highbrows
higher
highest
highland
highland's
highlands
highlight
highlight's
highlighted
highlighter
highlighters
highlighting
highlights
highly
highs
highway
highway's
highways
hijack
hijacked
hijacker
hijacker's
hijackers
hijacking
hijackings
hijacks
hike
hiked
hiker
hiker's
hikers
hikes
hiking
hilarious
hilariously
hilarity
hilarity's
hill
hill's
hillbillies
hillbilly
hillbilly's
hillier
hilliest
hills
hillside
hillside's
hillsides
hilltop
hilltop's
hilltops
hilly
hilt
hilt's
hilts
him
hims
himself
hind
hinder
hindered
hindering
hinders
hindquarter
hindquarters
hindrance
hindrance's
hindrances
hinds
hindsight
hindsight's
hinge
hinge's
hinged
hinges
hinging
hint
hint's
hinted
hinterland
hinterland's
hinterlands
hinting
hints
hip
hip's
hipped
hipper
hippest
hippie
hippie's
hippier
hippies
hippiest
hipping
hippo
hippo's
hippopotami
hippopotamus
hippopotamus's
hippopotamuses
hippos
hippy
hips
hire
hired
hires
hiring
his
hiss
hiss's
hissed
hisses
hissing
histogram
histogram's
historian
historian's
historians
historic
historical
historically
histories
history
history's
histrionic
histrionics
histrionics's
hit
hitch
hitched
hitches
hitchhike
hitchhiked
hitchhiker
hitchhikers
hitchhikes
hitchhiking
hitching
hither
hitherto
hits
hitting
hive
hive's
hived
hives
hiving
ho
hoard
hoard's
hoarded
hoarder
hoarder's
hoarders
hoarding
hoarding's
hoards
hoarse
hoarsely
hoarseness
hoarseness's
hoarser
hoarsest
hoax
hoax's
hoaxed
hoaxes
hoaxing
hobbies
hobbit
hobble
hobbled
hobbles
hobbling
hobby
hobby's
hobbyhorse
hobbyhorse's
hobbyhorses
hobgoblin
hobgoblin's
hobgoblins
hobnob
hobnobbed
hobnobbing
hobnobs
hobo
hobo's
hoboed
hoboes
hoboing
hobos
hock
hock's
hocked
hockey
hockey's
hocking
hocks
hodgepodge
hodgepodge's
hodgepodges
hoe
hoe's
hoed
hoeing
hoes
hog
hog's
hogged
hogging
hogs
hoist
hoisted
hoisting
hoists
hokey
hokier
hokiest
hold
holder
holder's
holders
holding
holding's
holdings
holdover
holdover's
holdovers
holds
holdup
holdup's
holdups
hole
hole's
holed
holes
holiday
holiday's
holidayed
holidaying
holidays
holier
holiest
holiness
holiness's
holing
holistic
holler
hollered
hollering
hollers
hollies
hollow
hollowed
hollower
hollowest
hollowing
hollows
holly
holly's
holocaust
holocaust's
holocausts
hologram
hologram's
holograms
holster
holster's
holstered
holstering
holsters
holy
homage
homage's
homaged
homages
homaging
home
home's
homecoming
homecoming's
homecomings
homed
homeland
homeland's
homelands
homeless
homelessness
homelessness's
homelier
homeliest
homely
homemade
homemaker
homemaker's
homemakers
homeowner
homeowners
homer
homer's
homered
homering
homeroom
homeroom's
homerooms
homers
homes
homesick
homesickness
homesickness's
homespun
homestead
homestead's
homesteaded
homesteading
homesteads
hometown
hometown's
hometowns
homeward
homewards
homework
homework's
homey
homeys
homicidal
homicide
homicide's
homicides
homier
homiest
homing
homoeopathic
homoeopathy
homoeopathy's
homogeneity
homogeneity's
homogeneous
homogenise
homogenised
homogenises
homogenising
homonym
homonym's
homonyms
homophobic
homosexual
homosexual's
homosexuality
homosexuality's
homosexuals
homy
honcho
honchos
hone
hone's
honed
honer
hones
honest
honester
honestest
honestly
honesty
honesty's
honey
honey's
honeycomb
honeycomb's
honeycombed
honeycombing
honeycombs
honeyed
honeying
honeymoon
honeymoon's
honeymooned
honeymooning
honeymoons
honeys
honeysuckle
honeysuckle's
honeysuckles
honied
honing
honk
honk's
honked
honking
honks
honoraries
honorary
honour
honour's
honourable
honourably
honoured
honouring
honours
hood
hood's
hooded
hooding
hoodlum
hoodlum's
hoodlums
hoods
hoodwink
hoodwinked
hoodwinking
hoodwinks
hoof
hoof's
hoofed
hoofing
hoofs
hook
hook's
hooked
hooker
hooker's
hookers
hookey
hookey's
hookier
hookiest
hooking
hooks
hooligan
hooligan's
hooligans
hoop
hoop's
hooped
hooping
hoops
hooray
hoorayed
hooraying
hoorays
hoot
hoot's
hooted
hooter
hooter's
hooting
hoots
hooves
hooves's
hop
hop's
hope
hope's
hoped
hopeful
hopefully
hopefulness
hopefulness's
hopefuls
hopeless
hopelessly
hopelessness
hopelessness's
hopes
hoping
hopped
hopper
hopper's
hopping
hopping's
hops
hopscotch
hopscotch's
hopscotched
hopscotches
hopscotching
horde
horde's
horded
hordes
hording
horizon
horizon's
horizons
horizontal
horizontally
horizontals
hormone
hormone's
hormones
horn
horn's
horned
hornet
hornet's
hornets
hornier
horniest
horns
horny
horoscope
horoscope's
horoscopes
horrendous
horrendously
horrible
horribles
horribly
horrid
horrific
horrified
horrifies
horrify
horrifying
horror
horror's
horrors
horse
horse's
horseback
horseback's
horsed
horseman
horseman's
horseplay
horseplay's
horsepower
horsepower's
horseradish
horseradish's
horseradishes
horses
horseshoe
horseshoe's
horseshoed
horseshoeing
horseshoes
horsing
horticultural
horticulture
horticulture's
hose
hose's
hosed
hoses
hosiery
hosiery's
hosing
hospice
hospice's
hospices
hospitable
hospital
hospital's
hospitalisation
hospitalisation's
hospitalisations
hospitalise
hospitalised
hospitalises
hospitalising
hospitality
hospitality's
hospitals
host
host's
hostage
hostage's
hostages
hosted
hostel
hostel's
hosteled
hosteling
hostelled
hostelling
hostels
hostess
hostess's
hostessed
hostesses
hostessing
hostile
hostiles
hostilities
hostility
hostility's
hosting
hosts
hot
hotbed
hotbed's
hotbeds
hotcake
hotcakes
hotel
hotel's
hotels
hothead
hothead's
hotheaded
hotheads
hotly
hotshot
hotshots
hotter
hottest
hound
hound's
hounded
hounding
hounds
hour
hour's
hourglass
hourglass's
hourglasses
hourlies
hourly
hours
house
house's
houseboat
houseboat's
houseboats
housebound
housebreak
housebreaking
housebreaks
housebroke
housebroken
housed
household
household's
households
househusband
househusbands
housekeeper
housekeeper's
housekeepers
housekeeping
housekeeping's
houses
housewares
housewarming
housewarming's
housewarmings
housewife
housewife's
housewives
housework
housework's
housing
housing's
housings
hove
hovel
hovel's
hovels
hover
hovered
hovering
hovers
how
howdied
howdies
howdy
howdying
however
howl
howl's
howled
howling
howls
hows
hub
hub's
hubbub
hubbub's
hubbubs
hubcap
hubcap's
hubcaps
hubs
huddle
huddle's
huddled
huddles
huddling
hue
hue's
hued
hues
huff
huff's
huffed
huffier
huffiest
huffing
huffs
huffy
hug
huge
hugely
huger
hugest
hugged
hugger
hugging
hugs
huh
huhs
hulk
hulk's
hulking
hulks
hull
hull's
hullabaloo
hullabaloo's
hullabaloos
hulled
hulling
hulls
hum
human
humane
humanely
humaner
humanest
humanise
humanised
humanises
humanising
humanism
humanism's
humanist
humanist's
humanists
humanitarian
humanitarianism
humanitarianism's
humanitarians
humanities
humanity
humanity's
humankind
humankind's
humanly
humans
humble
humbled
humbler
humbles
humblest
humbling
humblings
humbly
humbug
humbug's
humdrum
humid
humidified
humidifies
humidify
humidifying
humidity
humidity's
humiliate
humiliated
humiliates
humiliating
humiliation
humiliation's
humiliations
humility
humility's
hummed
humming
hummingbird
hummingbird's
hummingbirds
humorist
humorist's
humorists
humorous
humorously
humour
humour's
humoured
humouring
humours
hump
hump's
humped
humping
humps
hums
hunch
hunch's
hunchback
hunchback's
hunchbacks
hunched
hunches
hunching
hundred
hundred's
hundreds
hundredth
hundredths
hung
hunger
hunger's
hungered
hungering
hungers
hungrier
hungriest
hungrily
hungry
hunk
hunk's
hunker
hunkered
hunkering
hunkers
hunks
hunt
hunted
hunter
hunter's
hunters
hunting
hunting's
hunts
hurdle
hurdle's
hurdled
hurdler
hurdler's
hurdlers
hurdles
hurdling
hurl
hurled
hurling
hurling's
hurls
hurrah
hurrahed
hurrahing
hurrahs
hurray
hurrayed
hurraying
hurrays
hurricane
hurricane's
hurricanes
hurried
hurriedly
hurries
hurry
hurrying
hurt
hurtful
hurting
hurtle
hurtled
hurtles
hurtling
hurts
husband
husband's
husbanded
husbanding
husbands
hush
hushed
hushes
hushing
husk
husk's
husked
huskier
huskies
huskiest
huskily
huskiness
huskiness's
husking
husks
husky
hustle
hustled
hustler
hustler's
hustlers
hustles
hustling
hut
hut's
hutch
hutch's
hutched
hutches
hutching
huts
hyacinth
hyacinth's
hyacinths
hybrid
hybrid's
hybrids
hydrant
hydrant's
hydrants
hydraulic
hydraulicked
hydraulicking
hydraulics
hydraulics's
hydroelectric
hydrogen
hydrogen's
hydroplane
hydroplane's
hydroplaned
hydroplanes
hydroplaning
hyena
hyena's
hyenas
hygiene
hygiene's
hygienic
hygienically
hygienics
hymn
hymn's
hymnal
hymnal's
hymnals
hymned
hymning
hymns
hype
hype's
hyped
hyper
hyperactive
hyperactives
hyperactivity
hyperactivity's
hyperbole
hyperbole's
hypersensitive
hypertension
hypertension's
hyperventilate
hyperventilated
hyperventilates
hyperventilating
hypes
hyphen
hyphen's
hyphenate
hyphenated
hyphenates
hyphenating
hyphenation
hyphenation's
hyphened
hyphening
hyphens
hyping
hypnosis
hypnosis's
hypnotic
hypnotics
hypnotise
hypnotised
hypnotises
hypnotising
hypnotism
hypnotism's
hypnotist
hypnotist's
hypnotists
hypochondria
hypochondria's
hypochondriac
hypochondriac's
hypochondriacs
hypocrisies
hypocrisy
hypocrisy's
hypocrite
hypocrite's
hypocrites
hypocritical
hypocritically
hypodermic
hypodermics
hypotenuse
hypotenuse's
hypotenuses
hypothermia
hypothermia's
hypotheses
hypothesis
hypothesis's
hypothesise
hypothesised
hypothesises
hypothesising
hypothetical
hypothetically
hysterectomies
hysterectomy
hysterectomy's
hysteria
hysteria's
hysteric
hysterical
hysterically
hysterics
i
ice
ice's
iceberg
iceberg's
icebergs
icebox
icebox's
iceboxes
icebreaker
icebreaker's
icebreakers
iced
ices
icicle
icicle's
icicles
icier
iciest
icing
icing's
icings
ickier
ickiest
icky
icon
icon's
icons
icy
id
id's
idea
idea's
ideal
ideal's
idealise
idealised
idealises
idealising
idealism
idealism's
idealist
idealist's
idealistic
idealists
ideally
ideals
ideas
identical
identically
identifiable
identification
identification's
identified
identifier
identifier's
identifiers
identifies
identify
identifying
identities
identity
identity's
ideological
ideologically
ideologies
ideology
ideology's
idiocies
idiocy
idiocy's
idiom
idiom's
idiomatic
idioms
idiosyncrasies
idiosyncrasy
idiosyncrasy's
idiosyncratic
idiot
idiot's
idiotic
idiotically
idiots
idle
idled
idleness
idleness's
idler
idles
idlest
idling
idly
idol
idol's
idolatrous
idolatry
idolatry's
idolise
idolised
idolises
idolising
idols
idyllic
if
iffier
iffiest
iffy
ifs
igloo
igloo's
igloos
ignite
ignited
ignites
igniting
ignition
ignition's
ignitions
ignorance
ignorance's
ignorant
ignorants
ignore
ignored
ignores
ignoring
iguana
iguana's
iguanas
ilk
ilk's
ill
illegal
illegally
illegals
illegible
illegibly
illegitimacy
illegitimacy's
illegitimate
illicit
illiteracy
illiteracy's
illiterate
illiterates
illness
illness's
illnesses
illogical
illogically
ills
illuminate
illuminated
illuminates
illuminating
illumination
illumination's
illuminations
illusion
illusion's
illusions
illusory
illustrate
illustrated
illustrates
illustrating
illustration
illustration's
illustrations
illustrative
illustrator
illustrator's
illustrators
illustrious
image
image's
imaged
imagery
imagery's
images
imaginable
imaginary
imagination
imagination's
imaginations
imaginative
imaginatively
imagine
imagined
imagines
imaging
imagining
imbalance
imbalance's
imbalanced
imbalances
imbecile
imbecile's
imbeciles
imbibe
imbibed
imbibes
imbibing
imbue
imbued
imbues
imbuing
imitate
imitated
imitates
imitating
imitation
imitation's
imitations
imitative
imitator
imitator's
imitators
immaculate
immaculately
immaterial
immature
immatures
immaturity
immaturity's
immeasurable
immeasurably
immediacy
immediacy's
immediate
immediately
immense
immensely
immenser
immensest
immensities
immensity
immensity's
immerse
immersed
immerses
immersing
immersion
immersion's
immersions
immigrant
immigrant's
immigrants
immigrate
immigrated
immigrates
immigrating
immigration
immigration's
imminent
imminently
immobile
immobilise
immobilised
immobilises
immobilising
immobility
immobility's
immoral
immoralities
immorality
immorality's
immorally
immortal
immortalise
immortalised
immortalises
immortalising
immortality
immortality's
immortals
immovable
immune
immunisation
immunisation's
immunisations
immunise
immunised
immunises
immunising
immunity
immunity's
immutable
imp
imp's
impact
impact's
impacted
impacting
impacts
impair
impaired
impairing
impairment
impairment's
impairments
impairs
impale
impaled
impales
impaling
impart
imparted
impartial
impartiality
impartiality's
impartially
imparting
imparts
impassable
impasse
impasse's
impasses
impassioned
impassive
impatience
impatience's
impatiences
impatient
impatiently
impeach
impeached
impeaches
impeaching
impeachment
impeachment's
impeachments
impeccable
impeccables
impeccably
impedance
impedance's
impede
impeded
impedes
impediment
impediment's
impediments
impeding
impel
impelled
impelling
impels
impend
impended
impending
impends
impenetrable
imperative
imperatives
imperceptible
imperceptibly
imperfect
imperfection
imperfection's
imperfections
imperfectly
imperfects
imperial
imperialism
imperialism's
imperialist
imperialist's
imperialists
imperials
imperil
imperilled
imperilling
imperils
impersonal
impersonally
impersonate
impersonated
impersonates
impersonating
impersonation
impersonation's
impersonations
impersonator
impersonator's
impersonators
impertinence
impertinence's
impertinent
impertinents
impervious
impetuous
impetuously
impetus
impetus's
impetuses
impinge
impinged
impinges
impinging
impish
implacable
implant
implanted
implanting
implants
implausible
implement
implement's
implementable
implementation
implementation's
implementations
implemented
implementer
implementer's
implementing
implements
implicate
implicated
implicates
implicating
implication
implication's
implications
implicit
implicitly
implied
implies
implode
imploded
implodes
imploding
implore
implored
implores
imploring
imply
implying
impolite
impolitely
import
importance
importance's
important
importantly
importation
importation's
importations
imported
importer
importer's
importers
importing
imports
impose
imposed
imposes
imposing
imposition
imposition's
impositions
impossibilities
impossibility
impossibility's
impossible
impossibles
impossibly
impostor
impostor's
impostors
impotence
impotence's
impotent
impound
impounded
impounding
impounds
impoverish
impoverished
impoverishes
impoverishing
impractical
imprecise
impregnable
impregnate
impregnated
impregnates
impregnating
impress
impressed
impresses
impressing
impression
impression's
impressionable
impressionistic
impressions
impressive
impressively
imprint
imprint's
imprinted
imprinting
imprints
imprison
imprisoned
imprisoning
imprisonment
imprisonment's
imprisonments
imprisons
improbabilities
improbability
improbability's
improbable
improbably
impromptu
impromptus
improper
improperly
improprieties
impropriety
impropriety's
improve
improved
improvement
improvement's
improvements
improves
improving
improvisation
improvisation's
improvisations
improvise
improvised
improvises
improvising
imps
impudence
impudence's
impudent
impulse
impulse's
impulsed
impulses
impulsing
impulsive
impulsively
impulsiveness
impulsiveness's
impunity
impunity's
impure
impurer
impurest
impurities
impurity
impurity's
in
inabilities
inability
inability's
inaccessibility
inaccessibility's
inaccessible
inaccuracies
inaccuracy
inaccuracy's
inaccurate
inaction
inaction's
inactive
inactivity
inactivity's
inadequacies
inadequacy
inadequacy's
inadequate
inadequately
inadequates
inadmissible
inadvertent
inadvertently
inadvisable
inalienable
inane
inaner
inanest
inanimate
inapplicable
inappropriate
inarticulate
inarticulates
inasmuch
inattention
inattention's
inattentive
inaudible
inaudibly
inaugural
inaugurals
inaugurate
inaugurated
inaugurates
inaugurating
inauguration
inauguration's
inaugurations
inauspicious
inborn
inbred
inbreds
inbreed
inbreeding
inbreeding's
inbreeds
inbuilt
incalculable
incandescence
incandescence's
incandescent
incandescents
incantation
incantation's
incantations
incapable
incapacitate
incapacitated
incapacitates
incapacitating
incapacity
incapacity's
incarcerate
incarcerated
incarcerates
incarcerating
incarceration
incarceration's
incarcerations
incarnate
incarnated
incarnates
incarnating
incarnation
incarnation's
incarnations
incendiaries
incendiary
incense
incense's
incensed
incenses
incensing
incentive
incentive's
incentives
inception
inception's
inceptions
incessant
incessantly
incest
incest's
incestuous
inch
inch's
inched
inches
inching
incidence
incidence's
incidences
incident
incident's
incidental
incidentally
incidentals
incidents
incinerate
incinerated
incinerates
incinerating
incineration
incineration's
incinerator
incinerator's
incinerators
incision
incision's
incisions
incisive
incisor
incisor's
incisors
incite
incited
incitement
incitement's
incitements
incites
inciting
inclination
inclination's
inclinations
incline
inclined
inclines
inclining
include
included
includes
including
inclusion
inclusion's
inclusions
inclusive
incognito
incognitos
incoherence
incoherence's
incoherent
incoherently
income
income's
incomes
incoming
incomparable
incompatibilities
incompatibility
incompatibility's
incompatible
incompatibles
incompatibly
incompetence
incompetence's
incompetent
incompetently
incompetents
incomplete
incompletely
incomprehensible
inconceivable
inconclusive
inconclusively
incongruities
incongruity
incongruity's
incongruous
inconsequential
inconsiderable
inconsiderate
inconsistencies
inconsistency
inconsistency's
inconsistent
inconsistently
inconsolable
inconspicuous
inconspicuously
incontinence
incontinence's
incontinent
inconvenience
inconvenience's
inconvenienced
inconveniences
inconveniencing
inconvenient
inconveniently
incorporate
incorporated
incorporates
incorporating
incorporation
incorporation's
incorrect
incorrectly
incorrigible
increase
increased
increases
increasing
increasingly
increasings
incredible
incredibly
incredulity
incredulity's
incredulous
increment
increment's
incremental
incremented
incrementing
increments
incriminate
incriminated
incriminates
incriminating
incrimination
incrimination's
incubate
incubated
incubates
incubating
incubation
incubation's
incubator
incubator's
incubators
incumbent
incumbents
incur
incurable
incurables
incurably
incurred
incurring
incurs
indebted
indebtedness
indebtedness's
indecencies
indecency
indecency's
indecent
indecenter
indecentest
indecently
indecision
indecision's
indecisive
indecisively
indeed
indeeds
indefensible
indefinable
indefinably
indefinite
indefinitely
indefinites
indelible
indelibly
indelicate
indemnified
indemnifies
indemnify
indemnifying
indemnities
indemnity
indemnity's
indent
indentation
indentation's
indentations
indented
indenting
indents
independence
independence's
independent
independently
independents
indescribable
indescribables
indescribably
indestructible
indeterminate
index
index's
indexed
indexes
indexing
indicate
indicated
indicates
indicating
indication
indication's
indications
indicative
indicatives
indicator
indicator's
indicators
indices
indices's
indict
indicted
indicting
indictment
indictment's
indictments
indicts
indifference
indifference's
indifferent
indifferently
indigenous
indigent
indigents
indigestible
indigestibles
indigestion
indigestion's
indignant
indignantly
indignation
indignation's
indignities
indignity
indignity's
indigo
indigo's
indirect
indirection
indirection's
indirectly
indirectness
indirectness's
indiscreet
indiscretion
indiscretion's
indiscretions
indiscriminate
indiscriminately
indispensable
indispensables
indisposed
indisputable
indistinct
indistinctly
indistinguishable
individual
individualism
individualism's
individualist
individualist's
individualistic
individualists
individuality
individuality's
individually
individuals
indivisible
indoctrinate
indoctrinated
indoctrinates
indoctrinating
indoctrination
indoctrination's
indolence
indolence's
indolent
indomitable
indoor
indoors
induce
induced
inducement
inducement's
inducements
induces
inducing
induct
inducted
inducting
induction
induction's
inductions
inducts
indulge
indulged
indulgence
indulgence's
indulgences
indulgent
indulges
indulging
industrial
industrialisation
industrialisation's
industrialise
industrialised
industrialises
industrialising
industrialist
industrialist's
industrialists
industries
industrious
industry
industry's
inebriate
inebriated
inebriates
inebriating
inebriation
inebriation's
inedible
ineffective
ineffectiveness
ineffectiveness's
ineffectual
inefficiencies
inefficiency
inefficiency's
inefficient
inefficiently
inefficients
inelegant
ineligibility
ineligibility's
ineligible
ineligibles
inept
ineptitude
ineptitude's
inequalities
inequality
inequality's
inequities
inequity
inequity's
inert
inertia
inertia's
inertial
inerts
inescapable
inessential
inessentials
inevitability
inevitability's
inevitable
inevitably
inexact
inexcusable
inexhaustible
inexorable
inexorably
inexpensive
inexpensively
inexperience
inexperience's
inexperienced
inexplicable
inexplicably
inextricably
infallibility
infallibility's
infallible
infamies
infamous
infamy
infamy's
infancy
infancy's
infant
infant's
infantile
infantries
infantry
infantry's
infants
infatuate
infatuated
infatuates
infatuating
infatuation
infatuation's
infatuations
infect
infected
infecting
infection
infection's
infections
infectious
infects
infelicities
infelicity
infelicity's
infer
inference
inference's
inferences
inferior
inferiority
inferiority's
inferiors
inferno
inferno's
infernos
inferred
inferring
infers
infertile
infertility
infertility's
infest
infestation
infestation's
infestations
infested
infesting
infests
infidel
infidel's
infidelities
infidelity
infidelity's
infidels
infield
infield's
infielder
infielder's
infielders
infields
infiltrate
infiltrated
infiltrates
infiltrating
infiltration
infiltration's
infiltrator
infiltrator's
infiltrators
infinite
infinitely
infinitesimal
infinitesimals
infinities
infinitive
infinitive's
infinitives
infinity
infinity's
infirm
infirmaries
infirmary
infirmary's
infirmities
infirmity
infirmity's
infix
inflame
inflamed
inflames
inflaming
inflammable
inflammation
inflammation's
inflammations
inflammatory
inflatable
inflatable's
inflatables
inflate
inflated
inflates
inflating
inflation
inflation's
inflationary
inflection
inflection's
inflections
inflexibility
inflexibility's
inflexible
inflexibly
inflict
inflicted
inflicting
infliction
infliction's
inflicts
influence
influence's
influenced
influences
influencing
influential
influenza
influenza's
influx
influx's
influxes
info
info's
infomercial
infomercials
inform
informal
informality
informality's
informally
informant
informant's
informants
information
information's
informational
informative
informed
informer
informer's
informers
informing
informs
infraction
infraction's
infractions
infrared
infrared's
infrastructure
infrastructure's
infrastructures
infrequent
infrequently
infringe
infringed
infringement
infringement's
infringements
infringes
infringing
infuriate
infuriated
infuriates
infuriating
infuriatingly
infuse
infused
infuses
infusing
infusion
infusion's
infusions
ingenious
ingeniously
ingenuity
ingenuity's
ingest
ingested
ingesting
ingests
ingrain
ingrained
ingraining
ingrains
ingratiate
ingratiated
ingratiates
ingratiating
ingratitude
ingratitude's
ingredient
ingredient's
ingredients
inhabit
inhabitant
inhabitant's
inhabitants
inhabited
inhabiting
inhabits
inhalation
inhalation's
inhalations
inhale
inhaled
inhaler
inhaler's
inhalers
inhales
inhaling
inherent
inherently
inherit
inheritance
inheritance's
inheritances
inherited
inheriting
inherits
inhibit
inhibited
inhibiting
inhibition
inhibition's
inhibitions
inhibits
inhospitable
inhuman
inhumane
inhumanities
inhumanity
inhumanity's
initial
initialisation
initialise
initialised
initialises
initialising
initialled
initialling
initially
initials
initiate
initiated
initiates
initiating
initiation
initiation's
initiations
initiative
initiative's
initiatives
initiator
initiator's
initiators
inject
injected
injecting
injection
injection's
injections
injects
injunction
injunction's
injunctions
injure
injured
injures
injuries
injuring
injurious
injury
injury's
injustice
injustice's
injustices
ink
ink's
inked
inkier
inkiest
inking
inkling
inkling's
inks
inky
inlaid
inland
inlay
inlaying
inlays
inlet
inlet's
inlets
inmate
inmate's
inmates
inn
inn's
innards
innate
inned
inner
innermost
inners
inning
inning's
innings
innkeeper
innkeeper's
innkeepers
innocence
innocence's
innocent
innocenter
innocentest
innocently
innocents
innocuous
innovate
innovated
innovates
innovating
innovation
innovation's
innovations
innovative
innovator
innovator's
innovators
inns
innuendo
innuendo's
innuendoed
innuendoes
innuendoing
innuendos
innumerable
inoculate
inoculated
inoculates
inoculating
inoculation
inoculation's
inoculations
inoffensive
inoperative
inopportune
inordinate
inordinately
inorganic
inpatient
inpatient's
inpatients
input
input's
inputs
inputted
inputting
inquest
inquest's
inquests
inquisition
inquisition's
inquisitions
inquisitive
inroad
inroads
ins
insane
insanely
insaner
insanest
insanity
insanity's
insatiable
inscribe
inscribed
inscribes
inscribing
inscription
inscription's
inscriptions
inscrutable
insect
insect's
insecticide
insecticide's
insecticides
insects
insecure
insecurities
insecurity
insecurity's
insemination
insemination's
insensitive
insensitively
insensitivity
insensitivity's
inseparable
inseparables
insert
inserted
inserting
insertion
insertion's
insertions
inserts
inside
inside's
insider
insider's
insiders
insides
insidious
insight
insight's
insights
insigne
insignia
insignia's
insignias
insignificance
insignificance's
insignificant
insignificantly
insincere
insincerely
insincerity
insincerity's
insinuate
insinuated
insinuates
insinuating
insinuation
insinuation's
insinuations
insipid
insist
insisted
insistence
insistence's
insistent
insistently
insisting
insists
insofar
insolence
insolence's
insolent
insoluble
insolubles
insolvency
insolvency's
insolvent
insolvents
insomnia
insomnia's
insomniac
insomniacs
inspect
inspected
inspecting
inspection
inspection's
inspections
inspector
inspector's
inspectors
inspects
inspiration
inspiration's
inspirational
inspirations
inspire
inspired
inspires
inspiring
instability
instability's
instal
install
installation
installation's
installations
installed
installing
installs
instalment
instalment's
instalments
instals
instance
instance's
instanced
instances
instancing
instant
instant's
instantaneous
instantaneously
instantly
instants
instead
instep
instep's
insteps
instigate
instigated
instigates
instigating
instigation
instigation's
instil
instill
instilled
instilling
instills
instils
instinct
instinct's
instinctive
instinctively
instincts
institute
instituted
institutes
institutes's
instituting
institution
institution's
institutional
institutionalise
institutionalised
institutionalises
institutionalising
institutions
instruct
instructed
instructing
instruction
instruction's
instructions
instructive
instructively
instructor
instructor's
instructors
instructs
instrument
instrument's
instrumental
instrumentals
instrumented
instrumenting
instruments
insubordinate
insubordination
insubordination's
insubstantial
insufferable
insufficiency
insufficiency's
insufficient
insufficiently
insular
insularity
insularity's
insulate
insulated
insulates
insulating
insulation
insulation's
insulator
insulator's
insulators
insulin
insulin's
insult
insulted
insulting
insults
insurance
insurance's
insurances
insure
insured
insureds
insurer
insurers
insures
insurgencies
insurgency
insurgency's
insurgent
insurgents
insuring
insurmountable
insurrection
insurrection's
insurrections
intact
intake
intake's
intakes
intangible
intangibles
integer
integer's
integers
integral
integrals
integrate
integrated
integrates
integrating
integration
integration's
integrity
integrity's
intellect
intellect's
intellects
intellectual
intellectually
intellectuals
intelligence
intelligence's
intelligent
intelligently
intelligible
intelligibly
intend
intended
intendeds
intending
intends
intense
intensely
intenser
intensest
intensified
intensifier
intensifier's
intensifiers
intensifies
intensify
intensifying
intensities
intensity
intensity's
intensive
intensively
intensives
intent
intent's
intention
intention's
intentional
intentionally
intentions
intently
intents
inter
interact
interacted
interacting
interaction
interaction's
interactions
interactive
interactively
interacts
intercede
interceded
intercedes
interceding
intercept
intercepted
intercepting
interception
interception's
interceptions
intercepts
interchange
interchangeable
interchangeably
interchanged
interchanges
interchanging
intercom
intercom's
intercoms
interconnect
interconnected
interconnecting
interconnects
intercontinental
intercourse
intercourse's
interdependence
interdependence's
interdependent
interest
interest's
interested
interesting
interestingly
interests
interface
interface's
interfaced
interfaces
interfacing
interfacing's
interfere
interfered
interference
interference's
interferes
interfering
interim
interior
interior's
interiors
interject
interjected
interjecting
interjection
interjection's
interjections
interjects
interlock
interlocked
interlocking
interlocks
interloper
interloper's
interlopers
interlude
interlude's
interluded
interludes
interluding
intermarriage
intermarriage's
intermarriages
intermarried
intermarries
intermarry
intermarrying
intermediaries
intermediary
intermediary's
intermediate
intermediates
interment
interment's
interments
interminable
interminably
intermingle
intermingled
intermingles
intermingling
intermission
intermission's
intermissions
intermittent
intermittently
intern
internal
internally
internals
international
internationally
internationals
interned
interning
internist
internist's
internists
internment
internment's
interns
internship
internship's
internships
interpersonal
interplanetary
interplay
interplay's
interpolation
interpolation's
interpose
interposed
interposes
interposing
interpret
interpretation
interpretation's
interpretations
interpreted
interpreter
interpreter's
interpreters
interpreting
interprets
interracial
interred
interrelate
interrelated
interrelates
interrelating
interring
interrogate
interrogated
interrogates
interrogating
interrogation
interrogation's
interrogations
interrogator
interrogator's
interrogators
interrupt
interrupted
interrupting
interruption
interruption's
interruptions
interrupts
inters
intersect
intersected
intersecting
intersection
intersection's
intersections
intersects
intersperse
interspersed
intersperses
interspersing
interstate
interstates
interstellar
intertwine
intertwined
intertwines
intertwining
interval
interval's
intervals
intervene
intervened
intervenes
intervening
intervention
intervention's
interventions
interview
interview's
interviewed
interviewer
interviewer's
interviewers
interviewing
interviews
interweave
interweaved
interweaves
interweaving
interwove
interwoven
intestate
intestinal
intestine
intestine's
intestines
inti
intimacies
intimacy
intimacy's
intimate
intimated
intimately
intimates
intimating
intimation
intimation's
intimations
intimidate
intimidated
intimidates
intimidating
intimidation
intimidation's
into
intolerable
intolerably
intolerance
intolerance's
intolerant
intonation
intonation's
intonations
intoxicate
intoxicated
intoxicates
intoxicating
intoxication
intoxication's
intractable
intramural
intransitive
intransitively
intransitives
intravenous
intravenouses
intrepid
intricacies
intricacy
intricacy's
intricate
intricately
intrigue
intrigued
intrigues
intriguing
intrinsic
intrinsically
introduce
introduced
introduces
introducing
introduction
introduction's
introductions
introductory
introspective
introvert
introvert's
introverted
introverts
intrude
intruded
intruder
intruder's
intruders
intrudes
intruding
intrusion
intrusion's
intrusions
intrusive
intrusives
intuition
intuition's
intuitions
intuitive
intuitively
inundate
inundated
inundates
inundating
inundation
inundation's
inundations
invade
invaded
invader
invader's
invaders
invades
invading
invalid
invalid's
invalidate
invalidated
invalidates
invalidating
invalided
invaliding
invalids
invaluable
invariable
invariables
invariably
invariant
invariant's
invasion
invasion's
invasions
invasive
invective
invective's
invent
invented
inventing
invention
invention's
inventions
inventive
inventor
inventor's
inventoried
inventories
inventors
inventory
inventory's
inventorying
invents
inverse
inversely
inverses
inversion
inversion's
inversions
invert
invertebrate
invertebrate's
invertebrates
inverted
inverting
inverts
invest
invested
investigate
investigated
investigates
investigating
investigation
investigation's
investigations
investigative
investigator
investigator's
investigators
investing
investment
investment's
investments
investor
investor's
investors
invests
inveterate
invigorate
invigorated
invigorates
invigorating
invincible
invisibility
invisibility's
invisible
invisibly
invitation
invitation's
invitations
invite
invited
invites
inviting
invocation
invocation's
invocations
invoice
invoice's
invoiced
invoices
invoicing
invoke
invoked
invokes
invoking
involuntarily
involuntary
involve
involved
involvement
involvement's
involvements
involves
involving
invulnerable
inward
inwardly
inwards
iodine
iodine's
ion
ion's
ions
iota
iota's
iotas
irascible
irate
irater
iratest
ire
ire's
ired
ires
iridescence
iridescence's
iridescent
iring
iris
iris's
irises
irk
irked
irking
irks
iron
iron's
ironed
ironic
ironically
ironies
ironing
ironing's
irons
irony
irony's
irradiate
irradiated
irradiates
irradiating
irrational
irrationality
irrationality's
irrationally
irrationals
irreconcilable
irrefutable
irregular
irregularities
irregularity
irregularity's
irregularly
irregulars
irrelevance
irrelevance's
irrelevances
irrelevant
irreparable
irreparably
irreplaceable
irrepressible
irreproachable
irresistible
irresistibly
irrespective
irresponsibility
irresponsibility's
irresponsible
irresponsibly
irretrievable
irretrievably
irreverence
irreverence's
irreverent
irreverently
irreversible
irrevocable
irrevocably
irrigate
irrigated
irrigates
irrigating
irrigation
irrigation's
irritability
irritability's
irritable
irritably
irritant
irritants
irritate
irritated
irritates
irritating
irritation
irritation's
irritations
is
island
island's
islander
islander's
islanders
islands
isle
isle's
isles
isn't
isolate
isolated
isolates
isolating
isolation
isolation's
issue
issue's
issued
issues
issuing
isthmi
isthmus
isthmus's
isthmuses
it
it'd
it'll
it's
italic
italicise
italicised
italicises
italicising
italics
itch
itch's
itched
itches
itchier
itchiest
itchiness
itchiness's
itching
itchy
item
item's
itemise
itemised
itemises
itemising
items
iterate
iteration
iteration's
iterations
iterative
itinerant
itinerants
itineraries
itinerary
itinerary's
its
itself
ivies
ivories
ivory
ivory's
ivy
ivy's
j
jab
jabbed
jabber
jabbered
jabbering
jabbers
jabbing
jabs
jack
jack's
jackal
jackal's
jackals
jackass
jackass's
jackasses
jackdaw
jackdaw's
jacked
jacket
jacket's
jackets
jackhammer
jackhammer's
jackhammered
jackhammering
jackhammers
jacking
jackknife
jackknife's
jackknifed
jackknifes
jackknifing
jackknives
jackpot
jackpot's
jackpots
jacks
jade
jade's
jaded
jades
jading
jagged
jaggeder
jaggedest
jaguar
jaguar's
jaguars
jail
jail's
jailed
jailer
jailer's
jailers
jailing
jails
jalopies
jalopy
jalopy's
jam
jam's
jamb
jamb's
jambed
jambing
jamboree
jamboree's
jamborees
jambs
jammed
jamming
jams
jangle
jangled
jangles
jangling
janitor
janitor's
janitors
jar
jar's
jargon
jargon's
jarred
jarring
jars
jaundice
jaundice's
jaundiced
jaundices
jaundicing
jaunt
jaunt's
jaunted
jauntier
jaunties
jauntiest
jauntily
jaunting
jaunts
jaunty
javelin
javelin's
javelins
jaw
jaw's
jawbone
jawbone's
jawboned
jawbones
jawboning
jawed
jawing
jaws
jay
jay's
jays
jaywalk
jaywalked
jaywalker
jaywalker's
jaywalkers
jaywalking
jaywalks
jazz
jazz's
jazzed
jazzes
jazzier
jazziest
jazzing
jazzy
jealous
jealousies
jealously
jealousy
jealousy's
jeans
jeer
jeered
jeering
jeers
jeez
jell
jelled
jellied
jellies
jelling
jells
jelly
jelly's
jellyfish
jellyfish's
jellyfishes
jellying
jeopardise
jeopardised
jeopardises
jeopardising
jeopardy
jeopardy's
jerk
jerked
jerkier
jerkiest
jerkily
jerking
jerks
jerky
jersey
jersey's
jerseys
jest
jest's
jested
jester
jester's
jesters
jesting
jests
jet
jet's
jets
jetted
jetties
jetting
jettison
jettisoned
jettisoning
jettisons
jetty
jetty's
jewel
jewel's
jewelled
jeweller
jeweller's
jewellers
jewelling
jewelries
jewelry
jewelry's
jewels
jibe
jibed
jibes
jibing
jiffies
jiffy
jiffy's
jig
jig's
jigged
jigger
jigger's
jiggered
jiggering
jiggers
jigging
jiggle
jiggled
jiggles
jiggling
jigs
jigsaw
jigsaw's
jigsawed
jigsawing
jigsawn
jigsaws
jilt
jilted
jilting
jilts
jingle
jingled
jingles
jingling
jinx
jinx's
jinxed
jinxes
jinxing
jitterier
jitteriest
jitters
jittery
jive
jive's
jived
jives
jiving
job
job's
jobbed
jobbing
jobless
joblessness
joblessness's
jobs
jock
jock's
jocked
jockey
jockey's
jockeyed
jockeying
jockeys
jocking
jocks
jockstrap
jockstrap's
jockstraps
jocular
jocularity
jocularity's
jog
jogged
jogger
jogger's
joggers
jogging
jogs
john
john's
johns
join
joined
joining
joins
joint
joint's
jointed
jointing
jointly
joints
joke
joke's
joked
joker
joker's
jokers
jokes
joking
jollied
jollier
jollies
jolliest
jolly
jollying
jolt
jolted
jolting
jolts
jostle
jostled
jostles
jostling
jot
jots
jotted
jotting
journal
journal's
journalism
journalism's
journalist
journalist's
journalists
journals
journey
journey's
journeyed
journeying
journeys
jovial
jovially
jowl
jowls
joy
joy's
joyed
joyful
joyfuller
joyfullest
joyfully
joyfulness
joyfulness's
joying
joyous
joyously
joyridden
joyride
joyride's
joyrider
joyriders
joyrides
joyriding
joyrode
joys
joystick
joysticks
jubilant
jubilation
jubilation's
jubilee
jubilee's
jubilees
judge
judge's
judged
judgement
judgement's
judgemental
judgements
judges
judging
judicial
judicially
judiciaries
judiciary
judicious
judiciously
judo
judo's
jug
jug's
jugged
juggernaut
juggernaut's
jugging
juggle
juggled
juggler
juggler's
jugglers
juggles
juggling
jugs
jugular
jugulars
juice
juice's
juiced
juices
juicier
juiciest
juicing
juicy
jukebox
jukebox's
jukeboxes
jumble
jumbled
jumbles
jumbling
jumbo
jumbo's
jumbos
jump
jumped
jumper
jumper's
jumpers
jumpier
jumpiest
jumping
jumps
jumpsuit
jumpsuits
jumpy
junction
junction's
junctions
juncture
juncture's
junctures
jungle
jungle's
jungles
junior
juniors
juniper
juniper's
junipers
junk
junk's
junked
junket
junket's
junketed
junketing
junkets
junkie
junkie's
junkier
junkies
junkiest
junking
junks
junky
junkyard
junkyard's
junkyards
junta
junta's
juntas
juries
jurisdiction
jurisdiction's
juror
juror's
jurors
jury
jury's
just
juster
justest
justice
justice's
justices
justifiable
justifiably
justification
justification's
justifications
justified
justifies
justify
justifying
justly
jut
jute
jute's
juts
jutted
jutting
juvenile
juveniles
juxtapose
juxtaposed
juxtaposes
juxtaposing
juxtaposition
juxtaposition's
juxtapositions
k
kW
kaleidoscope
kaleidoscope's
kaleidoscopes
kangaroo
kangaroo's
kangarooed
kangarooing
kangaroos
kaput
kaput's
karat
karat's
karate
karate's
karats
karma
karma's
kayak
kayak's
kayaked
kayaking
kayaks
keel
keel's
keeled
keeling
keels
keen
keened
keener
keenest
keening
keenly
keenness
keenness's
keens
keep
keeper
keeper's
keepers
keeping
keeping's
keeps
keepsake
keepsake's
keepsakes
keg
keg's
kegged
kegging
kegs
kelp
kelp's
ken
ken's
kennel
kennel's
kennelled
kennelling
kennels
kept
kerb
kerb's
kerbed
kerbing
kerbs
kerchief
kerchief's
kerchiefed
kerchiefing
kerchiefs
kerchieves
kernel
kernel's
kernels
kerosene
kerosene's
ketchup
ketchup's
kettle
kettle's
kettles
key
key's
keyboard
keyboard's
keyboarded
keyboarding
keyboards
keyed
keyhole
keyhole's
keyholes
keying
keynote
keynote's
keynoted
keynotes
keynoting
keys
keystone
keystone's
keystones
keystroke
keystroke's
keystrokes
keyword
keyword's
keywords
khaki
khaki's
khakis
kick
kickback
kickback's
kickbacks
kicked
kicking
kickoff
kickoff's
kickoffs
kicks
kid
kid's
kidded
kiddie
kiddied
kiddies
kidding
kidding's
kiddo
kiddo's
kiddoes
kiddos
kiddy
kiddying
kidnap
kidnaped
kidnaping
kidnapped
kidnapper
kidnapper's
kidnappers
kidnapping
kidnappings
kidnaps
kidney
kidney's
kidneys
kids
kill
killed
killer
killer's
killers
killing
killings
kills
kiln
kiln's
kilned
kilning
kilns
kilo
kilo's
kilobyte
kilobytes
kilogramme
kilogramme's
kilogrammes
kilometre
kilometre's
kilometres
kilos
kilowatt
kilowatt's
kilowatts
kilt
kilt's
kilts
kimono
kimono's
kimonos
kin
kin's
kind
kinda
kinder
kindergarten
kindergarten's
kindergartens
kindergrtner
kindergrtner's
kindergrtners
kindest
kindhearted
kindle
kindled
kindles
kindlier
kindliest
kindling
kindling's
kindly
kindness
kindness's
kindnesses
kindred
kinds
kinfolk
king
king's
kingdom
kingdom's
kingdoms
kingfisher
kingfisher's
kingfishers
kingpin
kingpin's
kingpins
kings
kink
kink's
kinked
kinkier
kinkiest
kinking
kinks
kinky
kins
kinship
kinship's
kiosk
kiosk's
kiosks
kipper
kipper's
kiss
kissed
kisses
kissing
kit
kit's
kitchen
kitchen's
kitchened
kitchenette
kitchenette's
kitchenettes
kitchening
kitchens
kite
kite's
kited
kites
kiting
kits
kitten
kitten's
kittens
kitties
kitty
kitty's
kiwi
kiwi's
kiwis
kleptomaniac
kleptomaniac's
kleptomaniacs
klutz
klutz's
klutzes
klutzier
klutziest
klutzy
knack
knack's
knacked
knacker
knacker's
knacking
knacks
knapsack
knapsack's
knapsacks
knead
kneaded
kneading
kneads
knee
knee's
kneecap
kneecap's
kneecapped
kneecapping
kneecaps
kneed
kneeing
kneel
kneeled
kneeling
kneels
knees
knelt
knew
knickers
knickknack
knickknack's
knickknacks
knife
knife's
knifed
knifes
knifing
knight
knight's
knighted
knighthood
knighthood's
knighthoods
knighting
knights
knit
knits
knitted
knitting
knitting's
knives
knives's
knob
knob's
knobbier
knobbiest
knobby
knobs
knock
knocked
knocker
knocker's
knockers
knocking
knockout
knockout's
knockouts
knocks
knoll
knoll's
knolls
knot
knot's
knots
knotted
knottier
knottiest
knotting
knotty
know
knowing
knowinger
knowingest
knowingly
knowings
knowledge
knowledge's
knowledgeable
knowledgeably
known
knows
knuckle
knuckle's
knuckled
knuckles
knuckling
koala
koala's
koalas
kosher
koshered
koshering
koshers
kowtow
kowtowed
kowtowing
kowtows
ks
kudos
kudos's
l
lab
lab's
label
label's
labelled
labelling
labels
laboratories
laboratory
laboratory's
laborious
laboriously
labour
labour's
laboured
labourer
labourer's
labourers
labouring
labours
labs
labyrinth
labyrinth's
labyrinths
lace
lace's
laced
lacerate
lacerated
lacerates
lacerating
laceration
laceration's
lacerations
laces
lacier
laciest
lacing
lack
lack's
lacked
lacking
lacklustre
lacks
lacquer
lacquer's
lacquered
lacquering
lacquers
lacrosse
lacrosse's
lacy
lad
lad's
ladder
ladder's
laddered
laddering
ladders
lade
laded
laden
lades
ladies
lading
ladle
ladle's
ladled
ladles
ladling
lads
lady
lady's
ladybug
ladybug's
ladybugs
ladylike
lag
lager
lager's
laggard
laggard's
laggards
lagged
lagging
lagging's
lagoon
lagoon's
lagoons
lags
laid
lain
lair
lair's
lairs
lake
lake's
laked
lakes
laking
lamb
lamb's
lambda
lambda's
lambed
lambing
lambs
lame
lamed
lament
lamentable
lamentation
lamentation's
lamentations
lamented
lamenting
laments
lamer
lames
lamest
laminate
laminated
laminates
laminating
laming
lamp
lamp's
lampoon
lampoon's
lampooned
lampooning
lampoons
lamps
lampshade
lampshade's
lampshades
lance
lance's
lanced
lances
lancing
land
land's
landed
lander
landfill
landfills
landing
landing's
landings
landladies
landlady
landlady's
landlocked
landlord
landlord's
landlords
landmark
landmark's
landmarks
landowner
landowner's
landowners
lands
landscape
landscape's
landscaped
landscapes
landscaping
landslid
landslidden
landslide
landslide's
landslides
landsliding
lane
lane's
lanes
language
language's
languages
languid
languish
languished
languishes
languishing
languor
languor's
languorous
languors
lankier
lankiest
lanky
lantern
lantern's
lanterns
lap
lap's
lapel
lapel's
lapels
lapped
lapping
laps
lapse
lapse's
lapsed
lapses
lapsing
laptop
laptops
larcenies
larceny
larceny's
lard
lard's
larded
larding
lards
large
largely
larger
larges
largest
lark
lark's
larked
larking
larks
larva
larva's
larvae
larvas
larynges
laryngitis
laryngitis's
larynx
larynx's
larynxes
lascivious
laser
laser's
lasers
lash
lash's
lashed
lashes
lashing
lass
lass's
lasses
lasso
lasso's
lassoed
lassoes
lassoing
lassos
last
lasted
lasting
lastly
lasts
latch
latch's
latched
latches
latching
late
lately
latent
latents
later
lateral
lateraled
lateraling
lateralled
lateralling
laterals
latest
latex
latex's
lath
lathe
lathe's
lathed
lather
lather's
lathered
lathering
lathers
lathes
lathing
laths
latitude
latitude's
latitudes
latrine
latrine's
latrines
latter
lattice
lattice's
lattices
laud
laudable
lauded
lauding
lauds
laugh
laughable
laughed
laughing
laughing's
laughingstock
laughingstock's
laughingstocks
laughs
laughter
laughter's
launch
launched
launcher
launchers
launches
launching
launder
laundered
laundering
launders
laundries
laundry
laundry's
laureate
laureated
laureates
laureating
laurel
laurel's
laurels
lava
lava's
lavatories
lavatory
lavatory's
lavender
lavender's
lavendered
lavendering
lavenders
lavish
lavished
lavisher
lavishes
lavishest
lavishing
law
law's
lawful
lawless
lawlessness
lawlessness's
lawmaker
lawmaker's
lawmakers
lawn
lawn's
lawns
laws
lawsuit
lawsuit's
lawsuits
lawyer
lawyer's
lawyers
lax
laxative
laxative's
laxatives
laxer
laxes
laxest
laxity
laxity's
lay
layaway
layer
layer's
layered
layering
layers
laying
layman
layman's
laymen
layoff
layoff's
layoffs
layout
layout's
layouts
layover
layover's
layovers
lays
lazied
lazier
lazies
laziest
lazily
laziness
laziness's
lazy
lazying
leach
lead
leaded
leaden
leader
leader's
leaders
leadership
leadership's
leading
leads
leaf
leaf's
leafed
leafier
leafiest
leafing
leaflet
leaflet's
leafleted
leafleting
leaflets
leafletted
leafletting
leafs
leafy
league
league's
leagued
leagues
leaguing
leak
leak's
leakage
leakage's
leakages
leaked
leakier
leakiest
leaking
leaks
leaky
lean
leaned
leaner
leanest
leaning
leaning's
leanings
leans
leant
leap
leaped
leapfrog
leapfrog's
leapfrogged
leapfrogging
leapfrogs
leaping
leaps
leapt
learn
learning
learning's
learns
learnt
lease
lease's
leased
leases
leash
leash's
leashed
leashes
leashing
leasing
least
leather
leather's
leathery
leave
leaved
leaves
leaves's
leaving
leaving's
lecherous
lectern
lectern's
lecterns
lecture
lecture's
lectured
lecturer
lecturer's
lecturers
lectures
lecturing
led
ledge
ledge's
ledger
ledger's
ledgered
ledgering
ledgers
ledges
lee
lee's
leech
leech's
leeched
leeches
leeching
leek
leek's
leeks
leer
leered
leerier
leeriest
leering
leers
leery
leeway
leeway's
left
lefter
leftest
leftmost
leftover
leftovers
lefts
leg
leg's
legacies
legacy
legacy's
legal
legalise
legalised
legalises
legalising
legalistic
legality
legality's
legally
legals
legend
legend's
legendary
legends
legged
leggier
leggiest
legging
leggings
leggy
legibility
legibility's
legible
legibly
legion
legion's
legions
legislate
legislated
legislates
legislating
legislation
legislation's
legislative
legislator
legislator's
legislators
legislature
legislature's
legislatures
legit
legitimacy
legitimacy's
legitimate
legitimated
legitimately
legitimates
legitimating
legs
legume
legume's
legumes
leisure
leisure's
leisurely
lemme
lemon
lemon's
lemonade
lemonade's
lemoned
lemoning
lemons
lend
lender
lender's
lenders
lending
lends
length
length's
lengthen
lengthened
lengthening
lengthens
lengthier
lengthiest
lengths
lengthwise
lengthy
leniency
leniency's
lenient
leniently
lenients
lens
lens's
lenses
lent
lentil
lentil's
lentils
leopard
leopard's
leopards
leotard
leotard's
leotards
leper
leper's
lepers
leprosy
leprosy's
leprous
lept
les
lesbian
lesbian's
lesbianism
lesbianism's
lesbians
lesion
lesion's
lesions
less
lessen
lessened
lessening
lessens
lesser
lesson
lesson's
lessons
lest
let
let's
letdown
letdown's
letdowns
lethal
lethally
lethals
lethargic
lethargy
lethargy's
lets
letter
letter's
lettered
letterhead
letterhead's
letterheads
lettering
letters
letting
lettuce
lettuce's
lettuces
letup
letup's
letups
leukaemia
leukaemia's
levee
levee's
levees
level
levelheaded
levelled
leveller
levellest
levelling
levels
lever
lever's
leverage
leverage's
leveraged
leverages
leveraging
levered
levering
levers
levied
levies
levitate
levitated
levitates
levitating
levitation
levitation's
levity
levity's
levy
levying
lewd
lewder
lewdest
lexica
lexical
lexicon
lexicon's
lexicons
liabilities
liability
liability's
liable
liaise
liaised
liaises
liaising
liaison
liaison's
liaisons
liar
liar's
liars
lib
lib's
libbed
libbing
libel
libel's
libelled
libelling
libellous
libels
liberal
liberalisation
liberalisation's
liberalise
liberalised
liberalises
liberalising
liberalism
liberalism's
liberally
liberals
liberate
liberated
liberates
liberating
liberation
liberation's
libertarian
libertarian's
liberties
liberty
liberty's
libido
libido's
libidos
librarian
librarian's
librarians
libraries
library
library's
libretto
libretto's
libs
lice
lice's
licence
licence's
licenced
licences
licencing
license
license's
licensed
licenses
licensing
lichen
lichen's
lichens
lick
licked
licking
licking's
lickings
licks
licorice
licorice's
licorices
lid
lid's
lids
lie
lied
lied's
lien
lien's
liens
lies
lieu
lieu's
lieutenant
lieutenant's
lieutenants
life
life's
lifeboat
lifeboat's
lifeboats
lifeforms
lifeguard
lifeguard's
lifeguards
lifeless
lifelike
lifeline
lifeline's
lifelines
lifelong
lifesaver
lifesaver's
lifesavers
lifespan
lifestyle
lifestyles
lifetime
lifetime's
lifetimes
lift
lift's
lifted
lifting
liftoff
liftoff's
liftoffs
lifts
ligament
ligament's
ligaments
ligature
ligatures
light
light's
lighted
lighten
lightened
lightening
lightens
lighter
lighter's
lighters
lightest
lighthearted
lighthouse
lighthouse's
lighthouses
lighting
lighting's
lightly
lightness
lightness's
lightning
lightning's
lightninged
lightnings
lights
lightweight
lightweights
likable
like
liked
likelier
likeliest
likelihood
likelihood's
likelihoods
likely
liken
likened
likeness
likeness's
likenesses
likening
likens
liker
likes
likest
likewise
liking
liking's
lilac
lilac's
lilacs
lilies
lilt
lilt's
lilted
lilting
lilts
lily
lily's
limb
limb's
limber
limbered
limberer
limberest
limbering
limbers
limbo
limbo's
limboed
limboing
limbos
limbs
lime
lime's
limed
limelight
limelight's
limelighted
limelighting
limelights
limerick
limerick's
limericks
limes
limestone
limestone's
liming
limit
limit's
limitation
limitation's
limitations
limited
limiting
limitings
limitless
limits
limo
limos
limousine
limousine's
limousines
limp
limped
limper
limpest
limping
limps
linchpin
linchpin's
linchpins
line
line's
lineage
lineage's
lineages
linear
linearly
lined
linefeed
linen
linen's
linens
liner
liner's
liners
lines
lineup
lineups
linger
lingered
lingerie
lingerie's
lingering
lingers
lingo
lingo's
lingoes
lingos
linguist
linguist's
linguistic
linguistics
linguistics's
linguists
liniment
liniment's
liniments
lining
lining's
linings
link
link's
linkage
linkage's
linkages
linked
linker
linking
links
linoleum
linoleum's
lint
lint's
lints
lion
lion's
lioness
lioness's
lionesses
lions
lip
lip's
lips
lipstick
lipstick's
lipsticked
lipsticking
lipsticks
liquefied
liquefies
liquefy
liquefying
liqueur
liqueur's
liqueured
liqueuring
liqueurs
liquid
liquid's
liquidate
liquidated
liquidates
liquidating
liquidation
liquidation's
liquidations
liquids
liquor
liquor's
liquored
liquoring
liquors
lisp
lisp's
lisped
lisping
lisps
list
list's
listed
listen
listened
listener
listener's
listeners
listening
listens
listing
listing's
listings
listless
listlessly
lists
lit
litanies
litany
litany's
lite
literacy
literacy's
literal
literally
literals
literary
literate
literates
literature
literature's
lites
lithe
lither
lithest
lithium
lithium's
litigate
litigated
litigates
litigating
litigation
litigation's
litre
litre's
litres
litter
litter's
litterbug
litterbug's
litterbugs
littered
littering
litters
little
littler
littlest
liturgical
liturgies
liturgy
liturgy's
livable
live
lived
livelier
liveliest
livelihood
livelihood's
livelihoods
liveliness
liveliness's
lively
liven
livened
livening
livens
liver
liver's
livers
lives
lives's
livest
livestock
livestock's
livid
living
livings
lizard
lizard's
lizards
llama
llama's
llamas
load
load's
loadable
loaded
loader
loader's
loading
loading's
loads
loaf
loaf's
loafed
loafer
loafer's
loafers
loafing
loafs
loam
loam's
loan
loan's
loaned
loaning
loans
loath
loathe
loathed
loather
loathes
loathing
loathing's
loathings
loathsome
loaves
loaves's
lob
lob's
lobbed
lobbied
lobbies
lobbing
lobby
lobby's
lobbying
lobbyist
lobbyist's
lobbyists
lobe
lobe's
lobed
lobes
lobing
lobotomy
lobotomy's
lobs
lobster
lobster's
lobstered
lobstering
lobsters
local
locale
locale's
localed
locales
localing
localise
localised
localises
localising
localities
locality
locality's
localled
localling
locally
locals
locate
located
locates
locating
location
location's
locations
lock
lock's
locked
locker
locker's
lockers
locket
locket's
lockets
locking
locks
locksmith
locksmith's
locksmiths
locomotion
locomotion's
locomotive
locomotive's
locomotives
locust
locust's
locusts
lodge
lodge's
lodged
lodger
lodger's
lodgers
lodges
lodging
lodging's
lodgings
loft
loft's
lofted
loftier
loftiest
loftiness
loftiness's
lofting
lofts
lofty
log
log's
logarithm
logarithm's
logarithmic
logbook
logbook's
logbooks
logged
logger
logger's
logging
logging's
logic
logic's
logical
logically
logician
logician's
logistical
logistics
logjam
logjam's
logjams
logo
logo's
logos
logs
loin
loin's
loincloth
loincloth's
loincloths
loins
loiter
loitered
loiterer
loiterer's
loiterers
loitering
loiters
loll
lolled
lolling
lollipop
lollipop's
lollipops
lolls
lone
lonelier
loneliest
loneliness
loneliness's
lonely
loner
loner's
loners
lonesome
lonesomes
long
longed
longer
longest
longevity
longevity's
longhand
longhand's
longing
longing's
longingly
longings
longish
longitude
longitude's
longitudes
longitudinal
longs
longshoreman
longshoreman's
longshoremen
longtime
look
lookalike
lookalikes
looked
looking
lookout
lookout's
lookouts
looks
loom
loom's
loomed
looming
looms
loon
loon's
looney
looneys
loonier
loonies
looniest
loons
loony
loop
loop's
looped
loophole
loophole's
loopholes
looping
loops
loose
loosed
loosely
loosen
loosened
loosening
loosens
looser
looses
loosest
loosing
loosing's
loot
loot's
looted
looter
looter's
looters
looting
loots
lop
lope
loped
lopes
loping
lopped
lopping
lops
lopsided
lord
lord's
lorded
lording
lords
lore
lore's
lorries
lorry
lorry's
lose
loser
loser's
losers
loses
losing
loss
loss's
losses
lost
lot
lotion
lotion's
lotions
lots
lotteries
lottery
lottery's
lotus
lotus's
lotuses
loud
louder
loudest
loudlier
loudliest
loudly
loudmouth
loudmouth's
loudmouthed
loudmouths
loudness
loudness's
loudspeaker
loudspeaker's
loudspeakers
lounge
lounged
lounges
lounging
louse
louse's
loused
louses
lousier
lousiest
lousing
lousy
lovable
love
loved
lovelier
lovelies
loveliest
loveliness
loveliness's
lovely
lover
lover's
lovers
loves
lovesick
loving
lovingly
lovings
low
lowbrow
lowbrow's
lowbrows
lowdown
lowed
lower
lowercase
lowered
lowering
lowers
lowest
lowing
lowlier
lowliest
lowly
lows
loyal
loyaler
loyalest
loyaller
loyallest
loyally
loyalties
loyalty
loyalty's
lozenge
lozenge's
lozenges
ls
lubricant
lubricant's
lubricants
lubricate
lubricated
lubricates
lubricating
lubrication
lubrication's
lucid
lucidity
lucidity's
lucidly
luck
luck's
lucked
luckier
luckiest
luckily
lucking
lucks
lucky
lucrative
ludicrous
ludicrously
lug
luggage
luggage's
lugged
lugging
lugs
lugubrious
lukewarm
lull
lullabies
lullaby
lullaby's
lulled
lulling
lulls
lumber
lumber's
lumbered
lumbering
lumbering's
lumberjack
lumberjack's
lumberjacks
lumbers
lumberyard
lumberyard's
lumberyards
luminaries
luminary
luminary's
luminous
lump
lump's
lumped
lumpier
lumpiest
lumping
lumps
lumpy
lunacies
lunacy
lunacy's
lunar
lunatic
lunatics
lunch
lunch's
lunchbox
lunchboxes
lunched
luncheon
luncheon's
luncheoned
luncheoning
luncheons
lunches
lunching
lunchtime
lunchtime's
lunchtimes
lung
lung's
lunge
lunge's
lunged
lunges
lunging
lungs
lupin
lupins
lurch
lurched
lurches
lurching
lure
lured
lures
lurid
luridly
luring
lurk
lurked
lurking
lurks
luscious
lush
lusher
lushes
lushest
lust
lust's
lusted
luster
luster's
lustier
lustiest
lusting
lustre
lustre's
lustrous
lusts
lusty
lute
lute's
lutes
luxuriant
luxuriate
luxuriated
luxuriates
luxuriating
luxuries
luxurious
luxuriously
luxury
luxury's
lye
lye's
lying
lymph
lymph's
lymphatic
lymphatics
lynch
lynched
lynches
lynching
lynching's
lynchings
lyre
lyre's
lyres
lyric
lyrical
lyricist
lyricist's
lyricists
lyrics
m
ma
ma'am
ma's
macabre
macaroni
macaroni's
mace
mace's
maced
maces
machete
machete's
machetes
machine
machine's
machined
machinery
machinery's
machines
machining
machinist
machinist's
machinists
macho
macing
macintosh
macintosh's
mackerel
mackerel's
mackerels
macro
macro's
macrocosm
macrocosm's
macrocosms
macros
macroscopic
mad
madam
madam's
madame
madame's
madams
madcap
madcaps
madden
maddened
maddening
maddeningly
maddens
madder
maddest
made
madhouse
madhouse's
madhouses
madly
madman
madman's
madmen
madness
madness's
maelstrom
maelstrom's
maelstroms
magazine
magazine's
magazines
magenta
magenta's
maggot
maggot's
maggots
magic
magic's
magical
magically
magician
magician's
magicians
magicked
magicking
magics
magistrate
magistrate's
magistrates
magnanimity
magnanimity's
magnanimous
magnanimously
magnate
magnate's
magnates
magnesium
magnesium's
magnet
magnet's
magnetic
magnetics
magnetise
magnetised
magnetises
magnetising
magnetism
magnetism's
magnets
magnification
magnification's
magnifications
magnificence
magnificence's
magnificent
magnificently
magnified
magnifies
magnify
magnifying
magnitude
magnitude's
magnitudes
magnolia
magnolia's
magnolias
magnum
magnum's
magpie
magpie's
magpies
mahoganies
mahogany
mahogany's
maid
maid's
maiden
maiden's
maidens
maids
mail
mail's
mailbox
mailbox's
mailboxes
mailed
mailing
mailings
mailman
mailman's
mailmen
mails
maim
maimed
maiming
maims
main
mainframe
mainframes
mainland
mainland's
mainlands
mainline
mainly
mains
mains's
mainstay
mainstay's
mainstays
mainstream
mainstream's
mainstreamed
mainstreaming
mainstreams
maintain
maintainability
maintainable
maintained
maintainer
maintainer's
maintainers
maintaining
maintains
maintenance
maintenance's
maize
maize's
maizes
majestic
majestically
majesties
majesty
majesty's
major
major's
majored
majoring
majorities
majority
majority's
majorly
majors
make
maker
maker's
makers
makes
makeshift
makeshifts
makeup
makeup's
makeups
making
making's
maladies
maladjusted
malady
malady's
malaise
malaise's
malaria
malaria's
male
males
malevolence
malevolent
malformed
malfunction
malfunctioned
malfunctioning
malfunctions
malice
malice's
maliced
malices
malicing
malicious
maliciously
malign
malignancies
malignancy
malignancy's
malignant
malignants
maligned
maligning
maligns
mall
mall's
mallard
mallard's
mallards
malleable
malled
mallet
mallet's
mallets
malling
malls
malnourished
malnutrition
malnutrition's
malpractice
malpractice's
malpractices
malt
malt's
malted
malting
maltreat
maltreated
maltreating
maltreats
malts
mama
mama's
mamas
mammal
mammal's
mammalian
mammalian's
mammals
mammoth
mammoth's
mammoths
man
man's
manacle
manacle's
manacled
manacles
manacling
manage
manageable
managed
management
management's
manager
manager's
managerial
managers
manages
managing
mandarin
mandarin's
mandarins
mandate
mandate's
mandated
mandates
mandating
mandatory
mandible
mandible's
mandibles
mandolin
mandolin's
mandolins
mane
mane's
manes
mange
mange's
manged
manger
manger's
mangers
manges
mangier
mangiest
manging
mangle
mangled
mangles
mangling
mango
mango's
mangoes
mangos
mangrove
mangrove's
mangroves
mangy
manhandle
manhandled
manhandles
manhandling
manhole
manhole's
manholes
manhood
manhood's
manhunt
manhunt's
manhunts
mania
mania's
maniac
maniac's
maniacal
maniacs
manias
manic
manics
manicure
manicure's
manicured
manicures
manicuring
manicurist
manicurist's
manicurists
manifest
manifestation
manifestation's
manifestations
manifested
manifesting
manifestly
manifesto
manifesto's
manifestoed
manifestoes
manifestoing
manifestos
manifests
manifold
manifolded
manifolding
manifolds
manipulate
manipulated
manipulates
manipulating
manipulation
manipulations
manipulative
manipulative's
mankind
mankind's
manlier
manliest
manliness
manliness's
manly
manned
mannequin
mannequin's
mannequins
manner
manner's
mannerism
mannerism's
mannerisms
manners
manning
mannish
manoeuvre
manoeuvre's
manoeuvred
manoeuvres
manoeuvring
manor
manor's
manors
manpower
manpower's
mans
mansion
mansion's
mansions
manslaughter
manslaughter's
mantel
mantel's
mantelpiece
mantelpiece's
mantelpieces
mantels
mantle
mantle's
mantled
mantles
mantling
mantra
mantra's
mantras
manual
manually
manuals
manufacture
manufactured
manufacturer
manufacturer's
manufacturers
manufactures
manufacturing
manure
manure's
manured
manures
manuring
manuscript
manuscript's
manuscripts
many
map
map's
maple
maple's
maples
mapped
mapper
mapping
mapping's
mappings
maps
mar
marathon
marathon's
marathons
marble
marble's
marbled
marbles
marbling
march
marched
marcher
marcher's
marches
marching
mare
mare's
mares
margarine
margarine's
margin
margin's
marginal
marginally
marginals
margins
marigold
marigold's
marigolds
marijuana
marijuana's
marina
marina's
marinade
marinade's
marinaded
marinades
marinading
marinas
marinate
marinated
marinates
marinating
marine
mariner
mariner's
mariners
marines
marionette
marionette's
marionettes
marital
maritime
mark
mark's
markdown
markdown's
markdowns
marked
markedly
marker
marker's
markers
market
market's
marketability
marketability's
marketable
marketed
marketer
marketer's
marketers
marketing
marketing's
marketplace
marketplace's
marketplaces
markets
marking
marking's
markings
marks
marksman
marksman's
marksmen
markup
markup's
markups
marmalade
marmalade's
maroon
marooned
marooning
maroons
marquee
marquee's
marquees
marred
marriage
marriage's
marriages
married
marrieds
marries
marring
marrow
marrow's
marrowed
marrowing
marrows
marry
marrying
mars
marsh
marsh's
marshal
marshal's
marshaled
marshaling
marshalled
marshalling
marshals
marshes
marshier
marshiest
marshmallow
marshmallow's
marshmallows
marshy
marsupial
marsupial's
marsupials
mart
mart's
marted
martial
martin
martin's
marting
marts
martyr
martyr's
martyrdom
martyrdom's
martyred
martyring
martyrs
marvel
marvelled
marvelling
marvellous
marvels
mas
mascara
mascara's
mascaraed
mascaraing
mascaras
mascot
mascot's
mascots
masculine
masculines
masculinity
masculinity's
mash
mash's
mashed
mashes
mashing
mask
mask's
masked
masking
masks
masochism
masochism's
masochist
masochist's
masochistic
masochists
mason
mason's
masonry
masonry's
masons
masquerade
masquerade's
masqueraded
masquerades
masquerading
mass
massacre
massacre's
massacred
massacres
massacring
massage
massage's
massaged
massages
massaging
massed
masses
masseur
masseur's
masseurs
masseuse
masseuse's
masseuses
massing
massive
massively
mast
mast's
master
master's
mastered
masterful
mastering
masterly
mastermind
masterminded
masterminding
masterminds
masterpiece
masterpiece's
masterpieces
masters
mastery
mastery's
masticate
masticated
masticates
masticating
masts
masturbate
masturbated
masturbates
masturbating
masturbation
masturbation's
mat
mat's
matador
matador's
matadors
match
match's
matchbook
matchbook's
matchbooks
matchbox
matchbox's
matchboxes
matched
matches
matching
matchless
matchmaker
matchmaker's
matchmakers
matchmaking
matchmaking's
matchstick
matchstick's
matchsticks
mate
mate's
mated
material
material's
materialise
materialised
materialises
materialising
materialism
materialism's
materialist
materialist's
materialistic
materialists
materials
maternal
maternity
maternity's
mates
math
math's
mathematical
mathematically
mathematician
mathematician's
mathematicians
mathematics
mathematics's
mating
mating's
matine
matines
matriarch
matriarch's
matriarchal
matriarchies
matriarchs
matriarchy
matriarchy's
matrices
matriculate
matriculated
matriculates
matriculating
matriculation
matriculation's
matrimonial
matrimony
matrimony's
matrix
matrix's
matrixes
matron
matron's
matronly
matrons
mats
matt
matte
matte's
matted
matter
matter's
mattered
mattering
matters
mattes
matting
matting's
mattress
mattress's
mattresses
matts
mature
matured
maturer
matures
maturest
maturing
maturities
maturity
maturity's
maudlin
maul
mauled
mauling
mauls
mausolea
mausoleum
mausoleum's
mausoleums
mauve
mauve's
maverick
maverick's
mavericked
mavericking
mavericks
mawkish
maxed
maxes
maxim
maxim's
maxima
maxima's
maximal
maximise
maximised
maximises
maximising
maxims
maximum
maximum's
maximums
maxing
may
maybe
maybes
mayday
maydays
mayhem
mayhem's
mayo
mayonnaise
mayonnaise's
mayor
mayor's
mayors
maze
maze's
mazes
me
meadow
meadow's
meadows
meagre
meal
meal's
mealed
mealier
mealies
mealiest
mealing
meals
mealtime
mealtime's
mealtimes
mealy
mean
meander
meandered
meandering
meanders
meaner
meanest
meaning
meaning's
meaningful
meaningfully
meaningless
meanings
means
means's
meant
meantime
meantime's
meanwhile
measles
measles's
measlier
measliest
measly
measurable
measure
measure's
measured
measurement
measurement's
measurements
measures
measuring
meat
meat's
meatball
meatball's
meatballs
meatier
meatiest
meatloaf
meatloaves
meats
meaty
mecca
meccas
mechanic
mechanic's
mechanical
mechanically
mechanics
mechanisation
mechanisation's
mechanise
mechanised
mechanises
mechanising
mechanism
mechanism's
mechanisms
medal
medal's
medallion
medallion's
medallions
medallist
medallists
medals
meddle
meddled
meddler
meddlers
meddles
meddlesome
meddling
media
media's
mediaeval
median
medians
medias
mediate
mediated
mediates
mediating
mediation
mediation's
mediator
mediator's
mediators
medical
medically
medicals
medicate
medicated
medicates
medicating
medication
medication's
medications
medicinal
medicinals
medicine
medicine's
medicines
medieval
mediocre
mediocrities
mediocrity
mediocrity's
meditate
meditated
meditates
meditating
meditation
meditation's
meditations
medium
mediums
medley
medley's
medleys
meek
meeker
meekest
meekly
meekness
meekness's
meet
meeter
meeting
meeting's
meetinghouse
meetinghouses
meetings
meets
meg
meg's
megabyte
megabytes
megalomania
megalomania's
megalomaniac
megalomaniac's
megalomaniacs
megaphone
megaphone's
megaphoned
megaphones
megaphoning
megaton
megaton's
megatons
megs
melancholy
melancholy's
meld
melded
melding
melds
mellow
mellowed
mellower
mellowest
mellowing
mellows
melodic
melodics
melodies
melodious
melodrama
melodrama's
melodramas
melodramatic
melodramatics
melody
melody's
melon
melon's
melons
melt
meltdown
meltdowns
melted
melting
melts
member
member's
members
membership
membership's
memberships
membrane
membrane's
membranes
memento
memento's
mementoes
mementos
memo
memo's
memoir
memoirs
memorabilia
memorable
memorably
memoranda
memorandum
memorandum's
memorandums
memorial
memorials
memories
memorise
memorised
memorises
memorising
memory
memory's
memos
men
men's
menace
menaced
menaces
menacing
menagerie
menagerie's
menageries
mend
mended
mending
mending's
mends
menial
menials
meningitis
meningitis's
menopause
menopause's
menorah
menorah's
menorahs
menstrual
menstruate
menstruated
menstruates
menstruating
menstruation
menstruation's
mental
mentalities
mentality
mentality's
mentally
menthol
menthol's
mention
mentioned
mentioning
mentions
mentor
mentor's
mentored
mentoring
mentors
menu
menu's
menus
meow
meowed
meowing
meows
mercantile
mercenaries
mercenary
merchandise
merchandise's
merchandised
merchandises
merchandising
merchant
merchant's
merchanted
merchanting
merchants
mercies
merciful
mercifully
merciless
mercilessly
mercury
mercury's
mercy
mercy's
mere
mered
merely
merer
meres
merest
merge
merged
merger
merger's
mergers
merges
merging
meridian
meridian's
meridians
mering
meringue
meringue's
meringues
merit
merit's
merited
meriting
merits
mermaid
mermaid's
mermaids
merrier
merriest
merrily
merriment
merriment's
merry
mes
mesdames
mesh
mesh's
meshed
meshes
meshing
mesmerise
mesmerised
mesmerises
mesmerising
mess
mess's
message
message's
messaged
messages
messaging
messed
messenger
messenger's
messengers
messes
messier
messiest
messing
messy
met
metabolic
metabolism
metabolism's
metabolisms
metal
metal's
metallic
metallurgist
metallurgists
metallurgy
metallurgy's
metals
metamorphose
metamorphoses
metamorphosis
metamorphosis's
metaphor
metaphor's
metaphorical
metaphorically
metaphors
metaphysical
metaphysics
mete
meted
meteor
meteor's
meteoric
meteorite
meteorite's
meteorites
meteorological
meteorologist
meteorologists
meteorology
meteorology's
meteors
meter
meter's
metered
metering
meters
metes
methadone
methadone's
methane
methane's
method
method's
methodical
methodically
methodological
methodologies
methodology
methodology's
methods
meticulous
meticulously
meting
metre
metre's
metred
metres
metric
metring
metro
metro's
metropolis
metropolis's
metropolises
metropolitan
metros
mettle
mettle's
mew
mewed
mewing
mews
mezzanine
mezzanine's
mezzanines
mi
mi's
miaow
miaowed
miaowing
miaows
mice
mice's
microbe
microbe's
microbes
microbiology
microbiology's
microchip
microchips
microcode
microcomputer
microcomputers
microcosm
microcosm's
microcosms
microfiche
microfiche's
microfiches
microfilm
microfilm's
microfilmed
microfilming
microfilms
micrometre
micrometre's
micrometres
microorganism
microorganism's
microorganisms
microphone
microphone's
microphones
microprocessor
microprocessor's
microprocessors
microscope
microscope's
microscopes
microscopic
microsecond
microseconds
microwave
microwave's
microwaved
microwaves
microwaving
midair
midair's
midday
midday's
middle
middleman
middleman's
middlemen
middles
midget
midget's
midgets
midnight
midnight's
midriff
midriff's
midriffs
midst
midst's
midstream
midstream's
midsummer
midsummer's
midterm
midterm's
midterms
midway
midways
midweek
midweek's
midweeks
midwife
midwife's
midwifed
midwifes
midwifing
midwinter
midwinter's
midwived
midwives
midwiving
mien
mien's
miens
miff
miffed
miffing
miffs
might
mightier
mightiest
mighty
migraine
migraine's
migraines
migrant
migrant's
migrants
migrate
migrated
migrates
migrating
migration
migration's
migrations
migratory
mike
mike's
miked
mikes
miking
mild
milder
mildest
mildew
mildew's
mildewed
mildewing
mildews
mildly
mildness
mildness's
mile
mile's
mileage
mileage's
mileages
miles
milestone
milestone's
milestones
milieu
milieu's
milieus
milieux
militancy
militancy's
militant
militants
militaries
militarily
militarism
militarism's
military
militate
militated
militates
militating
militia
militia's
militias
milk
milk's
milked
milker
milkier
milkiest
milking
milkman
milkman's
milkmen
milks
milky
mill
mill's
milled
millennia
millennium
millennium's
millenniums
miller
miller's
millers
milligramme
milligramme's
milligrammes
millilitre
millilitre's
millilitres
millimetre
millimetre's
millimetres
milliner
milliner's
milliners
millinery
millinery's
milling
milling's
million
million's
millionaire
millionaire's
millionaires
millions
millionth
millionth's
millionths
millisecond
milliseconds
mills
mime
mime's
mimed
mimes
mimic
mimicked
mimicking
mimicries
mimicry
mimicry's
mimics
miming
mince
minced
mincemeat
mincemeat's
minces
mincing
mind
mind's
mindbogglingly
minded
mindedness
mindful
minding
mindless
mindlessly
minds
mine
mined
minefield
minefield's
minefields
miner
miner's
mineral
mineral's
minerals
miners
mines
mingle
mingled
mingles
mingling
mini
miniature
miniature's
miniatured
miniatures
miniaturing
minibus
minibus's
minibuses
minibusses
minicomputer
minicomputer's
minima
minimal
minimalism
minimalist
minimalist's
minimally
minimals
minimise
minimised
minimises
minimising
minimum
minimum's
minimums
mining
mining's
minion
minion's
minions
minis
miniseries
miniskirt
miniskirt's
miniskirts
minister
minister's
ministered
ministerial
ministering
ministers
ministries
ministry
ministry's
minivan
minivans
mink
mink's
minks
minnow
minnow's
minnows
minor
minored
minoring
minorities
minority
minority's
minors
minstrel
minstrel's
minstrels
mint
mint's
minted
mintier
mintiest
minting
mints
minty
minuet
minuet's
minuets
minus
minuscule
minuscule's
minuscules
minuses
minute
minute's
minuted
minuter
minutes
minutest
minuting
miracle
miracle's
miracles
miraculous
miraculously
mirage
mirage's
mirages
mire
mire's
mired
mires
miring
mirror
mirror's
mirrored
mirroring
mirrors
mirth
mirth's
misadventure
misadventure's
misadventures
misapprehension
misapprehension's
misappropriate
misappropriated
misappropriates
misappropriating
misappropriation
misappropriations
misbehave
misbehaved
misbehaves
misbehaving
misbehaviour
misbehaviour's
miscalculate
miscalculated
miscalculates
miscalculating
miscalculation
miscalculation's
miscalculations
miscarriage
miscarriage's
miscarriages
miscarried
miscarries
miscarry
miscarrying
miscellaneous
miscellany
miscellany's
mischief
mischief's
mischiefed
mischiefing
mischiefs
mischievous
mischievously
misconception
misconception's
misconceptions
misconduct
misconduct's
misconducted
misconducting
misconducts
misconstrue
misconstrued
misconstrues
misconstruing
misdeed
misdeed's
misdeeds
misdemeanour
misdemeanour's
misdemeanours
misdirect
misdirected
misdirecting
misdirection
misdirection's
misdirects
miser
miser's
miserable
miserables
miserably
miseries
miserly
misers
misery
misery's
misfit
misfit's
misfits
misfitted
misfitting
misfortune
misfortune's
misfortunes
misgiving
misgiving's
misgivings
misguide
misguided
misguides
misguiding
mishap
mishap's
mishapped
mishapping
mishaps
misinform
misinformation
misinformation's
misinformed
misinforming
misinforms
misinterpret
misinterpretation
misinterpretation's
misinterpretations
misinterpreted
misinterpreting
misinterprets
misjudge
misjudged
misjudgement
misjudgements
misjudges
misjudging
mislaid
mislay
mislaying
mislays
mislead
misleading
misleads
misled
mismanage
mismanaged
mismanagement
mismanagement's
mismanages
mismanaging
mismatch
mismatched
mismatches
mismatching
misnomer
misnomer's
misnomered
misnomering
misnomers
misogynist
misogynist's
misogynists
misogyny
misogyny's
misplace
misplaced
misplaces
misplacing
misprint
misprint's
misprinted
misprinting
misprints
mispronounce
mispronounced
mispronounces
mispronouncing
mispronunciation
mispronunciation's
mispronunciations
misquote
misquoted
misquotes
misquoting
misread
misreading
misreadings
misreads
misrepresent
misrepresentation
misrepresentation's
misrepresentations
misrepresented
misrepresenting
misrepresents
miss
missed
misses
misshapen
missile
missile's
missiles
missing
mission
mission's
missionaries
missionary
missionary's
missioned
missioning
missions
missive
missive's
missives
misspell
misspelled
misspelling
misspelling's
misspellings
misspells
misspelt
misspend
misspending
misspends
misspent
misstep
misstep's
misstepped
misstepping
missteps
mist
mist's
mistake
mistake's
mistaken
mistakenly
mistakes
mistaking
misted
mister
mister's
misters
mistier
mistiest
misting
mistletoe
mistletoe's
mistook
mistreat
mistreated
mistreating
mistreatment
mistreatment's
mistreats
mistress
mistress's
mistresses
mistrial
mistrial's
mistrials
mistrust
mistrusted
mistrusting
mistrusts
mists
misty
mistype
mistyping
misunderstand
misunderstanding
misunderstanding's
misunderstandings
misunderstands
misunderstood
misuse
misuse's
misused
misuses
misusing
mite
mite's
mites
mitigate
mitigated
mitigates
mitigating
mitigation
mitigation's
mitt
mitt's
mitten
mitten's
mittens
mitts
mix
mixed
mixer
mixer's
mixers
mixes
mixing
mixt
mixture
mixture's
mixtures
mnemonic
mnemonics
mnemonics's
moan
moan's
moaned
moaning
moans
moat
moat's
moated
moating
moats
mob
mob's
mobbed
mobbing
mobile
mobiles
mobilisation
mobilisation's
mobilisations
mobilise
mobilised
mobilises
mobilising
mobility
mobility's
mobs
moccasin
moccasin's
moccasins
mock
mocked
mockeries
mockery
mockery's
mocking
mockingbird
mockingbird's
mockingbirds
mocks
mod
modal
modals
mode
mode's
model
model's
modelled
modelling
modelling's
modellings
models
modem
modem's
modems
moder
moderate
moderated
moderately
moderates
moderating
moderation
moderation's
moderator
moderator's
moderators
modern
moderner
modernest
modernisation
modernisation's
modernise
modernised
modernises
modernising
modernity
modernity's
moderns
modes
modest
modester
modestest
modestly
modesty
modesty's
modicum
modicum's
modicums
modification
modification's
modifications
modified
modifier
modifier's
modifiers
modifies
modify
modifying
modular
modulate
modulated
modulates
modulating
modulation
modulation's
modulations
module
module's
modules
mohair
mohair's
moist
moisten
moistened
moistening
moistens
moister
moistest
moisture
moisture's
moisturiser
moisturisers
molar
molar's
molars
molasses
molasses's
mold
mold's
molded
molding
molding's
moldings
molds
mole
mole's
molecular
molecule
molecule's
molecules
moles
molest
molestation
molestation's
molested
molester
molester's
molesters
molesting
molests
mollified
mollifies
mollify
mollifying
mollusk
mollusks
molt
molted
molten
molting
molts
mom
mom's
moment
moment's
momentarily
momentary
momentous
moments
momentum
momentum's
momma
mommas
mommie
mommies
mommy
mommy's
moms
monarch
monarch's
monarchies
monarchs
monarchy
monarchy's
monasteries
monastery
monastery's
monastic
monastics
monetarism
monetary
money
money's
mongoose
mongoose's
mongrel
mongrel's
mongrels
monies
monies's
moniker
moniker's
monikers
monitor
monitor's
monitored
monitoring
monitors
monk
monk's
monkey
monkey's
monkeyed
monkeying
monkeys
monks
mono
monochrome
monochrome's
monochromes
monogamous
monogamy
monogamy's
monogram
monogram's
monogramed
monograming
monogrammed
monogramming
monograms
monolingual
monolinguals
monolith
monolith's
monolithic
monoliths
monologue
monologue's
monologued
monologues
monologuing
mononucleosis
mononucleosis's
monopolies
monopolisation
monopolise
monopolised
monopolises
monopolising
monopoly
monopoly's
monorail
monorail's
monorails
monosyllable
monosyllable's
monosyllables
monotone
monotone's
monotoned
monotones
monotonically
monotoning
monotonous
monotonously
monotony
monotony's
monsoon
monsoon's
monsoons
monster
monster's
monsters
monstrosities
monstrosity
monstrosity's
monstrous
montage
montage's
montages
month
month's
monthlies
monthly
months
monument
monument's
monumental
monuments
moo
mooch
mooched
mooches
mooching
mood
mood's
moodier
moodiest
moodily
moodiness
moodiness's
moods
moody
mooed
mooing
moon
moon's
moonbeam
moonbeam's
moonbeams
mooned
mooning
moonlight
moonlight's
moonlighted
moonlighting
moonlighting's
moonlights
moonlit
moons
moor
moor's
moored
mooring
mooring's
moorings
moors
moos
moose
moose's
moot
mooted
mooter
mooting
moots
mop
mop's
mope
moped
moped's
mopeds
mopes
moping
mopped
mopping
mops
moral
morale
morale's
moralist
moralist's
moralistic
moralists
moralities
morality
morality's
moralled
moralling
morally
morals
morass
morass's
morasses
moratoria
moratorium
moratorium's
moratoriums
morbid
more
moreover
mores
morgue
morgue's
morgues
morn
morn's
morned
morning
morning's
mornings
morns
moron
moron's
moronic
morons
morose
morphine
morphine's
morphology
morphology's
morsel
morsel's
morsels
mortal
mortality
mortality's
mortally
mortals
mortar
mortar's
mortarboard
mortarboard's
mortarboards
mortared
mortaring
mortars
mortgage
mortgage's
mortgaged
mortgages
mortgaging
mortician
mortician's
morticians
mortification
mortification's
mortified
mortifies
mortify
mortifying
mortuaries
mortuary
mortuary's
mosaic
mosaic's
mosaics
moses
mosque
mosque's
mosques
mosquito
mosquito's
mosquitoes
mosquitos
moss
moss's
mossed
mosses
mossier
mossies
mossiest
mossing
mossy
most
mostly
motel
motel's
motels
moth
moth's
mothball
mothball's
mothballed
mothballing
mothballs
mother
mother's
motherboard
motherboards
mothered
motherfucker
motherfucker's
motherfuckers
motherhood
motherhood's
mothering
motherly
mothers
moths
motif
motif's
motifs
motion
motion's
motioned
motioning
motionless
motions
motivate
motivated
motivates
motivating
motivation
motivation's
motivations
motive
motive's
motives
motley
motleyer
motleyest
motleys
motlier
motliest
motor
motor's
motorbike
motorbike's
motorbiked
motorbikes
motorbiking
motorboat
motorboat's
motorboats
motorcade
motorcade's
motorcades
motorcycle
motorcycle's
motorcycled
motorcycles
motorcycling
motorcyclist
motorcyclist's
motorcyclists
motored
motoring
motoring's
motorise
motorised
motorises
motorising
motorist
motorist's
motorists
motormouth
motormouths
motors
motorway
motorway's
motorways
mottle
mottled
mottles
mottling
motto
motto's
mottoes
mottos
mould
mould's
moulded
mouldier
mouldiest
moulding
moulding's
mouldings
moulds
mouldy
mound
mound's
mounded
mounding
mounds
mount
mountain
mountain's
mountaineer
mountaineer's
mountaineered
mountaineering
mountaineering's
mountaineers
mountainous
mountains
mountainside
mountainside's
mountainsides
mounted
mounting
mounting's
mountings
mounts
mourn
mourned
mourner
mourner's
mourners
mournful
mournfuller
mournfullest
mournfully
mourning
mourning's
mourns
mouse
mouse's
moused
mouses
mousey
mousier
mousiest
mousing
mousse
mousse's
moussed
mousses
moussing
moustache
moustache's
moustaches
mousy
mouth
mouth's
mouthed
mouthful
mouthful's
mouthfuls
mouthing
mouthpiece
mouthpiece's
mouthpieces
mouths
mouthwash
mouthwash's
mouthwashes
movable
movables
move
moved
movement
movement's
movements
mover
mover's
movers
moves
movie
movie's
movies
moving
mow
mowed
mower
mower's
mowers
mowing
mown
mows
ms
mu
mu's
much
muck
muck's
mucked
mucking
mucks
mucous
mucus
mucus's
mud
mud's
muddied
muddier
muddies
muddiest
muddle
muddled
muddles
muddling
muddy
muddying
mudslide
mudslides
mudslinging
mudslinging's
muff
muff's
muffed
muffin
muffin's
muffing
muffins
muffle
muffled
muffler
muffler's
mufflers
muffles
muffling
muffs
mug
mug's
mugged
mugger
mugger's
muggers
muggier
muggiest
mugginess
mugging
muggings
muggy
mugs
mulatto
mulatto's
mulattoes
mulattos
mulch
mulch's
mulched
mulches
mulching
mule
mule's
muled
mules
muling
mull
mulled
mulling
mulls
multicultural
multilateral
multimedia
multimillionaire
multimillionaire's
multimillionaires
multinational
multinationals
multiple
multiples
multiplex
multiplex's
multiplexed
multiplexes
multiplexing
multiplication
multiplication's
multiplications
multiplicative
multiplicities
multiplicity
multiplicity's
multiplied
multiplies
multiply
multiplying
multiprocessing
multitasking
multitude
multitude's
multitudes
mum
mum's
mumble
mumbled
mumbles
mumbling
mummies
mummified
mummifies
mummify
mummifying
mummy
mummy's
mumps
mumps's
mums
munch
munched
munches
munchies
munching
mundane
mundanes
municipal
municipalities
municipality
municipality's
municipals
munition
munitions
mural
mural's
murals
murder
murder's
murdered
murderer
murderer's
murderers
murdering
murderous
murders
murkier
murkiest
murky
murmur
murmur's
murmured
murmuring
murmurs
muscle
muscle's
muscled
muscles
muscling
muscular
muse
mused
muses
museum
museum's
museums
mush
mush's
mushed
mushes
mushier
mushiest
mushing
mushroom
mushroom's
mushroomed
mushrooming
mushrooms
mushy
music
music's
musical
musically
musicals
musician
musician's
musicians
musicked
musicking
musics
musing
musings
musk
musk's
musked
musket
musket's
muskets
musking
musks
muss
mussed
mussel
mussel's
mussels
musses
mussing
must
mustang
mustang's
mustangs
mustard
mustard's
muster
mustered
mustering
musters
mustier
mustiest
mustn't
musts
musty
mutability
mutability's
mutable
mutant
mutant's
mutants
mutate
mutated
mutates
mutating
mutation
mutation's
mutations
mute
muted
mutely
muter
mutes
mutest
mutilate
mutilated
mutilates
mutilating
mutilation
mutilation's
mutilations
muting
mutinied
mutinies
mutinous
mutiny
mutiny's
mutinying
mutt
mutt's
mutter
muttered
muttering
mutters
mutton
mutton's
mutts
mutual
mutually
muzzle
muzzle's
muzzled
muzzles
muzzling
my
myopic
myopics
myriad
myriads
mys
myself
mysteried
mysteries
mysterious
mysteriously
mystery
mystery's
mysterying
mystic
mystic's
mystical
mysticism
mysticism's
mystics
mystified
mystifies
mystify
mystifying
mystique
mystique's
myth
myth's
mythical
mythological
mythologies
mythology
mythology's
myths
mle
mle's
mles
n
nab
nabbed
nabbing
nabs
nag
nagged
nagging
nags
nail
nail's
nailbrush
nailbrush's
nailbrushes
nailed
nailing
nails
naive
naively
naiver
naives
naivest
naivety
naivety's
naivet
naivet's
naked
nakeder
nakedest
nakedness
nakedness's
name
name's
named
named's
nameless
namely
names
namesake
namesake's
namesakes
naming
naming's
nannied
nannies
nanny
nanny's
nannying
nap
napalm
napalm's
napalmed
napalming
napalms
nape
nape's
napes
napkin
napkin's
napkins
napped
nappier
nappies
nappiest
napping
nappy
nappy's
naps
narc
narced
narcing
narcissism
narcissism's
narcissist
narcissist's
narcissistic
narcissists
narcotic
narcotic's
narcotics
narcs
narrate
narrated
narrates
narrating
narration
narration's
narrations
narrative
narrative's
narratives
narrator
narrator's
narrators
narrow
narrowed
narrower
narrowest
narrowing
narrowly
narrowness
narrowness's
narrows
nasal
nasally
nasals
nastier
nastiest
nastily
nastiness
nastiness's
nasty
nation
nation's
national
nationalisation
nationalisation's
nationalisations
nationalise
nationalised
nationalises
nationalising
nationalism
nationalism's
nationalist
nationalist's
nationalistic
nationalists
nationalities
nationality
nationality's
nationally
nationals
nations
nationwide
native
natives
nativities
nativity
nativity's
nattier
nattiest
natty
natural
naturalisation
naturalisation's
naturalise
naturalised
naturalises
naturalising
naturalist
naturalist's
naturalists
naturally
naturalness
naturals
nature
nature's
natured
natures
naturing
naughtier
naughties
naughtiest
naughtily
naughtiness
naughtiness's
naughty
nausea
nausea's
nauseate
nauseated
nauseates
nauseating
nauseous
nautical
naval
navel
navel's
navels
navies
navigable
navigate
navigated
navigates
navigating
navigation
navigation's
navigational
navigator
navigator's
navigators
navy
navy's
nay
nay's
nays
near
nearby
neared
nearer
nearest
nearing
nearlier
nearliest
nearly
nears
nearsighted
nearsightedness
neat
neater
neatest
neatly
neatness
neatness's
nebula
nebula's
nebulae
nebulas
nebulous
necessaries
necessarily
necessary
necessitate
necessitated
necessitates
necessitating
necessities
necessity
necessity's
neck
neck's
necked
neckerchief
neckerchief's
neckerchiefs
neckerchieves
necking
necklace
necklace's
necklaces
neckline
neckline's
necklines
necks
necktie
necktie's
neckties
necrophilia
necrophilia's
nectar
nectar's
nectarine
nectarine's
nectarines
need
needed
needier
neediest
needing
needle
needle's
needled
needles
needless
needlessly
needlework
needlework's
needling
needs
needy
negate
negated
negates
negating
negation
negation's
negations
negative
negatived
negatively
negatives
negativing
neglect
neglected
neglectful
neglecting
neglects
negligee
negligee's
negligees
negligence
negligence's
negligent
negligently
negligible
negotiable
negotiate
negotiated
negotiates
negotiating
negotiation
negotiation's
negotiations
negotiator
negotiator's
negotiators
negs
neigh
neigh's
neighbour
neighbour's
neighboured
neighbourhood
neighbourhood's
neighbourhoods
neighbouring
neighbourliness
neighbourliness's
neighbourly
neighbours
neighed
neighing
neighs
neither
neon
neon's
neophyte
neophyte's
neophytes
nephew
nephew's
nephews
nepotism
nepotism's
nerd
nerdier
nerdiest
nerds
nerdy
nerve
nerve's
nerved
nerves
nerving
nervous
nervously
nervousness
nervousness's
nest
nest's
nested
nesting
nestle
nestled
nestles
nestling
nests
net
net's
nether
nets
netted
netting
netting's
nettle
nettle's
nettled
nettles
nettling
network
network's
networked
networking
networks
neural
neurological
neurologist
neurologist's
neurologists
neurology
neurology's
neuron
neuron's
neurons
neuroses
neurosis
neurosis's
neurotic
neurotics
neuter
neutered
neutering
neuters
neutral
neutralisation
neutralisation's
neutralise
neutralised
neutralises
neutralising
neutrality
neutrality's
neutrals
neutron
neutron's
neutrons
never
nevertheless
new
newbie
newbies
newborn
newborns
newcomer
newcomer's
newcomers
newed
newer
newest
newfangled
newing
newly
newlywed
newlywed's
newlyweds
newness
newness's
news
news's
newsagents
newscast
newscast's
newscaster
newscaster's
newscasters
newscasting
newscasts
newsed
newses
newsier
newsiest
newsing
newsletter
newsletter's
newsletters
newspaper
newspaper's
newspapered
newspapering
newspapers
newsprint
newsprint's
newsstand
newsstand's
newsstands
newsworthier
newsworthiest
newsworthy
newsy
newt
newt's
newton
newton's
newts
next
nibble
nibbled
nibbles
nibbling
nice
nicely
nicer
nicest
niceties
nicety
niche
niche's
niches
nick
nick's
nicked
nickel
nickel's
nickels
nicking
nickname
nickname's
nicknamed
nicknames
nicknaming
nicks
nicotine
nicotine's
niece
niece's
nieces
niftier
niftiest
nifty
nigger
nigger's
niggers
niggle
niggled
niggles
niggling
nigglings
nigh
night
night's
nightclub
nightclub's
nightclubbed
nightclubbing
nightclubs
nightfall
nightfall's
nightgown
nightgown's
nightgowns
nightie
nightie's
nighties
nightingale
nightingale's
nightingales
nightlife
nightlife's
nightly
nightmare
nightmare's
nightmares
nightmarish
nights
nighttime
nighty
nil
nil's
nilled
nilling
nils
nimble
nimbler
nimblest
nimbly
nincompoop
nincompoop's
nincompoops
nine
nine's
nines
nineteen
nineteen's
nineteens
nineteenth
nineteenths
nineties
ninetieth
ninetieths
ninety
ninety's
ninnies
ninny
ninny's
ninth
ninths
nip
nipped
nippier
nippiest
nipping
nipple
nipple's
nippled
nipples
nippling
nippy
nips
nit
nit's
nitrate
nitrate's
nitrated
nitrates
nitrating
nitrogen
nitrogen's
nits
nitwit
nitwit's
nitwits
no
nobility
nobility's
noble
nobleman
nobleman's
noblemen
nobler
nobles
noblest
noblewoman
noblewomen
nobly
nobodies
nobody
nocturnal
nod
nodded
nodding
node
node's
nodes
nods
noes
noise
noise's
noised
noiseless
noiselessly
noises
noisier
noisiest
noisily
noisiness
noisiness's
noising
noisy
nomad
nomad's
nomadic
nomads
nomenclature
nomenclature's
nomenclatures
nominal
nominally
nominate
nominated
nominates
nominating
nomination
nomination's
nominations
nominative
nominatives
nominee
nominee's
nominees
non
nonchalance
nonchalance's
nonchalant
nonchalantly
noncommittal
noncommittally
nonconformist
nonconformist's
nonconformists
nondairy
nondenominational
nondescript
none
nonentities
nonentity
nonentity's
nones
nonetheless
nonevent
nonevent's
nonevents
nonexistent
nonfat
nonfiction
nonfiction's
nonflammable
nonintervention
nonintervention's
nonpartisan
nonpartisans
nonplus
nonplused
nonpluses
nonplusing
nonplussed
nonplusses
nonplussing
nonprofit
nonprofits
nonproliferation
nonproliferation's
nonrefundable
nonrenewable
nonresident
nonresident's
nonresidents
nonsense
nonsense's
nonsensical
nonsmoker
nonsmoker's
nonsmokers
nonsmoking
nonstandard
nonstick
nonstop
nontrivial
nonverbal
nonviolence
nonviolence's
nonviolent
noodle
noodle's
noodled
noodles
noodling
nook
nook's
nooks
noon
noon's
nooned
nooning
noons
noose
noose's
nooses
nope
nopes
nor
norm
norm's
normal
normalcy
normalcy's
normalisation
normalise
normalised
normalises
normalising
normality
normality's
normally
normed
norming
norms
north
north's
northbound
northeast
northeast's
northeasterly
northeastern
northeastward
northerlies
northerly
northern
northerner
northerners
northernmost
northward
northwest
northwest's
northwesterly
northwestern
northwestward
nose
nose's
nosebleed
nosebleed's
nosebleeds
nosed
nosedive
nosedived
nosedives
nosediving
nosedove
noses
nosey
nosey's
noseyer
noseyest
noseys
nosing
nostalgia
nostalgia's
nostalgic
nostalgically
nostalgics
nostril
nostril's
nostrils
not
notable
notables
notably
notation
notation's
notations
notch
notch's
notched
notches
notching
note
note's
notebook
notebook's
notebooks
noted
notes
noteworthy
nothing
nothingness
nothingness's
nothings
notice
notice's
noticeable
noticeably
noticeboard
noticeboards
noticed
notices
noticing
notification
notification's
notifications
notified
notifies
notify
notifying
noting
notion
notion's
notional
notions
notoriety
notorious
notoriously
notwithstanding
nougat
nougat's
nougats
nought
nought's
noughts
noun
noun's
nouns
nourish
nourished
nourishes
nourishing
nourishment
nourishment's
nova
nova's
novel
novel's
novelist
novelist's
novelists
novels
novelties
novelty
novelty's
novice
novice's
novices
now
nowadays
nowhere
noxious
nozzle
nozzle's
nozzles
nuance
nuance's
nuances
nuclear
nuclei
nuclei's
nucleus
nucleus's
nucleuses
nude
nuder
nudes
nudest
nudge
nudged
nudges
nudging
nudist
nudist's
nudists
nudity
nudity's
nugget
nugget's
nuggets
nuisance
nuisance's
nuisances
nuke
nuke's
nuked
nukes
nuking
null
nullified
nullifies
nullify
nullifying
nulls
numb
numbed
number
number's
numbered
numbering
numbers
numbest
numbing
numbness
numbness's
numbs
numeral
numeral's
numerals
numerate
numerator
numerator's
numerators
numeric
numerical
numerically
numerous
nun
nun's
nuns
nuptial
nuptials
nurse
nurse's
nursed
nursemaid
nursemaid's
nursemaids
nurseries
nursery
nursery's
nurses
nursing
nurture
nurture's
nurtured
nurtures
nurturing
nut
nut's
nutcracker
nutcracker's
nutcrackers
nutmeg
nutmeg's
nutmegged
nutmegging
nutmegs
nutrient
nutrient's
nutrients
nutriment
nutriment's
nutriments
nutrition
nutrition's
nutritional
nutritious
nuts
nutshell
nutshell's
nutshells
nutted
nuttier
nuttiest
nutting
nutty
nuzzle
nuzzled
nuzzles
nuzzling
nylon
nylon's
nylons
nymph
nymph's
nymphomania
nymphomania's
nymphomaniac
nymphomaniacs
nymphs
ne
o
o'clock
oaf
oaf's
oafs
oak
oak's
oaks
oar
oar's
oared
oaring
oars
oases
oasis
oasis's
oat
oat's
oath
oath's
oaths
oatmeal
oatmeal's
oats
obedience
obedience's
obedient
obediently
obelisk
obelisk's
obelisks
obese
obesity
obesity's
obey
obeyed
obeying
obeys
obfuscation
obfuscation's
obituaries
obituary
obituary's
object
object's
objected
objecting
objection
objection's
objectionable
objections
objective
objectively
objectives
objectivity
objectivity's
objector
objector's
objectors
objects
obligate
obligated
obligates
obligating
obligation
obligation's
obligations
obligatory
oblige
obliged
obliges
obliging
obligingly
oblique
obliques
obliterate
obliterated
obliterates
obliterating
obliteration
obliteration's
oblivion
oblivion's
oblivious
oblong
oblongs
obnoxious
obnoxiously
oboe
oboe's
oboes
obscene
obscener
obscenest
obscenities
obscenity
obscenity's
obscure
obscured
obscurer
obscures
obscurest
obscuring
obscurities
obscurity
obscurity's
observable
observance
observance's
observances
observant
observation
observation's
observations
observatories
observatory
observatory's
observe
observed
observer
observer's
observers
observes
observing
obsess
obsessed
obsesses
obsessing
obsession
obsession's
obsessions
obsessive
obsessively
obsessives
obsolescence
obsolescent
obsolete
obsoleted
obsoletes
obsoleting
obstacle
obstacle's
obstacles
obstetrician
obstetrician's
obstetricians
obstetrics
obstetrics's
obstinacy
obstinacy's
obstinate
obstinately
obstruct
obstructed
obstructing
obstruction
obstruction's
obstructions
obstructive
obstructives
obstructs
obtain
obtainable
obtained
obtaining
obtains
obtrusive
obtuse
obtuser
obtusest
obvious
obviously
occasion
occasion's
occasional
occasionally
occasioned
occasioning
occasions
occult
occupancy
occupancy's
occupant
occupant's
occupants
occupation
occupation's
occupational
occupations
occupied
occupies
occupy
occupying
occur
occurred
occurrence
occurrence's
occurrences
occurring
occurs
ocean
ocean's
oceanic
oceanography
oceanography's
oceans
octagon
octagon's
octagonal
octagons
octal
octave
octave's
octaves
octopi
octopus
octopus's
octopuses
ocular
oculars
odd
odder
oddest
oddities
oddity
oddity's
oddly
oddness
oddness's
odds
ode
ode's
odes
odious
odometer
odometer's
odometers
odour
odour's
odours
odyssey
odysseys
oesophagus
oesophagus's
oesophaguses
oestrogen
oestrogen's
of
off
offbeat
offbeat's
offbeats
offed
offence
offence's
offences
offencive
offend
offended
offender
offender's
offenders
offending
offends
offensively
offensiveness
offensiveness's
offensives
offer
offered
offering
offering's
offerings
offers
offhand
office
office's
officer
officer's
officers
offices
official
officially
officials
officiate
officiated
officiates
officiating
officious
offing
offing's
offings
offload
offs
offset
offset's
offsets
offsetting
offshoot
offshoot's
offshoots
offshore
offspring
offspring's
offsprings
offstage
offstages
often
oftener
oftenest
ogle
ogled
ogles
ogling
ogre
ogre's
ogres
oh
ohm
ohm's
ohms
ohs
oil
oil's
oiled
oilfield
oilfield's
oilfields
oilier
oiliest
oiling
oils
oily
oink
oinked
oinking
oinks
ointment
ointment's
ointments
okay
okayed
okaying
okays
okra
okra's
okras
old
olden
oldened
oldening
oldens
older
oldest
oldie
oldie's
oldies
olfactory
olive
olive's
olives
ombudsman
ombudsman's
ombudsmen
omega
omega's
omelet
omelet's
omelets
omelette
omelette's
omelettes
omen
omen's
omens
ominous
ominously
omission
omission's
omissions
omit
omits
omitted
omitting
omnibus
omnibus's
omnipotence
omnipotence's
omnipotent
omnipresent
omniscience
omniscience's
omniscient
on
once
oncoming
one
onerous
ones
oneself
onetime
ongoing
ongoings
onion
onion's
onioned
onioning
onions
onliest
onlooker
onlooker's
onlookers
only
onomatopoeia
onomatopoeia's
onrush
onrush's
onrushes
onset
onset's
onsets
onsetting
onslaught
onslaught's
onslaughts
onto
onus
onus's
onuses
onward
onwards
oodles
oops
oopses
ooze
oozed
oozes
oozing
opal
opal's
opals
opaque
opaqued
opaquer
opaques
opaquest
opaquing
open
opened
opener
opener's
openers
openest
opening
opening's
openings
openly
openness
opens
opera
opera's
operable
operand
operand's
operands
operas
operate
operated
operates
operatic
operatics
operating
operation
operation's
operational
operationally
operations
operative
operatives
operator
operator's
operators
ophthalmologist
ophthalmologist's
ophthalmologists
ophthalmology
ophthalmology's
opinion
opinion's
opinionated
opinions
opium
opium's
opossum
opossum's
opossums
opponent
opponent's
opponents
opportune
opportunism
opportunism's
opportunist
opportunist's
opportunistic
opportunists
opportunities
opportunity
opportunity's
oppose
opposed
opposes
opposing
opposite
opposites
opposition
opposition's
oppress
oppressed
oppresses
oppressing
oppression
oppression's
oppressive
oppressor
oppressor's
oppressors
opt
opted
optic
optical
optician
optician's
opticians
optics
optics's
optima
optimal
optimisation
optimisation's
optimise
optimise's
optimised
optimises
optimising
optimism
optimism's
optimist
optimist's
optimistic
optimistically
optimists
optimum
optimum's
optimums
opting
option
option's
optional
optionally
optionals
optioned
optioning
options
optometrist
optometrist's
optometrists
optometry
optometry's
opts
opulence
opulence's
opulent
opus
opus's
opuses
or
or's
oracle
oracle's
oracled
oracles
oracling
oral
orally
orals
orange
orange's
oranges
orangutan
orangutan's
orangutans
oration
oration's
orations
orator
orator's
oratories
orators
oratory
oratory's
orbit
orbit's
orbital
orbital's
orbitals
orbited
orbiting
orbits
orchard
orchard's
orchards
orchestra
orchestra's
orchestral
orchestras
orchestrate
orchestrated
orchestrates
orchestrating
orchestration
orchestration's
orchestrations
orchid
orchid's
orchids
ordain
ordained
ordaining
ordains
ordeal
ordeal's
ordeals
order
order's
ordered
ordering
orderlies
orderly
orders
ordinal
ordinals
ordinance
ordinance's
ordinances
ordinarier
ordinaries
ordinariest
ordinarily
ordinary
ordination
ordination's
ordinations
ore
ore's
ores
organ
organ's
organic
organically
organics
organisation
organisation's
organisational
organisations
organise
organised
organiser
organiser's
organisers
organises
organising
organism
organism's
organisms
organist
organist's
organists
organs
orgasm
orgasm's
orgasms
orgies
orgy
orgy's
orient
orient's
oriental
orientals
orientate
orientated
orientates
orientating
orientation
orientation's
orientations
oriented
orienting
orients
orifice
orifice's
origin
origin's
original
originality
originality's
originally
originals
originate
originated
originates
originating
originator
originator's
originators
origins
oriole
oriole's
orioles
ornament
ornament's
ornamental
ornamented
ornamenting
ornaments
ornate
ornately
ornithologist
ornithologist's
ornithologists
ornithology
ornithology's
orphan
orphan's
orphanage
orphanage's
orphanages
orphaned
orphaning
orphans
orthodontics
orthodontics's
orthodontist
orthodontist's
orthodontists
orthodox
orthodoxes
orthodoxies
orthodoxy
orthodoxy's
orthogonal
orthogonality
orthogonality's
orthography
orthography's
orthopaedics
orthopaedics's
oscillate
oscillated
oscillates
oscillating
oscillation
oscillations
oscilloscope
oscilloscope's
osmosis
osmosis's
ostensible
ostensibly
ostentation
ostentation's
ostentatious
ostentatiously
ostracise
ostracised
ostracises
ostracising
ostracism
ostracism's
ostrich
ostrich's
ostriches
other
others
otherwise
otter
otter's
ottered
ottering
otters
ouch
ought
ounce
ounce's
ounces
our
ours
ourselves
oust
ousted
ouster
ouster's
ousters
ousting
ousts
out
outage
outage's
outages
outback
outback's
outbacks
outbid
outbidding
outbids
outbound
outbreak
outbreak's
outbreaking
outbreaks
outbroke
outbroken
outburst
outburst's
outbursting
outbursts
outcast
outcast's
outcasting
outcasts
outclass
outclassed
outclasses
outclassing
outcome
outcome's
outcomes
outcries
outcrop
outcropped
outcropping
outcroppings
outcrops
outcry
outcry's
outdated
outdid
outdistance
outdistanced
outdistances
outdistancing
outdo
outdoes
outdoing
outdone
outdoor
outdoors
outed
outer
outermost
outers
outfield
outfield's
outfielder
outfielder's
outfielders
outfields
outfit
outfit's
outfits
outfitted
outfitting
outgoing
outgoings
outgrew
outgrow
outgrowing
outgrown
outgrows
outgrowth
outgrowth's
outgrowths
outhouse
outhouse's
outhouses
outing
outing's
outings
outlaid
outlandish
outlast
outlasted
outlasting
outlasts
outlaw
outlaw's
outlawed
outlawing
outlaws
outlay
outlay's
outlaying
outlays
outlet
outlet's
outlets
outline
outline's
outlined
outlines
outlining
outlive
outlived
outlives
outliving
outlook
outlook's
outlooked
outlooking
outlooks
outlying
outmanoeuvre
outmanoeuvred
outmanoeuvres
outmanoeuvring
outmoded
outnumber
outnumbered
outnumbering
outnumbers
outpatient
outpatient's
outpatients
outperform
outperformed
outperforming
outperforms
outplacement
outpost
outpost's
outposts
outpouring
outpouring's
outpourings
output
output's
outputs
outputted
outputting
outrage
outrage's
outraged
outrageous
outrageously
outrages
outraging
outran
outreach
outreached
outreaches
outreaching
outright
outrun
outrunning
outruns
outs
outset
outset's
outsets
outsetting
outshine
outshined
outshines
outshining
outshone
outside
outsider
outsider's
outsiders
outsides
outskirt
outskirts
outsmart
outsmarted
outsmarting
outsmarts
outsource
outsourced
outsources
outsourcing
outspoken
outspokenness
outspokenness's
outstanding
outstandingly
outstation
outstation's
outstations
outstretch
outstretched
outstretches
outstretching
outstrip
outstripped
outstripping
outstrips
outstript
outward
outwardly
outwards
outweigh
outweighed
outweighing
outweighs
outwit
outwits
outwitted
outwitting
ova
ova's
oval
ovals
ovarian
ovaries
ovary
ovary's
ovation
ovation's
ovations
oven
oven's
ovens
over
overall
overalls
overate
overbear
overbearing
overbears
overblown
overboard
overbore
overborne
overburden
overburdened
overburdening
overburdens
overcame
overcast
overcasting
overcasts
overcharge
overcharged
overcharges
overcharging
overcoat
overcoat's
overcoats
overcome
overcomes
overcoming
overcompensate
overcompensated
overcompensates
overcompensating
overcompensation
overcompensation's
overcrowd
overcrowded
overcrowding
overcrowds
overdid
overdo
overdoes
overdoing
overdone
overdose
overdose's
overdosed
overdoses
overdosing
overdraft
overdraft's
overdraw
overdrawing
overdrawn
overdraws
overdrew
overdue
overeat
overeaten
overeating
overeats
overestimate
overestimated
overestimates
overestimating
overextend
overextended
overextending
overextends
overflow
overflowed
overflowing
overflows
overgrew
overgrow
overgrowing
overgrown
overgrows
overhand
overhands
overhang
overhanging
overhangs
overhaul
overhauled
overhauling
overhauls
overhead
overheads
overhear
overheard
overhearing
overhears
overheat
overheated
overheating
overheats
overhung
overjoy
overjoyed
overjoying
overjoys
overkill
overkill's
overlaid
overlain
overland
overlands
overlap
overlapped
overlapping
overlaps
overlay
overlaying
overlays
overlie
overlies
overload
overloaded
overloading
overloads
overlong
overlook
overlooked
overlooking
overlooks
overly
overlying
overnight
overnights
overpass
overpass's
overpasses
overpopulate
overpopulated
overpopulates
overpopulating
overpopulation
overpopulation's
overpower
overpowered
overpowering
overpowers
overprice
overpriced
overprices
overpricing
overprint
overprinted
overprinting
overprints
overran
overrate
overrated
overrates
overrating
overreact
overreacted
overreacting
overreacts
overridden
override
overrides
overriding
overrode
overrule
overruled
overrules
overruling
overrun
overrunning
overruns
overs
oversampling
oversaw
overseas
oversee
overseeing
overseen
overseer
overseer's
overseers
oversees
overshadow
overshadowed
overshadowing
overshadows
overshoot
overshooting
overshoots
overshot
oversight
oversight's
oversights
oversimplification
oversimplification's
oversimplifications
oversimplified
oversimplifies
oversimplify
oversimplifying
oversized
oversleep
oversleeping
oversleeps
overslept
overstate
overstated
overstates
overstating
overstep
overstepped
overstepping
oversteps
overt
overtake
overtaken
overtakes
overtaking
overthrew
overthrow
overthrowing
overthrown
overthrows
overtime
overtime's
overtimes
overtly
overtone
overtone's
overtones
overtook
overture
overture's
overtures
overturn
overturned
overturning
overturns
overuse
overused
overuses
overusing
overview
overview's
overviews
overweight
overwhelm
overwhelmed
overwhelming
overwhelmingly
overwhelms
overwork
overworked
overworking
overworks
overwrite
overwrites
overwriting
overwritten
overwrought
ovum
ovum's
ow
owe
owed
owes
owing
owl
owl's
owls
own
owned
owner
owner's
owners
ownership
ownership's
owning
owns
ox
ox's
oxen
oxen's
oxes
oxidation
oxidation's
oxide
oxide's
oxides
oxidise
oxidised
oxidises
oxidising
oxygen
oxygen's
oyster
oyster's
oysters
ozone
ozone's
p
pa
pa's
pace
pace's
paced
pacemaker
pacemaker's
pacemakers
paces
pacesetter
pacesetter's
pacesetters
pacific
pacified
pacifier
pacifier's
pacifiers
pacifies
pacifism
pacifism's
pacifist
pacifist's
pacifists
pacify
pacifying
pacing
pack
pack's
package
package's
packaged
packages
packaging
packaging's
packed
packer
packer's
packers
packet
packet's
packets
packing
packing's
packs
pact
pact's
pacts
pad
pad's
padded
paddies
padding
padding's
paddle
paddle's
paddled
paddles
paddling
paddock
paddock's
paddocked
paddocking
paddocks
paddy
paddy's
padlock
padlock's
padlocked
padlocking
padlocks
padre
padre's
padres
pads
paediatrician
pagan
pagan's
pagans
page
page's
pageant
pageant's
pageantry
pageantry's
pageants
paged
pager
pager's
pagers
pages
pagination
paging
pagoda
pagoda's
pagodas
paid
pail
pail's
pails
pain
pain's
pained
painful
painfuller
painfullest
painfully
paining
painkiller
painkiller's
painkillers
painless
painlessly
pains
painstaking
painstakingly
paint
paint's
paintbrush
paintbrush's
paintbrushes
painted
painter
painter's
painters
painting
painting's
paintings
paints
pair
pair's
paired
pairing
pairs
pal
pal's
palace
palace's
palaces
palatable
palate
palate's
palates
palatial
pale
paled
paleontologist
paleontologists
paleontology
paleontology's
paler
pales
palest
palette
palette's
palettes
paling
pall
pall's
pallbearer
pallbearer's
pallbearers
palled
pallid
palling
pallor
pallor's
palls
palm
palm's
palmed
palming
palms
palomino
palomino's
palominos
palpable
palpably
pals
paltrier
paltriest
paltry
pamper
pampered
pampering
pampers
pamphlet
pamphlet's
pamphlets
pan
panacea
panacea's
panaceas
panache
panache's
pancake
pancake's
pancaked
pancakes
pancaking
pancreas
pancreas's
pancreases
pancreatic
panda
panda's
pandas
pandemonium
pandemonium's
pander
pandered
pandering
panders
pane
pane's
panel
panel's
panelist
panelist's
panelists
panelled
panelling
panelling's
panellings
panels
panes
pang
pang's
panged
panging
pangs
panhandle
panhandle's
panhandled
panhandler
panhandlers
panhandles
panhandling
panic
panic's
panicked
panickier
panickiest
panicking
panicky
panics
panned
panning
panorama
panorama's
panoramas
panoramic
pans
pansies
pansy
pansy's
pant
panted
pantheism
pantheism's
panther
panther's
panthers
pantie
panties
panting
pantomime
pantomime's
pantomimed
pantomimes
pantomiming
pantries
pantry
pantry's
pants
panty
pantyhose
pap
pap's
papa
papa's
papacies
papacy
papacy's
papal
papas
papaya
papaya's
papayas
paper
paper's
paperback
paperback's
paperbacked
paperbacking
paperbacks
paperboy
paperboy's
paperboys
papered
papergirl
papergirl's
papergirls
papering
papers
paperweight
paperweight's
paperweights
paperwork
paperwork's
paprika
paprika's
papyri
papyrus
papyrus's
papyruses
par
par's
parable
parable's
parabled
parables
parabling
parachute
parachute's
parachuted
parachutes
parachuting
parade
parade's
paraded
parades
paradigm
paradigm's
paradigms
parading
paradise
paradise's
paradises
paradox
paradox's
paradoxes
paradoxical
paradoxically
paraffin
paraffin's
paragon
paragon's
paragons
paragraph
paragraph's
paragraphed
paragraphing
paragraphs
parakeet
parakeet's
parakeets
paralegal
paralegals
parallel
parallelled
parallelling
parallels
paralyse
paralysed
paralyses
paralysing
paralysis
paralysis's
paralytic
paralytics
paramedic
paramedic's
paramedics
parameter
parameter's
parameters
paramilitaries
paramilitary
paramount
paranoia
paranoia's
paranoid
paranoids
paraphernalia
paraphrase
paraphrase's
paraphrased
paraphrases
paraphrasing
paraplegic
paraplegics
parasite
parasite's
parasites
parasitic
parasol
parasol's
parasols
paratrooper
paratrooper's
paratroopers
parcel
parcel's
parcelled
parcelling
parcels
parch
parched
parches
parching
parchment
parchment's
parchments
pardon
pardonable
pardoned
pardoning
pardons
pare
pared
parent
parent's
parentage
parentage's
parental
parented
parentheses
parenthesis
parenthesis's
parenthesise
parenthesised
parenthesises
parenthesising
parenthetical
parenthood
parenthood's
parenting
parents
pares
paring
parish
parish's
parishes
parishioner
parishioner's
parishioners
parity
parity's
park
park's
parka
parka's
parkas
parked
parking
parking's
parks
parkway
parkway's
parkways
parliament
parliament's
parliamentary
parliaments
parlour
parlour's
parlours
parochial
parodied
parodies
parody
parody's
parodying
parole
parole's
paroled
paroles
paroling
parquet
parquet's
parqueted
parqueting
parquets
parred
parring
parrot
parrot's
parroted
parroting
parrots
pars
parse
parsec
parsecs
parsed
parser
parser's
parses
parsing
parsley
parsley's
parsnip
parsnip's
parsnips
parson
parson's
parsonage
parsonage's
parsonages
parsons
part
part's
partake
partaken
partakes
partaking
parted
partial
partiality
partiality's
partially
partials
participant
participant's
participants
participate
participated
participates
participating
participation
participation's
participle
participle's
participles
particle
particle's
particles
particular
particularly
particulars
partied
parties
parting
parting's
partings
partisan
partisan's
partisans
partition
partition's
partitioned
partitioning
partitions
partly
partner
partner's
partnered
partnering
partners
partnership
partnership's
partnerships
partook
partridge
partridge's
partridges
parts
partway
party
party's
partying
pas
pass
passable
passage
passage's
passages
passageway
passageway's
passageways
passbook
passbook's
passbooks
passed
passenger
passenger's
passengers
passer
passerby
passersby
passes
passing
passion
passion's
passionate
passionated
passionately
passionates
passionating
passioned
passioning
passions
passive
passively
passives
passport
passport's
passports
password
password's
passwords
pass
pass's
past
pasta
pasta's
pastas
paste
paste's
pasted
pastel
pastel's
pastels
pastes
pasteurisation
pasteurisation's
pasteurise
pasteurised
pasteurises
pasteurising
pastiche
pastiche's
pastier
pasties
pastiest
pastime
pastime's
pastimes
pasting
pastor
pastor's
pastoral
pastorals
pastors
pastries
pastry
pastry's
pasts
pasture
pasture's
pastured
pastures
pasturing
pasty
pat
patch
patch's
patched
patches
patchier
patchiest
patching
patchwork
patchwork's
patchworks
patchy
pate
pate's
patent
patent's
patented
patenting
patently
patents
paternal
paternalism
paternalism's
paternalistic
paternity
paternity's
pates
path
path's
pathetic
pathetically
pathological
pathologically
pathologist
pathologists
pathology
pathology's
pathos
pathos's
paths
pathway
pathway's
pathways
patience
patience's
patient
patienter
patientest
patiently
patients
patio
patio's
patios
patriarch
patriarch's
patriarchal
patriarchies
patriarchs
patriarchy
patriarchy's
patricide
patricide's
patricides
patrimonies
patrimony
patrimony's
patriot
patriot's
patriotic
patriotically
patriotism
patriotism's
patriots
patrol
patrol's
patrolled
patrolling
patrolman
patrolman's
patrolmen
patrols
patrolwoman
patrolwomen
patron
patron's
patronage
patronage's
patronages
patronise
patronised
patronises
patronising
patronisingly
patrons
pats
patted
patter
pattered
pattering
pattern
pattern's
patterned
patterning
patterns
patters
patties
patting
patty
patty's
paucity
paucity's
paunch
paunch's
paunched
paunches
paunchier
paunchiest
paunching
paunchy
pauper
pauper's
paupers
pause
paused
pauses
pausing
pave
paved
pavement
pavement's
pavemented
pavementing
pavements
paves
pavilion
pavilion's
pavilions
paving
paving's
paw
paw's
pawed
pawing
pawn
pawnbroker
pawnbroker's
pawnbrokers
pawned
pawning
pawns
paws
pay
payable
paycheck
paycheck's
paychecks
payday
payday's
paydays
payed
payee
payee's
payees
payer
payers
paying
payload
payload's
payloads
payment
payment's
payments
payoff
payoff's
payoffs
payroll
payroll's
payrolls
pays
pea
pea's
peace
peace's
peaceable
peaceably
peaceful
peacefuller
peacefullest
peacefully
peacefulness
peacekeeping
peacemaker
peacemaker's
peacemakers
peaces
peacetime
peacetime's
peach
peach's
peaches
peacock
peacock's
peacocks
peak
peak's
peaked
peaking
peaks
peal
peal's
pealed
pealing
peals
peanut
peanut's
peanuts
pear
pear's
pearl
pearl's
pearled
pearling
pearls
pears
peas
peasant
peasant's
peasants
pease
peat
peat's
pebble
pebble's
pebbled
pebbles
pebbling
pecan
pecan's
pecans
peck
peck's
pecked
pecking
pecks
peculiar
peculiarities
peculiarity
peculiarity's
peculiarly
pedagogical
pedagogy
pedagogy's
pedal
pedal's
pedalled
pedalling
pedals
pedant
pedant's
pedantic
pedantically
pedantry
pedantry's
pedants
peddle
peddled
peddler
peddler's
peddlers
peddles
peddling
pedestal
pedestal's
pedestals
pedestrian
pedestrian's
pedestrians
pediatrician's
pediatricians
pediatrics
pedigree
pedigree's
pedigreed
pedigrees
pee
peed
peeing
peek
peekaboo
peekaboo's
peeked
peeking
peeks
peel
peeled
peeling
peeling's
peels
peep
peeped
peephole
peephole's
peepholes
peeping
peeps
peer
peer's
peered
peering
peerless
peers
pees
peeve
peeved
peeves
peeving
peevish
peg
peg's
pegged
pegging
pegs
pejorative
pejoratives
pelican
pelican's
pelicans
pellet
pellet's
pelleted
pelleting
pellets
pelt
pelted
pelting
pelts
pelves
pelvic
pelvics
pelvis
pelvis's
pelvises
pen
pen's
penal
penalise
penalised
penalises
penalising
penalties
penalty
penalty's
penance
penance's
penanced
penances
penancing
pence
pence's
penchant
penchant's
penchants
pencil
pencil's
pencilled
pencilling
pencillings
pencils
pendant
pendant's
pendants
pended
pending
pends
pendulum
pendulum's
pendulums
penes
penetrate
penetrated
penetrates
penetrating
penetration
penetration's
penetrations
penguin
penguin's
penguins
penicillin
penicillin's
peninsula
peninsula's
peninsulas
penis
penis's
penises
penitence
penitence's
penitent
penitentiaries
penitentiary
penitentiary's
penitents
penknife
penknife's
penknives
penmanship
penmanship's
pennant
pennant's
pennants
penned
pennies
penniless
penning
penny
penny's
pens
pension
pension's
pensioned
pensioner
pensioners
pensioning
pensions
pensive
pensively
pentagon
pentagon's
pentagonal
pentagonals
pentagons
penthouse
penthouse's
penthoused
penthouses
penthousing
penultimate
peon
peon's
peonies
peons
peony
peony's
people
people's
peopled
peoples
peopling
pep
pep's
pepped
pepper
pepper's
peppered
peppering
peppermint
peppermint's
peppermints
pepperoni
pepperonis
peppers
peppier
peppiest
pepping
peppy
peps
per
perceive
perceived
perceives
perceiving
percent
percent's
percentage
percentage's
percentages
percentile
percentile's
percentiles
percents
perceptible
perceptibly
perception
perception's
perceptions
perceptive
perceptively
perch
perch's
perchance
perched
perches
perching
percolate
percolated
percolates
percolating
percolation
percolation's
percolator
percolator's
percolators
percussion
percussion's
peremptory
perennial
perennials
perfect
perfected
perfecter
perfectest
perfecting
perfection
perfection's
perfectionist
perfectionist's
perfectionists
perfections
perfectly
perfects
perforate
perforated
perforates
perforating
perforation
perforations
perform
performance
performance's
performances
performed
performer
performer's
performers
performing
performs
perfume
perfume's
perfumed
perfumes
perfuming
perfunctorily
perfunctory
perhaps
perhapses
peril
peril's
perilled
perilling
perilous
perilously
perils
perimeter
perimeter's
perimeters
period
period's
periodic
periodical
periodical's
periodically
periodicals
periods
peripheral
peripherals
peripheries
periphery
periphery's
periscope
periscope's
periscoped
periscopes
periscoping
perish
perishable
perishables
perished
perishes
perishing
perjure
perjured
perjures
perjuries
perjuring
perjury
perjury's
perk
perked
perkier
perkiest
perking
perks
perky
perm
perm's
permanence
permanence's
permanent
permanently
permanents
permeate
permeated
permeates
permeating
permed
perming
permissible
permission
permission's
permissions
permissive
permit
permits
permitted
permitting
perms
permutation
permutation's
permutations
pernicious
peroxide
peroxide's
peroxided
peroxides
peroxiding
perpendicular
perpendiculars
perpetrate
perpetrated
perpetrates
perpetrating
perpetrator
perpetrator's
perpetrators
perpetual
perpetually
perpetuals
perpetuate
perpetuated
perpetuates
perpetuating
perplex
perplexed
perplexes
perplexing
perplexities
perplexity
perplexity's
perquisite
perquisite's
perquisites
persecute
persecuted
persecutes
persecuting
persecution
persecution's
persecutions
persecutor
persecutor's
persecutors
perseverance
perseverance's
persevere
persevered
perseveres
persevering
persist
persisted
persistence
persistence's
persistent
persistently
persisting
persists
person
person's
persona
persona's
personable
personae
personal
personalise
personalised
personalises
personalising
personalities
personality
personality's
personally
personals
personification
personification's
personifications
personified
personifies
personify
personifying
personnel
personnel's
persons
perspective
perspective's
perspectives
perspiration
perspiration's
perspire
perspired
perspires
perspiring
persuade
persuaded
persuades
persuading
persuasion
persuasion's
persuasions
persuasive
persuasively
persuasiveness
persuasiveness's
pert
pertain
pertained
pertaining
pertains
perter
pertest
pertinent
pertinents
perts
perturb
perturbed
perturbing
perturbs
perusal
perusal's
perusals
peruse
perused
peruses
perusing
pervade
pervaded
pervades
pervading
pervasive
perverse
perversely
perversion
perversion's
perversions
perversity
perversity's
pervert
perverted
perverting
perverts
peskier
peskiest
pesky
pessimism
pessimism's
pessimist
pessimist's
pessimistic
pessimistically
pessimists
pest
pest's
pester
pestered
pestering
pesters
pesticide
pesticide's
pesticides
pestilence
pestilence's
pestilences
pests
pet
pet's
petal
petal's
petals
peter
petered
petering
peters
petite
petites
petition
petition's
petitioned
petitioning
petitions
petrified
petrifies
petrify
petrifying
petrol
petrol's
petroleum
petroleum's
pets
petted
petticoat
petticoat's
petticoats
pettier
petties
pettiest
pettiness
petting
petty
petulant
petunia
petunia's
petunias
pew
pew's
pews
pewter
pewter's
pewters
phalli
phallic
phallus
phallus's
phalluses
phantom
phantom's
phantoms
pharmaceutical
pharmaceuticals
pharmacies
pharmacist
pharmacist's
pharmacists
pharmacologist
pharmacologist's
pharmacologists
pharmacology
pharmacology's
pharmacy
pharmacy's
phase
phase's
phased
phases
phasing
pheasant
pheasant's
pheasants
phenomena
phenomena's
phenomenal
phenomenally
phenomenas
phenomenon
phenomenon's
phenomenons
philanthropic
philanthropies
philanthropist
philanthropist's
philanthropists
philanthropy
philanthropy's
philistine
philistines
philosopher
philosopher's
philosophers
philosophical
philosophically
philosophies
philosophise
philosophised
philosophises
philosophising
philosophy
philosophy's
phlegm
phlegm's
phlegmatic
phobia
phobia's
phobias
phobic
phobics
phoenix
phoenix's
phoenixes
phone
phone's
phoned
phones
phonetic
phonetically
phonetics
phonetics's
phoney
phonics
phonics's
phonied
phonier
phonies
phoniest
phoning
phonograph
phonograph's
phonographs
phony
phonying
phooey
phooeys
phosphate
phosphate's
phosphates
phosphor
phosphor's
phosphorescence
phosphorescence's
phosphorescent
phosphorus
phosphorus's
photo
photo's
photocopied
photocopier
photocopier's
photocopiers
photocopies
photocopy
photocopy's
photocopying
photoed
photogenic
photograph
photograph's
photographed
photographer
photographer's
photographers
photographic
photographing
photographs
photography
photography's
photoing
photon
photons
photos
photosynthesis
photosynthesis's
photosynthesise
photosynthesised
photosynthesises
photosynthesising
phototypesetter
phrase
phrase's
phrased
phraseology
phraseology's
phrases
phrasing
phrasing's
phrasings
physic
physical
physically
physicals
physician
physician's
physicians
physicist
physicist's
physicists
physics
physiological
physiology
physiology's
physiotherapy
physiotherapy's
physique
physique's
physiques
pi
pianist
pianist's
pianists
piano
piano's
pianos
piccolo
piccolo's
piccolos
pick
pickax
pickax's
pickaxe
pickaxed
pickaxes
pickaxing
picked
picker
picker's
pickers
picket
picket's
picketed
picketing
pickets
pickier
pickiest
picking
pickle
pickle's
pickled
pickles
pickling
pickpocket
pickpocket's
pickpockets
picks
pickup
pickups
picky
picnic
picnic's
picnicked
picnicking
picnics
pictorial
pictorials
picture
picture's
pictured
pictures
picturesque
picturing
piddle
piddled
piddles
piddling
pidgin
pidgin's
pidgins
pie
pie's
piece
piece's
pieced
piecemeal
pieces
piecework
piecework's
piecing
pier
pier's
pierce
pierced
pierces
piercing
piercings
piers
pies
piety
piety's
pig
pig's
pigeon
pigeon's
pigeoned
pigeonhole
pigeonhole's
pigeonholed
pigeonholes
pigeonholing
pigeoning
pigeons
pigged
piggier
piggies
piggiest
pigging
piggish
piggy
piggy's
piggyback
piggyback's
piggybacked
piggybacking
piggybacks
pigheaded
piglet
piglet's
piglets
pigment
pigment's
pigmentation
pigmentation's
pigments
pigpen
pigpen's
pigpens
pigs
pigsties
pigsty
pigsty's
pigtail
pigtail's
pigtails
pike
pike's
piked
pikes
piking
pile
pile's
piled
piles
pileup
pileup's
pileups
pilfer
pilfered
pilfering
pilfers
pilgrim
pilgrim's
pilgrimage
pilgrimage's
pilgrimages
pilgrims
piling
piling's
pilings
pill
pill's
pillage
pillaged
pillages
pillaging
pillar
pillar's
pillars
pillow
pillow's
pillowcase
pillowcase's
pillowcases
pillowed
pillowing
pillows
pills
pilot
pilot's
piloted
piloting
pilots
pimp
pimp's
pimped
pimping
pimple
pimple's
pimples
pimplier
pimpliest
pimply
pimply's
pimps
pin
pin's
pincer
pincers
pinch
pinched
pinches
pinching
pincushion
pincushion's
pincushions
pine
pine's
pineapple
pineapple's
pineapples
pined
pines
ping
ping's
pinged
pinging
pings
pining
pinion
pinion's
pinioned
pinioning
pinions
pink
pink's
pinked
pinker
pinkest
pinkie
pinkie's
pinkies
pinking
pinks
pinky
pinnacle
pinnacle's
pinnacles
pinned
pinning
pinpoint
pinpointed
pinpointing
pinpoints
pinprick
pinprick's
pinpricked
pinpricking
pinpricks
pins
pinstripe
pinstripe's
pinstripes
pint
pint's
pints
pinup
pinup's
pinups
pioneer
pioneer's
pioneered
pioneering
pioneers
pious
piously
pipe
pipe's
piped
pipeline
pipeline's
pipelines
pipes
piping
piping's
pipsqueak
pipsqueak's
pipsqueaks
piquancy
piquancy's
piquant
pique
pique's
piqued
piques
piquing
piracy
piracy's
piranha
piranha's
piranhas
pirate
pirate's
pirated
pirates
pirating
pirouette
pirouette's
pirouetted
pirouettes
pirouetting
pis
piss
pissed
pisses
pissing
pistachio
pistachio's
pistachios
pistol
pistol's
pistols
piston
piston's
pistons
pit
pit's
pitch
pitched
pitcher
pitcher's
pitchers
pitches
pitchfork
pitchfork's
pitchforked
pitchforking
pitchforks
pitching
piteous
piteously
pitfall
pitfall's
pitfalls
pithier
pithiest
pithy
pitied
pities
pitiful
pitifuller
pitifullest
pitifully
pitiless
pits
pittance
pittance's
pittances
pitted
pitting
pity
pity's
pitying
pivot
pivot's
pivotal
pivoted
pivoting
pivots
pixel
pixel's
pixels
pixie
pixie's
pixies
pixy
pizza
pizza's
pizzas
pizzazz
pj's
placard
placard's
placarded
placarding
placards
placate
placated
placates
placating
place
place's
placebo
placebo's
placeboes
placebos
placed
placement
placement's
placenta
placenta's
placentae
placentas
places
placid
placidly
placing
plagiarise
plagiarised
plagiarises
plagiarising
plagiarism
plagiarism's
plagiarisms
plagiarist
plagiarist's
plagiarists
plague
plague's
plagued
plagues
plaguing
plaice
plaice's
plaid
plaid's
plaided
plaiding
plaids
plain
plainclothes
plainer
plainest
plainly
plains
plaintiff
plaintiff's
plaintiffs
plaintive
plan
plan's
planar
plane
plane's
planed
planes
planet
planet's
planetaria
planetarium
planetarium's
planetariums
planetary
planets
planing
plank
plank's
planked
planking
planks
plankton
plankton's
planned
planner
planners
planning
plannings
plans
plant
plant's
plantain
plantain's
plantains
plantation
plantation's
plantations
planted
planter
planter's
planters
planting
plantings
plants
plaque
plaque's
plaques
plasma
plasma's
plaster
plaster's
plastered
plastering
plasters
plastic
plastic's
plastics
plate
plate's
plateau
plateau's
plateaued
plateauing
plateaus
plateaux
plated
plateful
platefuls
plates
platform
platform's
platformed
platforming
platforms
plating
plating's
platinum
platinum's
platitude
platitude's
platitudes
platonic
platoon
platoon's
platooned
platooning
platoons
platter
platter's
platters
plausibility
plausible
plausibly
play
playable
playback
playback's
playboy
playboy's
playboys
played
player
player's
players
playful
playfully
playfulness
playfulness's
playground
playground's
playgrounds
playhouse
playhouse's
playhouses
playing
playmate
playmate's
playmates
playoff
playoffs
playpen
playpen's
playpens
playroom
playroom's
playrooms
plays
plaything
plaything's
playthings
playwright
playwright's
playwrights
plaza
plaza's
plazas
plea
plea's
plead
pleaded
pleading
pleading's
pleads
pleas
pleasant
pleasanter
pleasantest
pleasantly
pleasantries
pleasantry
pleasantry's
please
pleased
pleases
pleasing
pleasings
pleasurable
pleasure
pleasure's
pleasured
pleasures
pleasuring
pleat
pleat's
pleated
pleating
pleats
pled
pledge
pledge's
pledged
pledges
pledging
plenaries
plenary
plentiful
plentifully
plenty
plenty's
plethora
plethora's
pliable
pliant
plied
pliers
plies
plight
plight's
plighted
plighting
plights
plod
plodded
plodding
ploddings
plods
plop
plop's
plopped
plopping
plops
plot
plot's
plots
plotted
plotter
plotter's
plotters
plotting
plough
plough's
ploughed
ploughing
ploughs
ploy
ploy's
ploys
pluck
plucked
pluckier
pluckiest
plucking
plucks
plucky
plug
plug's
plugged
plugging
plugs
plum
plum's
plumage
plumage's
plumb
plumbed
plumber
plumber's
plumbers
plumbing
plumbing's
plumbs
plume
plume's
plumed
plumes
pluming
plummet
plummeted
plummeting
plummets
plump
plumped
plumper
plumpest
plumping
plumps
plums
plunder
plundered
plundering
plunders
plunge
plunged
plunger
plunger's
plungers
plunges
plunging
plunk
plunked
plunking
plunks
plural
pluralities
plurality
plurality's
plurals
plus
pluses
plush
plush's
plusher
plushest
plussed
plusses
plussing
plutocracies
plutocracy
plutocracy's
plutonium
plutonium's
ply
plying
plywood
plywood's
pneumatic
pneumonia
pneumonia's
poach
poached
poacher
poacher's
poachers
poaches
poaching
pocket
pocket's
pocketbook
pocketbook's
pocketbooks
pocketed
pocketful
pocketful's
pocketfuls
pocketing
pocketknife
pocketknife's
pocketknives
pockets
pockmark
pockmark's
pockmarked
pockmarking
pockmarks
pod
pod's
podded
podding
podia
podiatrist
podiatrist's
podiatrists
podiatry
podiatry's
podium
podium's
podiums
pods
poem
poem's
poems
poet
poet's
poetic
poetical
poetically
poetry
poetry's
poets
pogrom
pogrom's
pogromed
pogroming
pogroms
poignancy
poignancy's
poignant
poignantly
poinsettia
poinsettia's
poinsettias
point
point's
pointed
pointedly
pointer
pointer's
pointers
pointier
pointiest
pointing
pointing's
pointless
pointlessly
pointlessness
pointlessness's
points
pointy
poise
poise's
poised
poises
poising
poison
poison's
poisoned
poisoning
poisoning's
poisonings
poisonous
poisons
poke
poked
poker
poker's
pokers
pokes
pokey
pokier
pokiest
poking
poky
polar
polarisation
polarisation's
polarise
polarised
polarises
polarising
polarities
polarity
polarity's
polars
pole
pole's
poled
polemic
polemical
polemics
poles
police
police's
policed
policeman
policeman's
policemen
polices
policewoman
policewoman's
policewomen
policies
policing
policy
policy's
poling
polio
polio's
polios
polish
polished
polishes
polishing
polite
politely
politeness
politeness's
politer
politest
political
politically
politician
politician's
politicians
politicise
politicised
politicises
politicising
politics
politics's
polka
polka's
polkaed
polkaing
polkas
poll
poll's
polled
pollen
pollen's
pollinate
pollinated
pollinates
pollinating
pollination
pollination's
polling
polls
pollster
pollster's
pollsters
pollutant
pollutant's
pollutants
pollute
polluted
pollutes
polluting
pollution
pollution's
polo
polo's
polyester
polyester's
polyesters
polygamist
polygamist's
polygamists
polygamous
polygamy
polygamy's
polygon
polygon's
polygons
polygraph
polygraph's
polygraphed
polygraphing
polygraphs
polymer
polymer's
polymers
polynomial
polynomials
polyp
polyp's
polyps
polytechnic
polytechnic's
polytechnics
pomegranate
pomegranate's
pomegranates
pomp
pomp's
pompom
pompom's
pompoms
pomposity
pomposity's
pompous
poncho
poncho's
ponchos
pond
pond's
ponder
pondered
pondering
ponderous
ponders
ponds
ponies
pontiff
pontiff's
pontiffs
pontifical
pontoon
pontoon's
pontooned
pontooning
pontoons
pony
pony's
ponytail
ponytail's
ponytails
pooch
pooch's
pooched
pooches
pooching
poodle
poodle's
poodles
pool
pool's
pooled
pooling
pools
poop
poop's
pooped
pooping
poops
poor
poorer
poorest
poorly
pop
popcorn
popcorn's
pope
pope's
poplar
poplar's
poplars
popped
poppies
popping
poppy
poppy's
pops
populace
populace's
populaces
popular
popularise
popularised
popularises
popularising
popularity
popularity's
popularly
populars
populate
populated
populates
populating
population
population's
populations
populous
porcelain
porcelain's
porch
porch's
porches
porcupine
porcupine's
porcupines
pore
pored
pores
poring
pork
pork's
porn
pornographer
pornographer's
pornographers
pornographic
pornography
pornography's
porous
porpoise
porpoise's
porpoised
porpoises
porpoising
porridge
porridge's
port
port's
portability
portable
portables
portal
portal's
portals
ported
portend
portended
portending
portends
portent
portent's
portents
porter
porter's
portered
portering
porters
portfolio
portfolio's
portfolios
porthole
porthole's
portholes
portico
portico's
porticoes
porticos
porting
portion
portion's
portioned
portioning
portions
portlier
portliest
portly
portrait
portrait's
portraits
portray
portrayal
portrayal's
portrayals
portrayed
portraying
portrays
ports
pose
posed
poses
posh
poshed
posher
poshes
poshest
poshing
posies
posing
position
position's
positional
positioned
positioning
positions
positive
positively
positiver
positives
positivest
positivism
positivism's
posse
posse's
posses
possess
possessed
possesses
possessing
possession
possession's
possessions
possessive
possessives
possessor
possessor's
possessors
possibilities
possibility
possibility's
possible
possibler
possibles
possiblest
possibly
possum
possum's
possums
post
post's
postage
postage's
postal
postbox
postbox's
postcard
postcard's
postcards
postcode
postcode's
postdate
postdated
postdates
postdating
postdoc
postdocs
postdoctoral
posted
poster
poster's
posterior
posteriors
posterity
posterity's
posters
postgraduate
postgraduate's
postgraduates
posthumous
posthumously
posting
posting's
postman
postman's
postmark
postmark's
postmarked
postmarking
postmarks
postmaster
postmaster's
postmasters
postmen
postmortem
postmortems
postpone
postponed
postponement
postponements
postpones
postponing
posts
postscript
postscript's
postscripts
postulate
postulated
postulates
postulating
posture
posture's
postured
postures
posturing
postwar
posy
posy's
pot
pot's
potassium
potassium's
potato
potato's
potatoes
potbellied
potbellies
potbelly
potbelly's
potency
potency's
potent
potential
potentially
pothole
pothole's
potholed
potholes
potholing
potion
potion's
potions
potluck
potluck's
potlucks
potpourri
potpourri's
potpourris
pots
potted
potter
potter's
pottered
potteries
pottering
potters
pottery
pottery's
pottier
potties
pottiest
potting
potty
pouch
pouch's
pouched
pouches
pouching
poultry
poultry's
pounce
pounced
pounces
pouncing
pound
pounded
pounding
pounds
pour
poured
pouring
pours
pout
pouted
pouting
pouts
poverty
poverty's
powder
powder's
powdered
powdering
powders
powdery
power
power's
powerboat
powerboat's
powerboats
powered
powerful
powerfully
powerhouse
powerhouse's
powerhouses
powering
powerless
powerlessness
powerlessness's
powers
powwow
powwow's
powwowed
powwowing
powwows
practicable
practical
practicalities
practicality
practicality's
practically
practicals
practise
practise's
practised
practises
practising
practitioner
practitioner's
practitioners
pragmatic
pragmatics
pragmatism
pragmatism's
pragmatist
pragmatist's
pragmatists
prairie
prairie's
prairies
praise
praise's
praised
praises
praiseworthy
praising
pram
pram's
prance
pranced
prances
prancing
prank
prank's
pranks
prankster
prankster's
pranksters
prattle
prattled
prattles
prattling
prawn
prawn's
prawned
prawning
prawns
pray
prayed
prayer
prayer's
prayers
praying
prays
preach
preached
preacher
preacher's
preachers
preaches
preaching
preamble
preamble's
preambled
preambles
preambling
precarious
precariously
precaution
precaution's
precautionary
precautions
precede
preceded
precedence
precedence's
precedent
precedent's
precedents
precedes
preceding
precept
precept's
precepts
precinct
precinct's
precincts
precious
precipice
precipice's
precipices
precipitate
precipitated
precipitates
precipitating
precipitation
precipitation's
precipitations
precipitous
precise
precisely
preciser
precises
precisest
precision
precision's
preclude
precluded
precludes
precluding
precocious
preconceive
preconceived
preconceives
preconceiving
preconception
preconception's
preconceptions
precondition
precondition's
preconditioned
preconditioning
preconditions
precursor
precursor's
precursors
predate
predated
predates
predating
predator
predator's
predators
predatory
predecessor
predecessor's
predecessors
predefined
predestination
predestination's
predestine
predestined
predestines
predestining
predetermine
predetermined
predetermines
predetermining
predicament
predicament's
predicaments
predicate
predicated
predicates
predicating
predict
predictable
predictably
predicted
predicting
prediction
prediction's
predictions
predictor
predictor's
predicts
predilection
predilection's
predilections
predispose
predisposed
predisposes
predisposing
predisposition
predisposition's
predispositions
predominance
predominance's
predominant
predominantly
predominate
predominated
predominates
predominating
preeminence
preeminence's
preeminent
preempt
preempted
preempting
preemptive
preempts
preen
preened
preening
preens
preexist
preexisted
preexisting
preexists
prefab
prefab's
prefabbed
prefabbing
prefabricate
prefabricated
prefabricates
prefabricating
prefabs
preface
preface's
prefaced
prefaces
prefacing
prefect
prefect's
prefer
preferable
preferably
preference
preference's
preferences
preferential
preferred
preferring
prefers
prefix
prefix's
prefixed
prefixes
prefixing
pregnancies
pregnancy
pregnancy's
pregnant
prehistoric
prehistory
prehistory's
prejudge
prejudged
prejudges
prejudging
prejudice
prejudice's
prejudiced
prejudices
prejudicial
prejudicing
preliminaries
preliminary
prelude
prelude's
preludes
premarital
premature
prematurely
premeditate
premeditated
premeditates
premeditating
premeditation
premeditation's
premier
premier's
premiere
premiere's
premiered
premieres
premiering
premiers
premise
premised
premises
premising
premium
premium's
premiums
premonition
premonition's
premonitions
prenatal
preoccupation
preoccupation's
preoccupations
preoccupied
preoccupies
preoccupy
preoccupying
prep
prep's
prepaid
preparation
preparation's
preparations
preparatory
prepare
prepared
preparedness
preparedness's
prepares
preparing
prepay
prepaying
prepays
preponderance
preponderance's
preponderances
preposition
preposition's
prepositional
prepositioned
prepositioning
prepositions
preposterous
prepped
preppie
preppier
preppies
preppiest
prepping
preppy
preps
preregister
preregistered
preregistering
preregisters
preregistration
preregistration's
prerequisite
prerequisites
prerogative
prerogative's
prerogatives
presage
presage's
presaged
presages
presaging
preschool
preschooler
preschoolers
preschools
prescribe
prescribed
prescribes
prescribing
prescription
prescription's
prescriptions
prescriptive
presence
presence's
presences
present
presentable
presentation
presentation's
presentations
presented
presenter
presenting
presently
presents
preservation
preservation's
preservative
preservative's
preservatives
preserve
preserved
preserves
preserving
preside
presided
presidencies
presidency
presidency's
president
president's
presidential
presidents
presides
presiding
press
pressed
presses
pressing
pressings
pressure
pressure's
pressured
pressures
pressuring
pressurise
pressurised
pressurises
pressurising
prestige
prestige's
prestigious
presto
presumably
presume
presumed
presumes
presuming
presumption
presumption's
presumptions
presumptuous
presuppose
presupposed
presupposes
presupposing
presupposition
presuppositions
pretence
pretence's
pretences
pretencion
pretencion's
pretencions
pretend
pretended
pretender
pretender's
pretenders
pretending
pretends
pretentious
pretentiously
pretentiousness
pretext
pretext's
pretexted
pretexting
pretexts
prettied
prettier
pretties
prettiest
prettily
pretty
prettying
pretzel
pretzel's
pretzels
prevail
prevailed
prevailing
prevails
prevalence
prevalence's
prevalent
prevalents
prevent
preventable
prevented
preventing
prevention
prevention's
preventive
preventives
prevents
preview
preview's
previewed
previewer
previewers
previewing
previews
previous
previously
prewar
prey
prey's
preyed
preyer
preying
preys
price
price's
priced
priceless
prices
pricey
pricier
priciest
pricing
prick
pricked
pricking
prickle
prickle's
prickled
prickles
pricklier
prickliest
prickling
prickly
pricks
pricy
pride
pride's
prided
prides
priding
pried
prier
pries
priest
priest's
priestess
priestess's
priestesses
priesthood
priesthood's
priesthoods
priests
prim
primacy
primacy's
primal
primaries
primarily
primary
primate
primate's
primates
prime
primed
primer
primer's
primers
primes
primeval
priming
priming's
primitive
primitives
primly
primmer
primmest
primordial
primordials
primp
primped
primping
primps
primrose
primrose's
primrosed
primroses
primrosing
prince
prince's
princelier
princeliest
princely
princes
princess
princess's
princesses
principal
principalities
principality
principality's
principally
principals
principle
principle's
principled
principles
principling
print
printable
printed
printer
printer's
printers
printing
printing's
printings
printout
printouts
prints
prior
priorities
prioritise
prioritised
prioritises
prioritising
priority
priority's
priors
prise
prise's
prised
prises
prising
prism
prism's
prisms
prison
prison's
prisoned
prisoner
prisoner's
prisoners
prisoning
prisons
prissier
prissies
prissiest
prissy
pristine
privacy
privacy's
private
privately
privater
privates
privatest
privation
privation's
privations
privatisation
privatisations
privatise
privatised
privatises
privatising
privier
privies
priviest
privilege
privilege's
privileged
privileges
privileging
privy
pro
probabilistic
probabilities
probability
probability's
probable
probables
probably
probation
probation's
probe
probed
probes
probing
problem
problem's
problematic
problematics
problems
procedural
procedure
procedure's
procedures
proceed
proceeded
proceeding
proceeding's
proceedings
proceeds
process
process's
processed
processes
processing
procession
procession's
processional
processionals
processioned
processioning
processions
processor
processor's
processors
proclaim
proclaimed
proclaiming
proclaims
proclamation
proclamation's
proclamations
procrastinate
procrastinated
procrastinates
procrastinating
procrastination
procrastination's
procreate
procreated
procreates
procreating
procure
procured
procurement
procurement's
procures
procuring
prod
prodded
prodding
prodigal
prodigals
prodigies
prodigious
prodigy
prodigy's
prods
produce
produced
producer
producer's
producers
produces
producing
product
product's
production
production's
productions
productive
productivity
productivity's
products
prof
prof's
profane
profaned
profanes
profaning
profanities
profanity
profanity's
profess
professed
professes
professing
profession
profession's
professional
professionalism
professionalism's
professionally
professionals
professions
professor
professor's
professors
proffer
proffered
proffering
proffers
proficiency
proficiency's
proficient
proficiently
proficients
profile
profile's
profiled
profiles
profiling
profit
profit's
profitability
profitability's
profitable
profitably
profited
profiteer
profiteer's
profiteered
profiteering
profiteers
profiting
profits
profound
profounder
profoundest
profoundly
profs
profundities
profundity
profundity's
profuse
profusely
profusion
profusion's
profusions
progeny
progeny's
prognoses
prognosis
prognosis's
program
program's
programed
programing
programmable
programme
programme's
programmed
programmer
programmer's
programmers
programmes
programming
programs
progress
progress's
progressed
progresses
progressing
progression
progression's
progressions
progressive
progressively
progressives
prohibit
prohibited
prohibiting
prohibition
prohibition's
prohibitions
prohibitive
prohibitively
prohibits
project
project's
projected
projectile
projectile's
projectiles
projecting
projection
projection's
projections
projector
projector's
projectors
projects
proletarian
proletarians
proletariat
proletariat's
proliferate
proliferated
proliferates
proliferating
proliferation
proliferation's
prolific
prologue
prologue's
prologues
prolong
prolonged
prolonging
prolongs
prom
prom's
promenade
promenade's
promenaded
promenades
promenading
prominence
prominence's
prominent
prominently
promiscuity
promiscuity's
promiscuous
promise
promised
promises
promising
promo
promontories
promontory
promontory's
promos
promote
promoted
promoter
promoter's
promoters
promotes
promoting
promotion
promotion's
promotional
promotions
prompt
prompted
prompter
promptest
prompting
promptings
promptly
promptness
promptness's
prompts
proms
promulgate
promulgated
promulgates
promulgating
prone
prong
prong's
prongs
pronoun
pronoun's
pronounce
pronounced
pronouncement
pronouncement's
pronouncements
pronounces
pronouncing
pronouns
pronto
pronunciation
pronunciation's
pronunciations
proof
proof's
proofed
proofing
proofread
proofreading
proofreads
proofs
prop
propaganda
propaganda's
propagandise
propagandised
propagandises
propagandising
propagate
propagated
propagates
propagating
propagation
propagation's
propel
propelled
propeller
propeller's
propellers
propelling
propels
propensities
propensity
propensity's
proper
properer
properest
properly
properties
property
property's
prophecies
prophecy
prophecy's
prophesied
prophesies
prophesy
prophesying
prophet
prophet's
prophetic
prophets
propitious
proponent
proponent's
proponents
proportion
proportion's
proportional
proportionality
proportionality's
proportionally
proportionals
proportionate
proportioned
proportioning
proportions
proposal
proposal's
proposals
propose
proposed
proposes
proposing
proposition
proposition's
propositional
propositioned
propositioning
propositions
propped
propping
proprietaries
proprietary
proprietor
proprietor's
proprietors
propriety
propriety's
props
propulsion
propulsion's
pros
prosaic
proscribe
proscribed
proscribes
proscribing
proscription
proscription's
proscriptions
prose
prose's
prosecute
prosecuted
prosecutes
prosecuting
prosecution
prosecution's
prosecutions
prosecutor
prosecutor's
prosecutors
proselytise
proselytised
proselytises
proselytising
proses
prospect
prospect's
prospected
prospecting
prospective
prospectives
prospector
prospector's
prospectors
prospects
prospectus
prospectus's
prospectuses
prosper
prospered
prospering
prosperity
prosperity's
prosperous
prospers
prosses
prostheses
prosthesis
prosthesis's
prostitute
prostitute's
prostituted
prostitutes
prostituting
prostitution
prostitution's
prostrate
prostrated
prostrates
prostrating
protagonist
protagonist's
protagonists
protect
protected
protecting
protection
protection's
protections
protective
protectives
protector
protector's
protectors
protects
protein
protein's
proteins
protest
protest's
protestant
protested
protester
protester's
protesters
protesting
protestor
protestors
protests
protocol
protocol's
protocols
proton
proton's
protons
prototype
prototype's
prototypes
protract
protracted
protracting
protraction
protraction's
protractor
protractor's
protractors
protracts
protrude
protruded
protrudes
protruding
protrusion
protrusion's
protrusions
protg
protg's
protgs
proud
prouder
proudest
proudly
provable
provably
prove
proved
proven
provenance
provenance's
proverb
proverb's
proverbial
proverbs
proves
provide
provided
providence
providence's
provident
provider
provider's
provides
providing
province
province's
provinces
provincial
provincials
proving
provision
provision's
provisional
provisionally
provisioned
provisioning
provisions
proviso
proviso's
provisoes
provisos
provocation
provocation's
provocations
provocative
provoke
provoked
provokes
provoking
provost
provost's
provosts
prow
prow's
prowess
prowess's
prowl
prowled
prowler
prowler's
prowlers
prowling
prowls
prows
proxies
proximity
proximity's
proxy
proxy's
prude
prude's
prudence
prudence's
prudent
prudently
prudes
prudish
prune
prune's
pruned
prunes
pruning
prurience
prurience's
prurient
pry
prying
prys
prcis
prcis's
prcised
prcising
psalm
psalm's
psalms
pseudo
pseudonym
pseudonym's
pseudonyms
psych
psyche
psyche's
psyched
psychedelic
psychedelics
psyches
psychiatric
psychiatrist
psychiatrist's
psychiatrists
psychiatry
psychiatry's
psychic
psychics
psyching
psycho
psycho's
psychoanalyse
psychoanalysed
psychoanalyses
psychoanalysing
psychoanalysis
psychoanalysis's
psychoanalyst
psychoanalysts
psychological
psychologically
psychologies
psychologist
psychologist's
psychologists
psychology
psychology's
psychopath
psychopath's
psychopathic
psychopathics
psychopaths
psychos
psychoses
psychosis
psychosis's
psychosomatic
psychosomatics
psychotherapies
psychotherapist
psychotherapist's
psychotherapists
psychotherapy
psychotherapy's
psychotic
psychotics
psychs
pub
pub's
pubbed
pubbing
puberty
puberty's
pubescence
pubic
public
publication
publication's
publications
publicise
publicised
publicises
publicising
publicist
publicist's
publicists
publicity
publicity's
publicly
publish
published
publisher
publisher's
publishers
publishes
publishing
publishing's
pubs
puck
puck's
pucked
pucker
puckered
puckering
puckers
pucking
pucks
pudding
pudding's
puddings
puddle
puddle's
puddled
puddles
puddling
pudgier
pudgiest
pudgy
pueblo
pueblo's
pueblos
puerile
puff
puff's
puffed
puffer
puffier
puffiest
puffing
puffs
puffy
pugnacious
puke
puked
pukes
puking
pull
pulled
pulley
pulley's
pulleys
pulling
pullout
pullouts
pullover
pullover's
pullovers
pulls
pulmonary
pulp
pulp's
pulped
pulping
pulpit
pulpit's
pulpits
pulps
pulsate
pulsated
pulsates
pulsating
pulsation
pulsation's
pulsations
pulse
pulse's
pulsed
pulses
pulsing
pulverisation
pulverisation's
pulverise
pulverised
pulverises
pulverising
puma
puma's
pumas
pumice
pumice's
pumices
pummel
pummelled
pummelling
pummels
pump
pump's
pumped
pumpernickel
pumpernickel's
pumping
pumping's
pumpkin
pumpkin's
pumpkins
pumps
pun
pun's
punch
punched
punches
punching
punchline
punctual
punctuality
punctuality's
punctuate
punctuated
punctuates
punctuating
punctuation
punctuation's
puncture
puncture's
punctured
punctures
puncturing
pundit
pundit's
pundits
pungent
punier
puniest
punish
punishable
punished
punishes
punishing
punishment
punishment's
punishments
punitive
punk
punk's
punker
punkest
punks
punned
punning
puns
punt
punt's
punted
punter
punter's
punters
punting
punts
puny
pup
pup's
pupil
pupil's
pupils
pupped
puppet
puppet's
puppeteer
puppeteer's
puppeteers
puppets
puppied
puppies
pupping
puppy
puppy's
puppying
pups
purchase
purchased
purchaser
purchaser's
purchasers
purchases
purchasing
pure
pured
puree
puree's
pureed
pureeing
purees
purely
purer
pures
purest
purgatories
purgatory
purgatory's
purge
purged
purges
purging
purification
purified
purifies
purify
purifying
puring
purist
purist's
purists
puritan
puritan's
puritanical
puritans
purity
purity's
purple
purple's
purpler
purples
purplest
purport
purported
purporting
purports
purpose
purpose's
purposed
purposeful
purposely
purposes
purposing
purr
purred
purring
purrs
purse
purse's
pursed
purser
purser's
pursers
purses
pursing
pursue
pursued
pursues
pursuing
pursuit
pursuit's
pursuits
purvey
purveyed
purveying
purveyor
purveyor's
purveyors
purveys
pus
pus's
push
pushed
pusher
pusher's
pushers
pushes
pushier
pushiest
pushing
pushover
pushover's
pushovers
pushy
puss
pusses
pussier
pussies
pussiest
pussy
pussy's
pussycat
pussycats
pussyfoot
pussyfooted
pussyfooting
pussyfoots
put
putative
putrid
puts
putt
putt's
putted
putter
putter's
puttered
puttering
putters
puttied
putties
putting
putts
putty
putty's
puttying
puzzle
puzzled
puzzles
puzzling
pygmies
pygmy
pygmy's
pyjamas
pylon
pylon's
pylons
pyramid
pyramid's
pyramided
pyramides
pyramiding
pyramids
pyre
pyre's
pyres
python
python's
pythons
pres
q
qua
quack
quacked
quacking
quacks
quad
quad's
quadrangle
quadrangle's
quadrangles
quadrant
quadrant's
quadrants
quadratic
quadratic's
quadrilateral
quadrilaterals
quadruped
quadruped's
quadrupeds
quadruple
quadrupled
quadruples
quadruplet
quadruplet's
quadruplets
quadrupling
quads
quagmire
quagmire's
quagmired
quagmires
quagmiring
quail
quail's
quailed
quailing
quails
quaint
quainter
quaintest
quake
quaked
quakes
quaking
qualification
qualification's
qualifications
qualified
qualifier
qualifier's
qualifiers
qualifies
qualify
qualifying
qualitative
qualities
quality
quality's
qualm
qualm's
qualms
quandaries
quandary
quandary's
quantified
quantifier
quantifier's
quantifiers
quantifies
quantify
quantifying
quantitative
quantities
quantity
quantity's
quantum
quantum's
quarantine
quarantine's
quarantined
quarantines
quarantining
quark
quark's
quarks
quarrel
quarrel's
quarrelled
quarrelling
quarrels
quarrelsome
quarried
quarries
quarry
quarry's
quarrying
quart
quart's
quarter
quarter's
quarterback
quarterback's
quarterbacked
quarterbacking
quarterbacks
quartered
quarterfinal
quarterfinal's
quarterfinals
quartering
quarterlies
quarterly
quarters
quartet
quartet's
quartets
quarts
quartz
quartz's
quash
quashed
quashes
quashing
quaver
quavered
quavering
quavers
quay
quay's
quays
queasier
queasiest
queasiness
queasiness's
queasy
queen
queen's
queened
queening
queenlier
queenliest
queenly
queens
queer
queered
queerer
queerest
queering
queers
quell
quelled
quelling
quells
quench
quenched
quenches
quenching
queried
queries
query
query's
querying
quest
quest's
quested
questing
question
question's
questionable
questioned
questioning
questionnaire
questionnaire's
questionnaires
questions
quests
queue
queue's
queued
queueing
queues
quibble
quibbled
quibbles
quibbling
quiche
quiche's
quiches
quick
quicken
quickened
quickening
quickens
quicker
quickest
quickie
quickie's
quickies
quickly
quicksand
quicksand's
quicksands
quiet
quieted
quieter
quieter's
quietest
quieting
quietly
quietness
quietness's
quiets
quill
quill's
quills
quilt
quilt's
quilted
quilting
quilts
quinine
quinine's
quintessence
quintessence's
quintessences
quintessential
quintet
quintet's
quintets
quintuplet
quintuplet's
quintuplets
quip
quip's
quipped
quipping
quips
quirk
quirk's
quirked
quirkier
quirkiest
quirking
quirks
quirky
quit
quite
quited
quites
quiting
quits
quitted
quitter
quitters
quitting
quiver
quivered
quivering
quivers
quixotic
quiz
quiz's
quizes
quizzed
quizzes
quizzical
quizzing
quorum
quorum's
quorums
quota
quota's
quotable
quotas
quotation
quotation's
quotations
quote
quoted
quotes
quotient
quotient's
quotients
quoting
r
rabbi
rabbi's
rabbies
rabbis
rabbit
rabbit's
rabbited
rabbiting
rabbits
rabble
rabble's
rabbles
rabid
rabies
raccoon
raccoon's
raccoons
race
race's
raced
racer
racer's
races
racetrack
racetrack's
racetracks
racial
racially
racier
raciest
racing
racism
racist
racist's
racists
rack
rack's
racked
racket
racket's
racketed
racketeer
racketeer's
racketeered
racketeering
racketeers
racketing
rackets
racking
racks
racoon
racy
radar
radar's
radars
radial
radials
radiance
radiance's
radiant
radiate
radiated
radiates
radiating
radiation
radiation's
radiations
radiator
radiator's
radiators
radical
radically
radicals
radii
radii's
radio
radio's
radioactive
radioactivity
radioactivity's
radioed
radioing
radiologist
radiologist's
radiologists
radiology
radiology's
radios
radiotherapy
radiotherapy's
radish
radish's
radishes
radium
radium's
radius
radius's
radiuses
radon
radon's
raffle
raffle's
raffled
raffles
raffling
raft
raft's
rafted
rafter
rafter's
rafters
rafting
rafts
rag
rag's
ragamuffin
ragamuffin's
ragamuffins
rage
rage's
raged
rages
ragged
raggeder
raggedest
ragging
raging
rags
ragtag
ragtag's
ragtags
ragtime
ragtime's
raid
raid's
raided
raider
raider's
raiders
raiding
raids
rail
rail's
railed
railing
railing's
railroad
railroad's
railroaded
railroading
railroads
rails
railway
railway's
railways
rain
rain's
rainbow
rainbow's
rainbows
raincoat
raincoat's
raincoats
raindrop
raindrop's
raindrops
rained
rainfall
rainfall's
rainfalls
rainforest
rainforest's
rainier
rainiest
raining
rains
rainstorm
rainstorm's
rainstorms
rainwater
rainwater's
rainy
raise
raised
raises
raisin
raisin's
raising
raising's
raisins
rake
rake's
raked
rakes
raking
rallied
rallies
rally
rallying
ram
ram's
ramble
rambled
rambler
rambler's
ramblers
rambles
rambling
ramblings
rambunctious
ramification
ramification's
ramifications
rammed
ramming
ramp
ramp's
rampage
rampaged
rampages
rampaging
rampant
ramps
ramrod
ramrod's
ramrodded
ramrodding
ramrods
rams
ramshackle
ran
ranch
ranch's
ranched
rancher
rancher's
ranchers
ranches
ranching
rancid
rancorous
rancour
random
randomly
randomness
randomness's
rang
range
range's
ranged
ranger
ranger's
rangers
ranges
ranging
rank
rank's
ranked
ranker
rankest
ranking
rankings
rankle
rankled
rankles
rankling
ranks
ransack
ransacked
ransacking
ransacks
ransom
ransom's
ransomed
ransoming
ransoms
rant
ranted
ranting
rants
rap
rape
rape's
raped
rapes
rapid
rapider
rapidest
rapidity
rapidity's
rapidly
rapids
raping
rapist
rapist's
rapists
rapped
rapping
rapport
rapport's
rapports
rapprochement
rapprochement's
rapprochements
raps
rapt
rapture
rapture's
raptures
rapturous
rare
rared
rarely
rarer
rares
rarest
raring
rarities
rarity
rarity's
rascal
rascal's
rascals
rash
rasher
rashes
rashest
rashly
rasp
rasp's
raspberries
raspberry
raspberry's
rasped
raspier
raspiest
rasping
rasps
raspy
raster
raster's
rat
rat's
rate
rate's
rated
rates
rather
ratification
ratified
ratifies
ratify
ratifying
rating
rating's
ratings
ratio
ratio's
ration
ration's
rational
rationale
rationale's
rationales
rationalisation
rationalisation's
rationalisations
rationalise
rationalised
rationalises
rationalising
rationality
rationality's
rationally
rationals
rationed
rationing
rations
ratios
rats
ratted
ratting
rattle
rattled
rattler
rattlers
rattles
rattlesnake
rattlesnake's
rattlesnakes
rattling
ratty
raucous
raucously
raunchier
raunchiest
raunchy
ravage
ravaged
ravages
ravaging
rave
raved
ravel
ravelled
ravelling
ravellings
ravels
raven
raven's
ravened
ravening
ravenous
ravenously
ravens
raves
ravine
ravine's
ravined
ravines
raving
ravings
ravining
ravish
ravished
ravishes
ravishing
raw
rawer
rawest
ray
ray's
rayon
rayon's
rays
raze
razed
razes
razing
razor
razor's
razors
razz
razzed
razzes
razzing
re
re's
reach
reached
reaches
reaching
react
reacted
reacting
reaction
reaction's
reactionaries
reactionary
reactions
reactive
reactor
reactor's
reactors
reacts
read
readability
readability's
readable
reader
reader's
readers
readership
readership's
readerships
readied
readier
readies
readiest
readily
readiness
readiness's
reading
reading's
readings
readjust
readjusted
readjusting
readjustment
readjustment's
readjustments
readjusts
reads
ready
readying
real
realer
realest
realisation
realisation's
realise
realised
realises
realising
realism
realism's
realist
realist's
realistic
realistically
realists
realities
reality
reality's
reallied
reallies
reallocate
reallocated
reallocates
reallocating
really
reallying
realm
realm's
realms
realty
realty's
ream
ream's
reamed
reaming
reams
reap
reaped
reaper
reaper's
reapers
reaping
reappear
reappearance
reappearance's
reappearances
reappeared
reappearing
reappears
reaps
rear
rear's
reared
rearing
rearrange
rearranged
rearrangement
rearrangement's
rearrangements
rearranges
rearranging
rears
reason
reason's
reasonable
reasonableness
reasonableness's
reasonably
reasoned
reasoning
reasoning's
reasons
reassurance
reassurance's
reassurances
reassure
reassured
reassures
reassuring
reassuringly
rebate
rebate's
rebated
rebates
rebating
rebel
rebelled
rebelling
rebellion
rebellion's
rebellions
rebellious
rebels
rebind
rebinding
rebinds
rebirth
rebirth's
rebirths
reborn
rebound
rebounded
rebounding
rebounds
rebuff
rebuffed
rebuffing
rebuffs
rebuild
rebuilding
rebuilds
rebuilt
rebuke
rebuked
rebukes
rebuking
rebut
rebuts
rebuttal
rebuttal's
rebuttals
rebutted
rebutting
recalcitrance
recalcitrance's
recalcitrant
recall
recalled
recalling
recalls
recant
recanted
recanting
recants
recap
recapped
recapping
recaps
recapture
recaptured
recaptures
recapturing
recede
receded
recedes
receding
receipt
receipt's
receipted
receipting
receipts
receive
received
receiver
receiver's
receivers
receivership
receivership's
receives
receiving
recent
recenter
recentest
recently
receptacle
receptacle's
receptacles
reception
reception's
receptionist
receptionist's
receptionists
receptions
receptive
recess
recess's
recessed
recesses
recessing
recession
recession's
recessions
recharge
rechargeable
recharged
recharges
recharging
recipe
recipe's
recipes
recipient
recipient's
recipients
reciprocal
reciprocals
reciprocate
reciprocated
reciprocates
reciprocating
recital
recital's
recitals
recitation
recitation's
recitations
recite
recited
recites
reciting
reckless
recklessly
recklessness
reckon
reckoned
reckoning
reckoning's
reckonings
reckons
reclaim
reclaimed
reclaiming
reclaims
reclamation
reclamation's
recline
reclined
reclines
reclining
recluse
recluse's
recluses
recognisable
recognisably
recognise
recognised
recognises
recognising
recognition
recognition's
recoil
recoiled
recoiling
recoils
recollect
recollected
recollecting
recollection
recollection's
recollections
recollects
recommend
recommendation
recommendation's
recommendations
recommended
recommending
recommends
recompense
recompensed
recompenses
recompensing
recompile
recompiled
recompiling
reconcile
reconciled
reconciles
reconciliation
reconciliations
reconciling
recondition
reconditioned
reconditioning
reconditions
reconfigure
reconfigured
reconnaissance
reconnaissance's
reconnaissances
reconnect
reconnected
reconnecting
reconnects
reconsider
reconsidered
reconsidering
reconsiders
reconstitute
reconstituted
reconstitutes
reconstituting
reconstruct
reconstructed
reconstructing
reconstruction
reconstruction's
reconstructions
reconstructs
record
record's
recorded
recorder
recorder's
recorders
recording
recording's
recordings
records
recount
recounted
recounting
recounts
recoup
recouped
recouping
recoups
recourse
recourse's
recover
recoverable
recovered
recoveries
recovering
recovers
recovery
recovery's
recreate
recreated
recreates
recreating
recreation
recreation's
recreational
recreations
recruit
recruited
recruiter
recruiter's
recruiters
recruiting
recruitment
recruitment's
recruits
recta
rectal
rectangle
rectangle's
rectangles
rectangular
rectified
rectifies
rectify
rectifying
rector
rector's
rectors
rectum
rectum's
rectums
recuperate
recuperated
recuperates
recuperating
recuperation
recuperation's
recur
recurred
recurrence
recurrence's
recurrences
recurrent
recurring
recurs
recursion
recursion's
recursive
recursively
recyclable
recyclables
recycle
recycled
recycles
recycling
red
red's
redden
reddened
reddening
reddens
redder
reddest
reddish
redeem
redeemable
redeemed
redeeming
redeems
redefine
redefined
redefines
redefining
redefinition
redefinition's
redemption
redemption's
redesign
redesigned
redesigning
redesigns
redevelop
redeveloped
redeveloping
redevelopment
redevelopment's
redevelopments
redevelops
redhead
redhead's
redheads
redid
redirect
redirected
redirecting
redirection
redirects
rediscover
rediscovered
rediscovering
rediscovers
redistribute
redistributed
redistributes
redistributing
redistribution
redistribution's
redneck
redneck's
rednecks
redness
redness's
redo
redoes
redoing
redone
redouble
redoubled
redoubles
redoubling
redraft
redraft's
redraw
redress
redressed
redresses
redressing
reds
redskin
redskin's
redskins
reduce
reduced
reduces
reducing
reduction
reduction's
reductions
redundancies
redundancy
redundancy's
redundant
redwood
redwood's
redwoods
reed
reed's
reeds
reeducate
reeducated
reeducates
reeducating
reeducation
reeducation's
reef
reef's
reefed
reefing
reefs
reek
reeked
reeking
reeks
reel
reel's
reelect
reelected
reelecting
reelection
reelection's
reelections
reelects
reeled
reeling
reels
reenact
reenacted
reenacting
reenactment
reenactment's
reenactments
reenacts
reentries
reentry
reentry's
ref
ref's
refed
refer
referee
referee's
refereed
refereeing
referees
reference
reference's
referenced
references
referencing
referenda
referendum
referendum's
referendums
referred
referring
refers
reffed
reffing
refill
refilled
refilling
refills
refinance
refinanced
refinances
refinancing
refine
refined
refinement
refinement's
refinements
refineries
refinery
refinery's
refines
refining
refinish
refinished
refinishes
refinishing
reflect
reflected
reflecting
reflection
reflection's
reflections
reflective
reflector
reflector's
reflectors
reflects
reflex
reflex's
reflexes
reflexive
reflexives
reform
reformat
reformation
reformation's
reformations
reformatted
reformatting
reformed
reformer
reformer's
reformers
reforming
reforms
refraction
refraction's
refrain
refrained
refraining
refrains
refresh
refreshed
refreshes
refreshing
refreshingly
refreshment
refreshment's
refreshments
refrigerate
refrigerated
refrigerates
refrigerating
refrigeration
refrigeration's
refrigerator
refrigerator's
refrigerators
refs
refuel
refuelled
refuelling
refuels
refuge
refuge's
refugee
refugee's
refugees
refuges
refund
refundable
refunded
refunding
refunds
refurbish
refurbished
refurbishes
refurbishing
refurbishment
refurbishments
refusal
refusal's
refusals
refuse
refuse's
refused
refuses
refusing
refutation
refutation's
refute
refuted
refutes
refuting
regain
regained
regaining
regains
regal
regale
regaled
regales
regalia
regalia's
regaling
regals
regard
regarded
regarding
regardless
regards
regatta
regatta's
regattas
regenerate
regenerated
regenerates
regenerating
regeneration
regeneration's
regent
regent's
regents
reggae
reggae's
regime
regime's
regimen
regimen's
regimens
regiment
regiment's
regimental
regimentals
regimented
regimenting
regiments
regimes
region
region's
regional
regionally
regions
register
register's
registered
registering
registers
registrar
registrar's
registrars
registration
registration's
registrations
registries
registry
registry's
regress
regressed
regresses
regressing
regression
regression's
regressions
regret
regretful
regretfully
regrets
regrettable
regrettably
regretted
regretting
regroup
regrouped
regrouping
regroups
regular
regularity
regularity's
regularly
regulars
regulate
regulated
regulates
regulating
regulation
regulation's
regulations
regurgitate
regurgitated
regurgitates
regurgitating
regurgitation
regurgitation's
rehab
rehabbed
rehabbing
rehabilitate
rehabilitated
rehabilitates
rehabilitating
rehabilitation
rehabilitation's
rehabs
rehash
rehashed
rehashes
rehashing
rehearsal
rehearsal's
rehearsals
rehearse
rehearsed
rehearses
rehearsing
reign
reign's
reigned
reigning
reigns
reimburse
reimbursed
reimbursement
reimbursements
reimburses
reimbursing
rein
rein's
reincarnate
reincarnated
reincarnates
reincarnating
reincarnation
reincarnation's
reincarnations
reindeer
reindeer's
reindeers
reined
reinforce
reinforced
reinforcement
reinforcement's
reinforcements
reinforces
reinforcing
reining
reins
reinstate
reinstated
reinstatement
reinstatement's
reinstates
reinstating
reinvent
reinvented
reinventing
reinvents
reissue
reissued
reissues
reissuing
reiterate
reiterated
reiterates
reiterating
reiteration
reiterations
reject
rejected
rejecting
rejection
rejection's
rejections
rejects
rejoice
rejoiced
rejoices
rejoicing
rejoicings
rejoin
rejoinder
rejoinder's
rejoinders
rejoined
rejoining
rejoins
rejuvenate
rejuvenated
rejuvenates
rejuvenating
rejuvenation
rekindle
rekindled
rekindles
rekindling
relaid
relapse
relapsed
relapses
relapsing
relate
related
relates
relating
relation
relation's
relational
relations
relationship
relationship's
relationships
relative
relatively
relatives
relativistic
relativity
relativity's
relax
relaxation
relaxation's
relaxations
relaxed
relaxes
relaxing
relay
relay's
relayed
relaying
relays
releasable
release
released
releases
releasing
relegate
relegated
relegates
relegating
relent
relented
relenting
relentless
relentlessly
relents
relevance
relevance's
relevant
reliability
reliability's
reliable
reliables
reliably
reliance
reliance's
reliant
relic
relic's
relics
relied
relief
relief's
reliefs
relies
relieve
relieved
relieves
relieving
religion
religion's
religions
religious
religiously
relinquish
relinquished
relinquishes
relinquishing
relish
relished
relishes
relishing
relive
relived
relives
reliving
reload
reload's
reloaded
reloading
reloads
relocatable
relocate
relocated
relocates
relocating
relocation
relocation's
reluctance
reluctance's
reluctant
reluctantly
rely
relying
remade
remain
remainder
remainder's
remainders
remained
remaining
remains
remake
remake's
remakes
remaking
remark
remarkable
remarkably
remarked
remarking
remarks
remarriage
remarriage's
remarriages
remarried
remarries
remarry
remarrying
remedial
remedied
remedies
remedy
remedy's
remedying
remember
remembered
remembering
remembers
remembrance
remembrance's
remembrances
remind
reminded
reminder
reminders
reminding
reminds
reminisce
reminisced
reminiscence
reminiscence's
reminiscences
reminiscent
reminisces
reminiscing
remiss
remission
remission's
remissions
remit
remits
remittance
remittance's
remittances
remitted
remitting
remnant
remnant's
remnants
remodel
remodelled
remodelling
remodels
remorse
remorse's
remorseful
remorseless
remote
remotely
remoteness
remoteness's
remoter
remotes
remotest
removable
removables
removal
removal's
removals
remove
removed
remover
remover's
removers
removes
removing
remunerate
remunerated
remunerates
remunerating
remuneration
remuneration's
remunerations
renaissance
rename
renamed
renames
renaming
rend
render
rendered
rendering
rendering's
renderings
renders
rendezvous
rendezvous's
rendezvoused
rendezvouses
rendezvousing
rending
rendition
rendition's
renditioned
renditioning
renditions
rends
renegade
renegade's
renegaded
renegades
renegading
renege
reneged
reneges
reneging
renew
renewable
renewal
renewal's
renewals
renewed
renewing
renews
renounce
renounced
renounces
renouncing
renovate
renovated
renovates
renovating
renovation
renovation's
renovations
renown
renown's
renowned
renowning
renowns
rent
rent's
rental
rental's
rentals
rented
renter
renter's
renters
renting
rents
renunciation
renunciation's
renunciations
reopen
reopened
reopening
reopens
reorganisation
reorganisation's
reorganisations
reorganise
reorganised
reorganises
reorganising
rep
rep's
repaid
repair
repaired
repairing
repairs
reparation
reparation's
repatriate
repatriated
repatriates
repatriating
repatriation
repay
repaying
repayment
repayment's
repayments
repays
repeal
repealed
repealing
repeals
repeat
repeatable
repeated
repeatedly
repeating
repeats
repel
repelled
repellent
repellents
repelling
repels
repent
repentance
repentance's
repentant
repentants
repented
repenting
repents
repercussion
repercussion's
repercussions
repertoire
repertoire's
repertoires
repetition
repetition's
repetitions
repetitious
repetitive
rephrase
rephrased
rephrases
rephrasing
replace
replaceable
replaced
replacement
replacement's
replacements
replaces
replacing
replay
replay's
replayed
replaying
replays
replenish
replenished
replenishes
replenishing
replenishment
replete
repleted
repletes
repleting
replica
replica's
replicas
replicate
replicated
replicates
replicating
replication
replication's
replications
replied
replies
reply
replying
report
report's
reported
reportedly
reporter
reporter's
reporters
reporting
reports
repose
repose's
reposed
reposes
reposing
repositories
repository
repository's
repossess
repossessed
repossesses
repossessing
reprehensible
represent
representation
representation's
representations
representative
representative's
representatives
represented
representing
represents
repress
repressed
represses
repressing
repression
repression's
repressions
repressive
reprieve
reprieved
reprieves
reprieving
reprimand
reprimand's
reprimanded
reprimanding
reprimands
reprint
reprint's
reprinted
reprinting
reprints
reprisal
reprisal's
reprisals
reprise
reprise's
reprised
reprises
reprising
reproach
reproached
reproaches
reproaching
reproduce
reproduced
reproduces
reproducing
reproduction
reproduction's
reproductions
reproductive
reprogramed
reprograming
reprogramme
reprogrammed
reprogrammes
reprogramming
reprove
reproved
reproves
reproving
reps
reptile
reptile's
reptiles
reptilian
reptilians
republic
republic's
republican
republicans
republics
repudiate
repudiated
repudiates
repudiating
repudiation
repudiation's
repudiations
repugnance
repugnance's
repugnant
repulse
repulsed
repulses
repulsing
repulsion
repulsion's
repulsive
reputable
reputation
reputation's
reputations
repute
reputed
reputedly
reputes
reputing
request
requested
requesting
requests
requiem
requiems
require
required
requirement
requirement's
requirements
requires
requiring
requisite
requisites
requisition
requisition's
requisitioned
requisitioning
requisitions
reran
reread
rereading
rereads
reroute
rerouted
reroutes
rerouting
rerun
rerunning
reruns
resale
resale's
resales
reschedule
rescheduled
reschedules
rescheduling
rescind
rescinded
rescinding
rescinds
rescue
rescued
rescuer
rescuers
rescues
rescuing
research
research's
researched
researcher
researchers
researches
researching
resemblance
resemblance's
resemblances
resemble
resembled
resembles
resembling
resent
resented
resentful
resenting
resentment
resentment's
resentments
resents
reservation
reservation's
reservations
reserve
reserved
reserves
reserving
reservoir
reservoir's
reservoirs
reset
resets
resetting
reshuffle
reshuffle's
reshuffled
reshuffles
reshuffling
reside
resided
residence
residence's
residences
residencies
residency
residency's
resident
resident's
residential
residents
resides
residing
residual
residuals
residue
residue's
residues
resign
resignation
resignation's
resignations
resigned
resigning
resigns
resilience
resilience's
resilient
resin
resin's
resins
resist
resistance
resistance's
resistances
resistant
resisted
resisting
resistor
resistors
resists
resolute
resolutely
resoluter
resolutes
resolutest
resolution
resolution's
resolutions
resolve
resolved
resolver
resolver's
resolves
resolving
resonance
resonance's
resonances
resonant
resonate
resonated
resonates
resonating
resort
resorted
resorting
resorts
resound
resounded
resounding
resoundingly
resounds
resource
resource's
resourced
resourceful
resourcefulness
resourcefulness's
resources
resourcing
respect
respect's
respectability
respectability's
respectable
respectables
respectably
respected
respectful
respectfully
respecting
respective
respectively
respects
respiration
respiration's
respirator
respirator's
respirators
respiratory
respiratory's
respite
respite's
respites
resplendent
respond
responded
responding
responds
response
response's
responses
responsibilities
responsibility
responsibility's
responsible
responsibly
responsive
responsiveness
responsiveness's
rest
rest's
restart
restarted
restarting
restarts
restate
restated
restatement
restatement's
restatements
restates
restating
restaurant
restaurant's
restaurants
rested
restful
restfuller
restfullest
resting
restitution
restitution's
restive
restless
restlessly
restlessness
restlessness's
restoration
restoration's
restorations
restore
restored
restores
restoring
restrain
restrained
restraining
restrains
restraint
restraint's
restraints
restrict
restricted
restricting
restriction
restriction's
restrictions
restrictive
restrictives
restricts
restructure
restructured
restructures
restructuring
restructurings
rests
resubmit
resubmits
resubmitted
resubmitting
result
result's
resultant
resultants
resulted
resulting
results
resume
resumed
resumes
resuming
resumption
resumption's
resumptions
resurface
resurfaced
resurfaces
resurfacing
resurgence
resurgence's
resurgences
resurgent
resurrect
resurrected
resurrecting
resurrection
resurrection's
resurrections
resurrects
resuscitate
resuscitated
resuscitates
resuscitating
resuscitation
resuscitation's
retail
retail's
retailed
retailer
retailer's
retailers
retailing
retails
retain
retained
retainer
retainer's
retainers
retaining
retains
retake
retaken
retakes
retaking
retaliate
retaliated
retaliates
retaliating
retaliation
retaliation's
retaliations
retard
retardation
retardation's
retarded
retarding
retards
retch
retched
retches
retching
retention
retention's
rethink
rethinking
rethinks
rethought
reticence
reticent
retina
retina's
retinae
retinas
retinue
retinue's
retinues
retire
retired
retiree
retiree's
retirees
retirement
retirement's
retirements
retires
retiring
retook
retort
retorted
retorting
retorts
retrace
retraced
retraces
retracing
retract
retractable
retracted
retracting
retraction
retraction's
retractions
retracts
retread
retreaded
retreading
retreads
retreat
retreated
retreating
retreats
retrial
retrial's
retrials
retribution
retribution's
retributions
retries
retrieval
retrieval's
retrievals
retrieve
retrieved
retriever
retriever's
retrievers
retrieves
retrieving
retroactive
retroactively
retrod
retrodden
retrograde
retrospect
retrospect's
retrospected
retrospecting
retrospective
retrospectively
retrospectives
retrospects
retry
return
returnable
returnables
returned
returning
returns
retype
reunion
reunion's
reunions
reunite
reunited
reunites
reuniting
reuse
reused
reuses
reusing
rev
rev's
revaluation
revaluation's
revaluations
revalue
revalued
revalues
revaluing
revamp
revamped
revamping
revamps
reveal
revealed
revealing
revealings
reveals
revel
revelation
revelation's
revelations
revelled
reveller
revellers
revelling
revellings
revelries
revelry
revelry's
revels
revenge
revenge's
revenged
revengeful
revenges
revenging
revenue
revenue's
revenues
reverberate
reverberated
reverberates
reverberating
reverberation
reverberation's
reverberations
revere
revered
reverence
reverence's
reverenced
reverences
reverencing
reverent
reverently
reveres
reverie
reverie's
reveries
revering
reversal
reversal's
reversals
reverse
reversed
reverses
reversible
reversing
reversion
reversion's
revert
reverted
reverting
reverts
revery
review
reviewed
reviewer
reviewers
reviewing
reviews
revile
reviled
reviles
reviling
revise
revised
revises
revising
revision
revision's
revisions
revisit
revisited
revisiting
revisits
revitalisation
revitalisation's
revitalise
revitalised
revitalises
revitalising
revival
revival's
revivals
revive
revived
revives
reviving
revoke
revoked
revokes
revoking
revolt
revolt's
revolted
revolting
revolts
revolution
revolution's
revolutionaries
revolutionary
revolutionary's
revolutionise
revolutionised
revolutionises
revolutionising
revolutions
revolve
revolved
revolver
revolver's
revolvers
revolves
revolving
revs
revue
revue's
revues
revulsion
revulsion's
revved
revving
reward
reward's
rewarded
rewarding
rewards
rewind
rewinding
rewinds
rework
reworked
reworking
reworks
rewound
rewrite
rewrites
rewriting
rewritten
rewrote
rhapsodies
rhapsody
rhapsody's
rhetoric
rhetoric's
rhetorical
rhetorically
rheumatism
rheumatism's
rhinestone
rhinestone's
rhinestones
rhino
rhino's
rhinoceri
rhinoceros
rhinoceros's
rhinoceroses
rhinos
rhododendron
rhododendron's
rhododendrons
rhubarb
rhubarb's
rhubarbs
rhyme
rhyme's
rhymed
rhymes
rhyming
rhythm
rhythm's
rhythmic
rhythmically
rhythms
rib
rib's
ribald
ribbed
ribbing
ribbon
ribbon's
ribbons
ribs
rice
rice's
riced
rices
rich
richer
riches
richest
richly
richness
richness's
ricing
ricketier
ricketiest
rickety
rickshaw
rickshaw's
rickshaws
ricochet
ricocheted
ricocheting
ricochets
ricochetted
ricochetting
rid
riddance
riddance's
ridded
ridden
ridding
riddle
riddle's
riddled
riddles
riddling
ride
rider
rider's
riders
rides
ridge
ridge's
ridged
ridges
ridging
ridicule
ridicule's
ridiculed
ridicules
ridiculing
ridiculous
ridiculously
riding
riding's
rids
rife
rifer
rifest
rifle
rifle's
rifled
rifles
rifling
rift
rift's
rifted
rifting
rifts
rig
rigged
rigging
rigging's
right
righted
righteous
righteously
righteousness
righteousness's
righter
rightest
rightful
rightfully
righting
rightly
rightmost
rightness
rightness's
rights
rights's
rigid
rigidity
rigidly
rigmarole
rigmarole's
rigmaroles
rigorous
rigorously
rigour
rigour's
rigours
rigs
rile
riled
riles
riling
rim
rim's
rimmed
rimming
rims
rind
rind's
rinded
rinding
rinds
ring
ring's
ringed
ringing
ringleader
ringleader's
ringleaders
ringlet
ringlet's
ringlets
rings
ringside
ringside's
ringworm
ringworm's
rink
rink's
rinked
rinking
rinks
rinse
rinsed
rinses
rinsing
riot
riot's
rioted
rioter
rioter's
rioters
rioting
riotous
riots
rip
ripe
riped
ripen
ripened
ripeness
ripeness's
ripening
ripens
riper
ripes
ripest
riping
riposte
riposte's
ripped
ripper
ripping
ripple
ripple's
rippled
ripples
rippling
rips
rise
risen
riser
riser's
risers
rises
rising
rising's
risk
risk's
risked
riskier
riskiest
risking
risks
risky
risqu
rite
rite's
rites
ritual
ritual's
ritually
rituals
ritzier
ritziest
ritzy
rival
rival's
rivalled
rivalling
rivalries
rivalry
rivalry's
rivals
rive
river
river's
riverbed
riverbeds
riverfront
riverfronts
rivers
riverside
riversides
rives
rivet
rivet's
riveted
riveting
rivets
rivetted
rivetting
roach
roach's
roaches
road
road's
roadblock
roadblock's
roadblocked
roadblocking
roadblocks
roadhouse
roadhouse's
roadhouses
roadkill
roadrunner
roadrunner's
roadrunners
roads
roadside
roadsides
roadway
roadway's
roadways
roadworthy
roam
roamed
roaming
roams
roar
roared
roaring
roars
roast
roasted
roasting
roasts
rob
robbed
robber
robber's
robberies
robbers
robbery
robbery's
robbing
robe
robe's
robed
robes
robin
robin's
robing
robins
robot
robot's
robotics
robots
robs
robust
robuster
robustest
robustness
robustness's
rock
rock's
rocked
rocker
rocker's
rockers
rocket
rocket's
rocketed
rocketing
rockets
rockier
rockiest
rocking
rocks
rocky
rod
rod's
rode
roded
rodent
rodent's
rodents
rodeo
rodeo's
rodeos
rodes
roding
rods
roe
roe's
roes
rogue
rogue's
rogues
roguish
role
role's
roles
roll
rolled
roller
roller's
rollers
rollerskating
rollick
rollicked
rollicking
rollicks
rolling
rolls
roman
romance
romance's
romanced
romances
romancing
romantic
romantically
romanticise
romanticised
romanticises
romanticising
romantics
romp
romped
romping
romps
roof
roof's
roofed
roofing
roofing's
roofs
rooftop
rooftops
rook
rook's
rooked
rookie
rookie's
rookier
rookies
rookiest
rooking
rooks
room
room's
roomed
roomful
roomful's
roomfuls
roomier
roomiest
rooming
roommate
roommate's
roommates
rooms
roomy
roost
roost's
roosted
rooster
rooster's
roosters
roosting
roosts
root
root's
rooted
rooter
rooting
rootless
roots
rope
rope's
roped
ropes
roping
rosaries
rosary
rosary's
rose
rose's
rosemary
rosemary's
roses
rosier
rosiest
roster
roster's
rostered
rostering
rosters
rostra
rostrum
rostrum's
rostrums
rosy
rot
rotaries
rotary
rotate
rotated
rotates
rotating
rotation
rotation's
rotations
rote
rote's
roted
rotes
roting
rotisserie
rotisserie's
rotisseries
rotor
rotor's
rotors
rots
rotted
rotten
rottener
rottenest
rottens
rotting
rotund
rotunda
rotunda's
rotundas
rotunded
rotunding
rotunds
rouge
rouge's
rouged
rouges
rough
roughage
roughage's
roughed
roughen
roughened
roughening
roughens
rougher
roughest
roughhouse
roughhouse's
roughhoused
roughhouses
roughhousing
roughing
roughly
roughness
roughness's
roughs
roughshod
rouging
roulette
roulette's
round
roundabout
roundabout's
roundabouts
rounded
rounder
roundest
rounding
roundness
roundness's
rounds
roundup
roundup's
roundups
rouse
roused
rouses
rousing
rout
rout's
route
route's
routed
router
router's
routes
routine
routine's
routinely
routines
routing
routing's
routs
rove
roved
roves
roving
roving's
row
row's
rowboat
rowboat's
rowboats
rowdier
rowdies
rowdiest
rowdiness
rowdiness's
rowdy
rowed
rowing
rows
royal
royally
royals
royalties
royalty
royalty's
rs
rub
rubbed
rubber
rubber's
rubberier
rubberiest
rubberneck
rubberneck's
rubbernecked
rubbernecking
rubbernecks
rubbers
rubbery
rubbing
rubbing's
rubbish
rubbish's
rubbished
rubbishes
rubbishing
rubble
rubble's
rubbled
rubbles
rubbling
rubdown
rubdown's
rubdowns
rubella
rubella's
rubied
rubier
rubies
rubiest
rubric
rubric's
rubs
ruby
ruby's
rubying
rucksack
rucksack's
ruckus
ruckus's
ruckuses
rudder
rudder's
rudders
ruddied
ruddier
ruddies
ruddiest
ruddy
ruddying
rude
rudely
rudeness
rudeness's
ruder
rudest
rudiment
rudimentary
rudiments
rue
rued
rueful
rues
ruff
ruff's
ruffed
ruffian
ruffian's
ruffianed
ruffianing
ruffians
ruffing
ruffle
ruffled
ruffles
ruffling
ruffs
rug
rug's
rugby
rugby's
rugged
ruggeder
ruggedest
rugging
rugs
ruin
ruin's
ruined
ruing
ruining
ruinous
ruins
rule
rule's
ruled
ruler
ruler's
rulered
rulering
rulers
rules
ruling
ruling's
rulings
rum
rum's
rumble
rumbled
rumbles
rumbling
ruminate
ruminated
ruminates
ruminating
rummage
rummaged
rummages
rummaging
rummer
rummest
rummy
rummy's
rumour
rumour's
rumoured
rumouring
rumours
rump
rump's
rumped
rumping
rumple
rumpled
rumples
rumpling
rumps
rums
run
runaround
runarounds
runaway
runaways
rundown
rundown's
rundowns
rune
runes
rung
rung's
rungs
runner
runner's
runners
runnier
runniest
running
runny
runs
runt
runt's
runts
runway
runway's
runways
rupture
rupture's
ruptured
ruptures
rupturing
rural
ruse
ruse's
ruses
rush
rushed
rushes
rushing
rushing's
rust
rust's
rusted
rustic
rustics
rustier
rustiest
rusting
rustle
rustled
rustler
rustler's
rustlers
rustles
rustling
rustproof
rustproofed
rustproofing
rustproofs
rusts
rusty
rut
rut's
ruthless
ruthlessly
ruthlessness
ruthlessness's
ruts
rutted
rutting
rye
rye's
s
sabbatical
sabbaticals
sabotage
sabotage's
sabotaged
sabotages
sabotaging
saboteur
saboteur's
saboteurs
sabre
sabre's
sabres
sac
sac's
saccharin
saccharin's
sack
sack's
sacked
sacking
sacks
sacrament
sacrament's
sacramented
sacramenting
sacraments
sacred
sacrifice
sacrifice's
sacrificed
sacrifices
sacrificial
sacrificing
sacrilege
sacrilege's
sacrileges
sacrilegious
sacrosanct
sacs
sad
sadden
saddened
saddening
saddens
sadder
saddest
saddle
saddle's
saddled
saddles
saddling
sades
sadism
sadism's
sadist
sadist's
sadistic
sadistically
sadists
sadly
sadness
sadness's
safari
safari's
safaried
safariing
safaris
safe
safeguard
safeguard's
safeguarded
safeguarding
safeguards
safekeeping
safekeeping's
safekeepings
safely
safer
safes
safest
safetied
safeties
safety
safety's
safetying
saffron
saffron's
saffrons
sag
saga
saga's
sagas
sage
sage's
sagebrush
sagebrush's
sager
sages
sagest
sagged
sagger
sagging
sags
said
sail
sail's
sailboard
sailboarded
sailboarding
sailboards
sailboat
sailboat's
sailboats
sailed
sailing
sailing's
sailor
sailor's
sailors
sails
saint
saint's
saintlier
saintliest
saintly
saints
sake
sake's
salad
salad's
salads
salami
salami's
salamis
salaried
salaries
salary
salary's
salarying
sale
sale's
saleable
sales
salesclerk
salesclerk's
salesclerks
salesman
salesman's
salesmen
salespeople
salesperson
salesperson's
saleswoman
saleswomen
salient
salients
saliva
saliva's
salivate
salivated
salivates
salivating
sallow
sallower
sallowest
sally
sally's
salmon
salmon's
salmonella
salmonella's
salmonellae
salmonellas
salmons
salon
salon's
salons
saloon
saloon's
saloons
salsa
salsas
salt
salt's
salted
salter
saltest
saltier
salties
saltiest
salting
salts
saltwater
salty
salutation
salutation's
salutations
salute
saluted
salutes
saluting
salvage
salvage's
salvaged
salvages
salvaging
salvation
salvation's
salve
salve's
salved
salves
salving
same
sameness
sameness's
sames
sample
sample's
sampled
sampler
sampler's
samples
sampling
sampling's
sanatoria
sanatorium
sanatorium's
sanatoriums
sanctified
sanctifies
sanctify
sanctifying
sanctimonious
sanction
sanction's
sanctioned
sanctioning
sanctions
sanctity
sanctity's
sanctuaries
sanctuary
sanctuary's
sand
sand's
sandal
sandal's
sandals
sandbag
sandbag's
sandbagged
sandbagging
sandbags
sandblast
sandblast's
sandblasted
sandblasting
sandblasts
sandcastle
sandcastles
sanded
sandier
sandiest
sanding
sandman
sandman's
sandmen
sandpaper
sandpaper's
sandpapered
sandpapering
sandpapers
sands
sandstone
sandstone's
sandstorm
sandstorm's
sandstorms
sandwich
sandwich's
sandwiched
sandwiches
sandwiching
sandy
sane
saned
saner
sanes
sanest
sang
sangs
saning
sanitaria
sanitaries
sanitarium
sanitarium's
sanitariums
sanitary
sanitation
sanitation's
sanitise
sanitised
sanitises
sanitising
sanity
sanity's
sank
sanserif
sap
sap's
sapling
sapling's
sapped
sapphire
sapphire's
sapphires
sapping
saps
sarcasm
sarcasm's
sarcasms
sarcastic
sarcastically
sardine
sardine's
sardined
sardines
sardining
sardonic
sari
sari's
saris
sash
sash's
sashes
sass
sass's
sassed
sasses
sassier
sassiest
sassing
sassy
sat
satanic
satanism
satchel
satchel's
satchels
satellite
satellite's
satellited
satellites
satelliting
satin
satin's
satined
satining
satins
satiny
satire
satire's
satires
satirical
satirically
satirise
satirised
satirises
satirising
satirist
satirist's
satirists
satisfaction
satisfaction's
satisfactions
satisfactorily
satisfactory
satisfied
satisfies
satisfy
satisfying
saturate
saturated
saturates
saturating
saturation
saturation's
sauce
sauce's
sauced
saucepan
saucepan's
saucepans
saucer
saucer's
saucers
sauces
saucier
sauciest
saucing
saucy
sauerkraut
sauerkraut's
sauna
sauna's
saunaed
saunaing
saunas
saunter
sauntered
sauntering
saunters
sausage
sausage's
sausages
sauted
saut
sauted
sauting
sauts
savage
savaged
savagely
savager
savageries
savagery
savagery's
savages
savagest
savaging
save
saved
saver
saver's
savers
saves
saving
savings
saviour
saviour's
saviours
savour
savour's
savoured
savourier
savouries
savouriest
savouring
savours
savoury
savoury's
savvied
savvier
savvies
savviest
savvy
savvying
saw
saw's
sawdust
sawdust's
sawdusted
sawdusting
sawdusts
sawed
sawing
sawn
saws
sax
sax's
saxes
saxophone
saxophone's
saxophones
say
saying
saying's
sayings
says
says's
scab
scab's
scabbed
scabbing
scabs
scad
scads
scaffold
scaffold's
scaffolding
scaffolding's
scaffolds
scalar
scalar's
scalars
scald
scalded
scalding
scaldings
scalds
scale
scale's
scaled
scales
scalier
scaliest
scaling
scallop
scallop's
scalloped
scalloping
scallops
scalp
scalp's
scalped
scalpel
scalpel's
scalpels
scalper
scalper's
scalpers
scalping
scalps
scaly
scam
scammed
scamming
scamper
scampered
scampering
scampers
scams
scan
scandal
scandal's
scandalise
scandalised
scandalises
scandalising
scandalous
scandals
scanned
scanner
scanner's
scanners
scanning
scans
scant
scanted
scanter
scantest
scantier
scanties
scantiest
scanting
scants
scanty
scapegoat
scapegoat's
scapegoated
scapegoating
scapegoats
scar
scar's
scarce
scarcely
scarcer
scarcest
scarcity
scarcity's
scare
scarecrow
scarecrow's
scarecrows
scared
scares
scarf
scarf's
scarfed
scarfing
scarfs
scarier
scariest
scaring
scarlet
scarlet's
scarleted
scarleting
scarlets
scarred
scarring
scars
scarves
scarves's
scary
scathing
scatter
scatterbrain
scatterbrain's
scatterbrained
scatterbrains
scattered
scattering
scattering's
scatters
scavenge
scavenged
scavenger
scavenger's
scavengers
scavenges
scavenging
scenario
scenario's
scenarios
scene
scene's
scened
scenery
scenery's
scenes
scenic
scening
scent
scent's
scented
scenting
scents
sceptic
sceptic's
sceptical
scepticism
scepticism's
sceptics
sceptre
sceptres
schedule
schedule's
scheduled
scheduler
schedules
scheduling
scheme
scheme's
schemed
schemer
schemer's
schemers
schemes
scheming
schism
schism's
schisms
schizophrenia
schizophrenia's
schizophrenic
schizophrenics
schlep
schlepp
schlepped
schlepping
schlepps
schleps
schlock
schlock's
schlockier
schlockiest
schlocky
schmaltz
schmaltz's
schmaltzier
schmaltziest
schmaltzy
schmooze
schmoozed
schmoozes
schmoozing
schmuck
schmuck's
schmucks
scholar
scholar's
scholarly
scholars
scholarship
scholarship's
scholarships
scholastic
school
school's
schoolboy
schoolboy's
schoolboys
schoolchild
schoolchild's
schoolchildren
schooled
schoolgirl
schoolgirl's
schoolgirls
schooling
schooling's
schools
schoolteacher
schoolteacher's
schoolteachers
schooner
schooner's
schooners
science
science's
sciences
scientific
scientifically
scientist
scientist's
scientists
scintillate
scintillated
scintillates
scintillating
scissor
scissors
scoff
scoffed
scoffing
scoffs
scold
scolded
scolding
scoldings
scolds
scoop
scoop's
scooped
scooping
scoops
scoot
scooted
scooter
scooter's
scooters
scooting
scoots
scope
scope's
scoped
scopes
scoping
scorch
scorched
scorches
scorching
score
score's
scoreboard
scoreboard's
scoreboards
scorecard
scorecard's
scorecards
scored
scored's
scorer
scores
scoring
scorn
scorn's
scorned
scornful
scornfully
scorning
scorns
scorpion
scorpion's
scorpions
scotch
scotch's
scotched
scotches
scotching
scotchs
scoundrel
scoundrel's
scoundrels
scour
scoured
scourge
scourge's
scourged
scourges
scourging
scouring
scours
scout
scout's
scouted
scouting
scouts
scowl
scowled
scowling
scowls
scrabble
scrabbled
scrabbles
scrabbling
scragglier
scraggliest
scraggly
scram
scramble
scrambled
scrambles
scrambling
scrammed
scramming
scrams
scrap
scrap's
scrapbook
scrapbook's
scrapbooks
scrape
scraped
scrapes
scraping
scrapped
scrappier
scrappiest
scrapping
scrappy
scraps
scratch
scratched
scratches
scratches's
scratchier
scratchiest
scratching
scratchy
scrawl
scrawled
scrawling
scrawls
scrawnier
scrawniest
scrawny
scream
screamed
screaming
screams
screech
screech's
screeched
screeches
screeching
screen
screen's
screened
screening
screening's
screenplay
screenplay's
screenplays
screens
screw
screw's
screwball
screwball's
screwballs
screwdriver
screwdriver's
screwdrivers
screwed
screwier
screwiest
screwing
screws
screwy
scribble
scribbled
scribbles
scribbling
scribe
scribe's
scribes
scrimp
scrimped
scrimping
scrimps
script
script's
scripted
scripting
scripts
scripture
scripture's
scriptures
scriptwriter
scriptwriters
scroll
scroll's
scrolled
scrolling
scrolls
scrooge
scrooges
scrounge
scrounged
scrounges
scrounging
scrub
scrubbed
scrubbing
scrubs
scruff
scruff's
scruffier
scruffiest
scruffs
scruffy
scruple
scruple's
scrupled
scruples
scrupling
scrupulous
scrupulously
scrutinise
scrutinised
scrutinises
scrutinising
scrutiny
scrutiny's
scuff
scuffed
scuffing
scuffle
scuffled
scuffles
scuffling
scuffs
sculptor
sculptor's
sculptors
sculpture
sculpture's
sculptured
sculptures
sculpturing
scum
scum's
scummed
scumming
scums
scurried
scurries
scurrilous
scurry
scurrying
scuttle
scuttle's
scuttled
scuttles
scuttling
scythe
scythe's
scythed
scythes
scything
sea
sea's
seafaring
seafood
seafood's
seal
seal's
sealed
sealing
seals
seam
seam's
seaman
seaman's
seamed
seamen
seaming
seamless
seams
seamstress
seamstress's
seamstresses
seaport
seaport's
seaports
sear
search
searched
searches
searching
searchlight
searchlight's
searchlights
seared
searing
sears
seas
seashell
seashell's
seashells
seashore
seashore's
seashores
seasick
seasickness
seasickness's
seaside
seaside's
seasides
season
season's
seasonable
seasonal
seasoned
seasoning
seasoning's
seasonings
seasons
seat
seat's
seated
seating
seating's
seats
seaweed
seaweed's
secede
seceded
secedes
seceding
secession
secession's
seclude
secluded
secludes
secluding
seclusion
seclusion's
second
secondaries
secondarily
secondary
seconded
secondhand
seconding
secondly
seconds
secrecy
secrecy's
secret
secretarial
secretaries
secretary
secretary's
secrete
secreted
secreter
secretes
secretest
secreting
secretion
secretion's
secretions
secretive
secretively
secretly
secrets
secs
sect
sect's
section
section's
sectioned
sectioning
sections
sector
sector's
sectors
sects
secular
secure
secured
securely
securer
secures
securest
securing
securities
security
security's
sedan
sedan's
sedans
sedate
sedated
sedater
sedates
sedatest
sedating
sedation
sedation's
sedative
sedatives
sedentary
sediment
sediment's
sedimentary
sediments
seduce
seduced
seduces
seducing
seduction
seduction's
seductions
seductive
see
seed
seed's
seeded
seedier
seediest
seeding
seedless
seedling
seedling's
seeds
seedy
seeing
seeing's
seek
seeking
seeks
seem
seemed
seeming
seemingly
seems
seen
seep
seepage
seepage's
seeped
seeping
seeps
seer
sees
seesaw
seesaw's
seesawed
seesawing
seesaws
seethe
seethed
seethes
seething
seethings
segment
segment's
segmentation
segmentation's
segmented
segmenting
segments
segregate
segregated
segregates
segregating
segregation
segregation's
seize
seized
seizes
seizing
seizure
seizure's
seizures
seldom
select
selected
selecting
selection
selection's
selections
selective
selectively
selector
selector's
selectors
selects
self
self's
selfish
selfishly
selfishness
selfless
sell
seller
seller's
sellers
selling
sellout
sellout's
sellouts
sells
selves
selves's
semantic
semantically
semantics
semantics's
semblance
semblance's
semblances
semen
semen's
semester
semester's
semesters
semicircle
semicircle's
semicircles
semicolon
semicolon's
semicolons
semiconductor
semiconductor's
semiconductors
semifinal
semifinal's
semifinalist
semifinalist's
semifinalists
semifinals
seminal
seminar
seminar's
seminaries
seminars
seminary
seminary's
semiprecious
senate
senate's
senates
senator
senator's
senatorial
senators
send
sender
sender's
sending
sends
senile
senility
senility's
senior
seniority
seniority's
seniors
sensation
sensation's
sensational
sensationalism
sensationalism's
sensationally
sensations
sense
sense's
sensed
senseless
senses
sensibilities
sensibility
sensibility's
sensible
sensibler
sensibles
sensiblest
sensibly
sensing
sensitive
sensitively
sensitives
sensitivities
sensitivity
sensitivity's
sensor
sensor's
sensors
sensory
sensual
sensuality
sensuality's
sensuous
sent
sentence
sentence's
sentenced
sentences
sentencing
sentience
sentience's
sentient
sentiment
sentiment's
sentimental
sentimentality
sentimentality's
sentiments
sentries
sentry
sentry's
separable
separate
separated
separately
separates
separates's
separating
separation
separation's
separations
separator
separator's
separators
sepulchre
sepulchre's
sepulchred
sepulchres
sepulchring
sequel
sequel's
sequels
sequence
sequence's
sequenced
sequencer
sequencer's
sequences
sequencing
sequential
sequentially
sequin
sequin's
sequining
sequinned
sequins
sequoia
sequoia's
sequoias
sera
serenade
serenade's
serenaded
serenades
serenading
serene
serened
serenely
serener
serenes
serenest
serening
serenity
serenity's
sergeant
sergeant's
sergeants
serial
serial's
serials
series
series's
serious
seriously
seriousness
seriousness's
sermon
sermon's
sermoned
sermoning
sermons
serpent
serpent's
serpented
serpenting
serpents
serrated
serum
serum's
serums
servant
servant's
servanted
servanting
servants
serve
served
server
server's
servers
serves
service
service's
serviceable
serviced
serviceman
serviceman's
servicemen
services
servicewoman
servicewomen
servicing
serviette
serviette's
serviettes
servile
serviles
serving
serving's
servings
servitude
servitude's
session
session's
sessions
set
setback
setbacks
sets
settable
setter
setter's
setters
setting
setting's
settings
settle
settled
settlement
settlement's
settlements
settler
settler's
settlers
settles
settling
setup
setup's
setups
seven
seven's
sevens
seventeen
seventeen's
seventeens
seventeenth
seventeenths
seventh
sevenths
seventies
seventieth
seventieths
seventy
seventy's
sever
several
severance
severance's
severances
severe
severed
severely
severer
severest
severing
severity
severity's
severs
sew
sewage
sewage's
sewed
sewer
sewer's
sewers
sewing
sewing's
sewn
sews
sex
sex's
sexed
sexes
sexier
sexiest
sexing
sexism
sexism's
sexist
sexist's
sexists
sexual
sexuality
sexuality's
sexually
sexy
sh
shabbier
shabbiest
shabbily
shabby
shack
shack's
shackle
shackle's
shackled
shackles
shackling
shacks
shade
shade's
shaded
shades
shadier
shadiest
shading
shading's
shadings
shadow
shadow's
shadowed
shadowier
shadowiest
shadowing
shadows
shadowy
shady
shaft
shaft's
shafted
shafting
shafts
shaggier
shaggiest
shaggy
shake
shakedown
shakedowns
shaken
shakes
shakeup
shakeups
shakier
shakiest
shakily
shaking
shaking's
shaky
shall
shallow
shallower
shallowest
shallowness
shallowness's
shallows
sham
sham's
shamble
shambles
shambles's
shame
shame's
shamed
shameful
shamefully
shameless
shamelessly
shames
shaming
shammed
shamming
shampoo
shampoo's
shampooed
shampooing
shampoos
shamrock
shamrock's
shamrocks
shams
shanties
shanty
shanty's
shantytown
shantytown's
shantytowns
shape
shape's
shaped
shapelier
shapeliest
shapely
shapes
shaping
share
share's
shared
shareholder
shareholder's
shareholders
shares
sharing
shark
shark's
sharked
sharking
sharks
sharp
sharped
sharpen
sharpened
sharpener
sharpeners
sharpening
sharpens
sharper
sharper's
sharpest
sharping
sharply
sharpness
sharpness's
sharps
shatter
shattered
shattering
shatters
shave
shaved
shaven
shaver
shaver's
shavers
shaves
shaving
shaving's
shawl
shawl's
shawled
shawling
shawls
she
she'd
she'll
she's
sheaf
sheaf's
shear
sheared
shearing
shears
sheath
sheath's
sheathe
sheathed
sheathes
sheathing
sheaths
sheave
sheaves
sheaves's
shed
shed's
shedding
sheds
sheen
sheen's
sheep
sheep's
sheepish
sheepishly
sheer
sheered
sheerer
sheerest
sheering
sheers
sheet
sheet's
sheets
sheik
sheik's
sheikh
sheikhs
sheiks
shelf
shelf's
shell
shell's
shelled
sheller
shellfish
shellfish's
shellfishes
shelling
shells
shelter
shelter's
sheltered
sheltering
shelters
shelve
shelved
shelves
shelves's
shelving
shelving's
shenanigan
shenanigans
shepherd
shepherd's
shepherded
shepherding
shepherds
sherbet
sherbet's
sherbets
sheriff
sheriff's
sheriffs
sherries
sherry
sherry's
shes
shied
shield
shield's
shielded
shielding
shields
shies
shift
shifted
shiftier
shiftiest
shifting
shiftless
shifts
shifty
shimmer
shimmered
shimmering
shimmers
shin
shin's
shine
shined
shines
shingle
shingle's
shingled
shingles
shingling
shinier
shiniest
shining
shinned
shinnied
shinnies
shinning
shinny
shinny's
shinnying
shins
shiny
ship
ship's
shipload
shipload's
shiploads
shipment
shipment's
shipments
shipped
shipping
shipping's
ships
shipshape
shipwreck
shipwreck's
shipwrecked
shipwrecking
shipwrecks
shipyard
shipyard's
shipyards
shire
shire's
shirk
shirked
shirking
shirks
shirt
shirt's
shirted
shirting
shirts
shirtsleeve
shirtsleeve's
shirtsleeves
shit
shits
shittier
shittiest
shitting
shitty
shiver
shivered
shivering
shivers
shoal
shoal's
shoaled
shoaling
shoals
shock
shocked
shocking
shocks
shod
shodden
shoddier
shoddiest
shoddily
shoddy
shoe
shoe's
shoed
shoeing
shoelace
shoelace's
shoelaces
shoes
shoestring
shoestring's
shoestrings
shone
shoo
shooed
shooing
shook
shook's
shoon
shoos
shoot
shooting
shootings
shoots
shop
shop's
shopkeeper
shopkeeper's
shopkeepers
shoplift
shoplifted
shoplifter
shoplifter's
shoplifters
shoplifting
shoplifting's
shoplifts
shopped
shopper
shopper's
shoppers
shopping
shopping's
shops
shore
shore's
shored
shores
shoring
shorn
short
shortage
shortage's
shortages
shortchange
shortchanged
shortchanges
shortchanging
shortcoming
shortcoming's
shortcomings
shortcut
shortcut's
shortcuts
shortcutting
shorted
shorten
shortened
shortening
shortening's
shortenings
shortens
shorter
shortest
shortfall
shortfall's
shortfalls
shorthand
shorthand's
shorting
shortlist
shortly
shortness
shortness's
shorts
shortsighted
shortwave
shortwave's
shortwaves
shot
shot's
shotgun
shotgun's
shotgunned
shotgunning
shotguns
shots
should
shoulder
shoulder's
shouldered
shouldering
shoulders
shouldest
shouldn't
shout
shout's
shouted
shouting
shouts
shove
shoved
shovel
shovel's
shovelled
shovelling
shovels
shoves
shoving
show
showbiz
showcase
showcase's
showcased
showcases
showcasing
showdown
showdown's
showdowns
showed
shower
shower's
showered
showering
showers
showier
showiest
showing
showing's
showings
showman
showman's
showmanship
showmanship's
showmen
shown
showpiece
showpiece's
showpieces
showroom
showroom's
showrooms
shows
showy
shrank
shrapnel
shrapnel's
shred
shred's
shredded
shredding
shreds
shrew
shrew's
shrewd
shrewder
shrewdest
shrewdly
shrewdness
shrewdness's
shrewed
shrewing
shrews
shriek
shriek's
shrieked
shrieking
shrieks
shrill
shrilled
shriller
shrillest
shrilling
shrills
shrimp
shrimp's
shrimped
shrimping
shrimps
shrine
shrine's
shrines
shrink
shrinkage
shrinkage's
shrinking
shrinks
shrivel
shrivelled
shrivelling
shrivels
shroud
shroud's
shrouded
shrouding
shrouds
shrub
shrub's
shrubbed
shrubberies
shrubbery
shrubbery's
shrubbing
shrubs
shrug
shrugged
shrugging
shrugs
shrunk
shrunken
shuck
shuck's
shucked
shucking
shucks
shuckses
shudder
shuddered
shuddering
shudders
shuffle
shuffled
shuffles
shuffling
shun
shunned
shunning
shuns
shunt
shunted
shunting
shunts
shush
shushed
shushes
shushing
shut
shutdown
shutdown's
shutdowns
shuteye
shuteye's
shuts
shutter
shutter's
shuttered
shuttering
shutters
shutting
shuttle
shuttle's
shuttled
shuttles
shuttling
shy
shyer
shyest
shying
shyly
shyness
shyness's
shyster
shyster's
shysters
sibling
sibling's
siblings
sic
sices
sick
sicked
sicken
sickened
sickening
sickenings
sickens
sicker
sickest
sicking
sickle
sickle's
sickled
sickles
sicklier
sickliest
sickling
sickly
sickness
sickness's
sicknesses
sicks
sics
side
side's
sideburns
sided
sidekick
sidekick's
sidekicks
sideline
sideline's
sidelined
sidelines
sidelining
sidelong
sides
sideshow
sideshow's
sideshows
sidestep
sidestepped
sidestepping
sidesteps
sidetrack
sidetracked
sidetracking
sidetracks
sidewalk
sidewalk's
sidewalks
sideways
siding
siding's
sidings
sidle
sidled
sidles
sidling
siege
siege's
sieges
sierra
sierra's
siesta
siesta's
siestas
sieve
sieve's
sieved
sieves
sieving
sift
sifted
sifting
sifts
sigh
sighed
sighing
sighs
sight
sight's
sighted
sighting
sightings
sightless
sightread
sights
sightseeing
sightseer
sightseers
sigma
sigma's
sign
sign's
signal
signal's
signalled
signalling
signals
signatories
signatory
signatory's
signature
signature's
signatures
signed
signer
significance
significance's
significant
significantly
signified
signifies
signify
signifying
signing
signings
signpost
signpost's
signposted
signposting
signposts
signs
silence
silence's
silenced
silencer
silencer's
silencers
silences
silencing
silent
silenter
silentest
silently
silents
silhouette
silhouette's
silhouetted
silhouettes
silhouetting
silicon
silicon's
silk
silk's
silken
silkened
silkening
silkens
silkier
silkies
silkiest
silks
silky
sill
sill's
sillier
sillies
silliest
silliness
silliness's
sills
silly
silo
silo's
silos
silt
silt's
silted
silting
silts
silver
silver's
silvered
silverier
silveriest
silvering
silvers
silversmith
silversmith's
silversmiths
silverware
silverware's
silvery
similar
similarities
similarity
similarity's
similarly
simile
simile's
similes
simmer
simmered
simmering
simmers
simper
simpered
simpering
simpers
simple
simpled
simpler
simples
simplest
simplex
simplicity
simplicity's
simplification
simplifications
simplified
simplifies
simplify
simplifying
simpling
simplistic
simply
simulate
simulated
simulates
simulating
simulation
simulation's
simulations
simulator
simulator's
simulators
simultaneous
simultaneously
sin
sin's
since
sincere
sincerely
sincerer
sincerest
sincerity
sincerity's
sine
sine's
sinew
sinew's
sinews
sinewy
sinful
sing
singe
singed
singeing
singer
singer's
singers
singes
singing
single
singled
singles
singling
singly
sings
singsong
singsong's
singsonged
singsonging
singsongs
singular
singularity
singularity's
singularly
singulars
sinister
sink
sinking
sinking's
sinks
sinned
sinner
sinner's
sinners
sinning
sins
sinus
sinus's
sinuses
sip
sipped
sipping
sips
sir
sir's
sire
sire's
sired
siren
siren's
sirens
sires
siring
sirloin
sirloin's
sirloins
sirred
sirring
sirs
sissier
sissies
sissiest
sissy
sissy's
sister
sister's
sistered
sisterhood
sisterhood's
sisterhoods
sistering
sisterly
sisters
sit
sitcom
sitcom's
sitcoms
site
site's
sited
sites
siting
sits
sitter
sitter's
sitters
sitting
sitting's
sittings
situate
situated
situates
situating
situation
situation's
situations
six
six's
sixes
sixpence
sixpence's
sixpences
sixteen
sixteen's
sixteens
sixteenth
sixteenths
sixth
sixths
sixties
sixtieth
sixtieths
sixty
sixty's
sizable
size
size's
sizeable
sized
sizer
sizes
sizing
sizzle
sizzled
sizzles
sizzling
skate
skate's
skateboard
skateboard's
skateboarded
skateboarder
skateboarders
skateboarding
skateboards
skated
skater
skater's
skaters
skates
skating
skein
skein's
skeined
skeining
skeins
skeleton
skeleton's
skeletons
skeptically
sketch
sketch's
sketched
sketches
sketchier
sketchiest
sketching
sketchy
skew
skewed
skewer
skewer's
skewered
skewering
skewers
skewing
skews
ski
ski's
skid
skidded
skidding
skids
skied
skier
skiers
skies
skiing
skiing's
skill
skill's
skilled
skillet
skillet's
skillets
skillful
skillfully
skills
skim
skimmed
skimming
skimp
skimped
skimpier
skimpiest
skimping
skimps
skimpy
skims
skin
skin's
skinflint
skinflint's
skinflints
skinhead
skinhead's
skinheads
skinned
skinnier
skinniest
skinning
skinny
skins
skintight
skip
skipped
skipper
skipper's
skippered
skippering
skippers
skipping
skips
skirmish
skirmish's
skirmished
skirmishes
skirmishing
skirt
skirt's
skirted
skirting
skirts
skis
skit
skit's
skited
skiting
skits
skittish
skulk
skulked
skulking
skulks
skull
skull's
skullcap
skullcap's
skullcaps
skulls
skunk
skunk's
skunked
skunking
skunks
sky
sky's
skydive
skydived
skydiver
skydiver's
skydivers
skydives
skydiving
skydiving's
skydove
skyed
skying
skylight
skylight's
skylights
skyline
skyline's
skylines
skyrocket
skyrocket's
skyrocketed
skyrocketing
skyrockets
skyscraper
skyscraper's
skyscrapers
slab
slab's
slabbed
slabbing
slabs
slack
slacked
slacken
slackened
slackening
slackens
slacker
slacker's
slackers
slackest
slacking
slacks
slag
slag's
slain
slake
slaked
slakes
slaking
slalom
slalom's
slalomed
slaloming
slaloms
slam
slammed
slamming
slams
slander
slander's
slandered
slandering
slanders
slang
slang's
slant
slanted
slanting
slants
slap
slap's
slapdash
slapdashes
slapped
slapping
slaps
slapstick
slapstick's
slash
slashed
slashes
slashing
slat
slat's
slate
slate's
slated
slates
slather
slather's
slathered
slathering
slathers
slating
slats
slaughter
slaughter's
slaughtered
slaughterhouse
slaughterhouse's
slaughterhouses
slaughtering
slaughters
slave
slave's
slaved
slavery
slavery's
slaves
slaving
slavish
slay
slaying
slayings
slays
sleazier
sleaziest
sleazy
sled
sled's
sledded
sledding
sledgehammer
sledgehammer's
sledgehammered
sledgehammering
sledgehammers
sleds
sleek
sleeked
sleeker
sleekest
sleeking
sleeks
sleep
sleep's
sleeper
sleeper's
sleepers
sleepier
sleepiest
sleepily
sleeping
sleeping's
sleepless
sleeplessness
sleeplessness's
sleeps
sleepwalk
sleepwalked
sleepwalking
sleepwalks
sleepy
sleepyhead
sleepyhead's
sleepyheads
sleet
sleet's
sleeted
sleeting
sleets
sleeve
sleeve's
sleeveless
sleeves
sleigh
sleigh's
sleighed
sleighing
sleighs
slender
slenderer
slenderest
slept
sleuth
sleuth's
sleuths
slew
slewed
slewing
slews
slice
slice's
sliced
slices
slicing
slick
slicked
slicker
slickest
slicking
slicks
slid
slide
slided
slides
sliding
slier
sliest
slight
slighted
slighter
slightest
slighting
slightly
slights
slim
slime
slime's
slimier
slimiest
slimmed
slimmer
slimmest
slimming
slims
slimy
sling
sling's
slinging
slings
slingshot
slingshot's
slingshots
slink
slinked
slinking
slinks
slip
slipped
slipper
slipper's
slipperier
slipperiest
slippers
slippery
slipping
slips
slipshod
slit
slither
slithered
slithering
slithers
slits
slitted
slitter
slitting
sliver
sliver's
slivered
slivering
slivers
slob
slob's
slobber
slobbered
slobbering
slobbers
slobs
slog
slogan
slogan's
slogans
slogged
slogging
slogs
slop
slope
sloped
slopes
sloping
slopped
sloppier
sloppiest
sloppily
slopping
sloppy
slops
slosh
slosh's
sloshed
sloshes
sloshing
slot
slot's
sloth
sloth's
slothed
slothful
slothing
sloths
slots
slotted
slotting
slouch
slouched
slouches
slouching
slovenlier
slovenliest
slovenly
slow
slowdown
slowdown's
slowdowns
slowed
slower
slowest
slowing
slowly
slowness
slowness's
slowpoke
slowpoke's
slowpokes
slows
sludge
sludge's
sludged
sludges
sludging
slug
slug's
slugged
slugging
sluggish
slugs
sluice
sluice's
sluiced
sluices
sluicing
slum
slum's
slumber
slumbered
slumbering
slumbers
slummed
slummer
slumming
slump
slumped
slumping
slumps
slums
slung
slunk
slur
slurp
slurped
slurping
slurps
slurred
slurring
slurs
slush
slush's
slushier
slushiest
slushy
slut
slut's
sluts
sly
slyer
slyest
slyly
slyness
slyness's
smack
smack's
smacked
smacking
smacks
small
smalled
smaller
smallest
smalling
smallish
smallpox
smallpox's
smalls
smart
smarted
smarter
smartest
smarting
smartly
smarts
smash
smashed
smashes
smashing
smattering
smattering's
smatterings
smear
smeared
smearing
smears
smell
smelled
smellier
smelliest
smelling
smells
smelly
smelt
smelted
smelting
smelts
smidgen
smidgen's
smidgens
smile
smile's
smiled
smiles
smiling
smirk
smirk's
smirked
smirking
smirks
smit
smite
smites
smith
smith's
smithereens
smiths
smiting
smitten
smock
smock's
smocked
smocking
smocks
smog
smog's
smoggier
smoggiest
smoggy
smoke
smoke's
smoked
smoker
smoker's
smokers
smokes
smokestack
smokestack's
smokestacks
smokier
smokies
smokiest
smoking
smoking's
smoky
smoldered
smolders
smooch
smooched
smooches
smooching
smooth
smoothed
smoother
smoothes
smoothest
smoothing
smoothly
smoothness
smoothness's
smooths
smote
smother
smothered
smothering
smothers
smoulder
smouldered
smouldering
smoulders
smudge
smudged
smudges
smudging
smug
smugged
smugger
smuggest
smugging
smuggle
smuggled
smuggler
smuggler's
smugglers
smuggles
smuggling
smugly
smugness
smugness's
smugs
smut
smut's
smuts
smuttier
smuttiest
smutty
smrgsbord
smrgsbord's
smrgsbords
snack
snack's
snacked
snacking
snacks
snafu
snafu's
snafus
snag
snag's
snagged
snagging
snags
snail
snail's
snailed
snailing
snails
snake
snake's
snaked
snakes
snaking
snap
snapped
snappier
snappiest
snapping
snappy
snaps
snapshot
snapshot's
snapshots
snare
snare's
snared
snares
snaring
snarl
snarled
snarling
snarls
snatch
snatched
snatches
snatching
snazzier
snazziest
snazzy
sneak
sneaked
sneaker
sneaker's
sneakers
sneakier
sneakiest
sneaking
sneaks
sneaky
sneer
sneer's
sneered
sneering
sneers
sneeze
sneezed
sneezes
sneezing
snicker
snicker's
snickered
snickering
snickers
snide
snider
snides
snidest
sniff
sniffed
sniffing
sniffle
sniffled
sniffles
sniffles's
sniffling
sniffs
snigger
snigger's
snip
snipe
snipe's
sniped
sniper
sniper's
snipers
snipes
sniping
snipped
snippet
snippet's
snippets
snipping
snips
snit
snit's
snitch
snitched
snitches
snitching
snits
snob
snob's
snobbery
snobbery's
snobbier
snobbiest
snobbish
snobby
snobs
snooker
snooker's
snoop
snooped
snooping
snoops
snootier
snootiest
snooty
snooze
snoozed
snoozes
snoozing
snore
snored
snores
snoring
snorkel
snorkel's
snorkeled
snorkeling
snorkelled
snorkelling
snorkels
snort
snorted
snorting
snorts
snot
snot's
snots
snotted
snottier
snottiest
snotting
snotty
snout
snout's
snouted
snouting
snouts
snow
snow's
snowball
snowball's
snowballed
snowballing
snowballs
snowboard
snowboarded
snowboarding
snowboards
snowbound
snowdrift
snowdrift's
snowdrifts
snowed
snowfall
snowfall's
snowfalls
snowflake
snowflake's
snowflakes
snowier
snowiest
snowing
snowman
snowman's
snowmen
snowmobile
snowmobile's
snowmobiled
snowmobiles
snowmobiling
snowplow
snowplow's
snowplowed
snowplowing
snowplows
snows
snowstorm
snowstorm's
snowstorms
snowy
snub
snubbed
snubbing
snubs
snuck
snuff
snuffed
snuffer
snuffing
snuffs
snug
snugged
snugger
snuggest
snugging
snuggle
snuggled
snuggles
snuggling
snugly
snugs
so
soak
soaked
soaking
soakings
soaks
soap
soap's
soaped
soapier
soapiest
soaping
soaps
soapy
soar
soared
soaring
soars
sob
sobbed
sobbing
sober
sobered
soberer
soberest
sobering
sobers
sobriety
sobriety's
sobs
soccer
soccer's
sociable
sociables
social
socialise
socialised
socialises
socialising
socialism
socialism's
socialist
socialist's
socialists
socialite
socialite's
socialites
socially
socials
societies
society
society's
socioeconomic
sociological
sociological's
sociologist
sociologist's
sociologists
sociology
sociology's
sociopath
sociopath's
sociopaths
sock
sock's
socked
socket
socket's
sockets
socking
socks
sod
sod's
soda
soda's
sodas
sodded
sodden
sodding
sodium
sodium's
sodomy
sodomy's
sods
sofa
sofa's
sofas
soft
softball
softball's
softballs
soften
softened
softening
softens
softer
softest
softhearted
softie
softies
softly
softness
softness's
software
software's
softy
softy's
soggier
soggiest
soggy
soil
soil's
soiled
soiling
soils
sojourn
sojourn's
sojourned
sojourning
sojourns
solace
solace's
solaced
solaces
solacing
solar
sold
solder
solder's
soldered
soldering
solders
soldier
soldier's
soldiered
soldiering
soldiers
sole
soled
solely
solemn
solemner
solemnest
solemnity
solemnity's
solemnly
soles
soli
solicit
solicited
soliciting
solicitor
solicitor's
solicitors
solicitous
solicits
solid
solidarity
solidarity's
solider
solidest
solidified
solidifies
solidify
solidifying
solidity
solidly
solids
soliloquies
soliloquy
soliloquy's
soling
solitaire
solitaire's
solitaires
solitaries
solitary
solitude
solitude's
solo
solo's
soloed
soloing
soloist
soloist's
soloists
solos
soluble
solubles
solution
solution's
solutions
solvable
solve
solved
solvent
solvents
solves
solving
somber
sombrely
some
somebodies
somebody
someday
somehow
someone
someones
someplace
somersault
somersault's
somersaulted
somersaulting
somersaults
something
somethings
sometime
sometimes
someway
someways
somewhat
somewhats
somewhere
somewheres
son
son's
sonata
sonata's
sonatas
song
song's
songs
songwriter
songwriter's
songwriters
sonic
sonics
sonnet
sonnet's
sonnets
sonorous
sons
soon
sooner
soonest
soot
soot's
soothe
soothed
soother
soothes
soothest
soothing
soothingly
soothings
sootier
sootiest
sooty
sop
sop's
sophisticate
sophisticated
sophisticates
sophisticating
sophistication
sophistication's
sophistry
sophistry's
sophomore
sophomore's
sophomores
sophomoric
soporific
soporifics
sopped
sopping
soppings
soprano
soprano's
sopranos
sops
sorbet
sorbet's
sorbets
sorcerer
sorcerer's
sorcerers
sorceress
sorceresses
sorcery
sorcery's
sordid
sore
sored
sorely
soreness
sorer
sores
sorest
soring
sororities
sorority
sorority's
sorrier
sorriest
sorrow
sorrow's
sorrowed
sorrowful
sorrowfully
sorrowing
sorrows
sorry
sort
sort's
sorta
sorted
sorting
sorts
souffl
souffl's
souffls
sought
soul
soul's
soulful
souls
sound
sound's
sounded
sounder
soundest
sounding
soundly
soundness
soundness's
soundproof
soundproofed
soundproofing
soundproofs
sounds
soundtrack
soundtrack's
soundtracks
soup
soup's
souped
souping
soups
sour
source
source's
sourced
sources
sourcing
sourdough
sourdoughs
soured
sourer
sourest
souring
sourly
sourness
sourness's
sours
south
south's
southbound
southeast
southeast's
southeasterly
southeastern
southeastward
southerlies
southerly
southern
southerner
southerner's
southerners
southerns
southpaw
southpaw's
southpaws
southward
southwest
southwest's
southwesterly
southwestern
southwestward
souvenir
souvenir's
souvenirs
sovereign
sovereign's
sovereigns
sovereignty
sovereignty's
sow
sowed
sowing
sown
sows
sox
sox's
soybean
soybean's
soybeans
spa
spa's
space
space's
spacecraft
spacecraft's
spacecrafts
spaced
spaces
spaceship
spaceship's
spaceships
spacey
spacial
spacier
spaciest
spacing
spacing's
spacious
spaciousness
spaciousness's
spacy
spade
spade's
spaded
spades
spading
spaghetti
spaghetti's
span
span's
spangle
spangle's
spangled
spangles
spangling
spaniel
spaniel's
spanielled
spanielling
spaniels
spank
spanked
spanking
spanking's
spankings
spanks
spanned
spanner
spanner's
spanners
spanning
spans
spar
spar's
spare
spared
sparer
spares
sparest
sparing
sparingly
spark
spark's
sparked
sparking
sparkle
sparkled
sparkler
sparkler's
sparklers
sparkles
sparkling
sparks
sparred
sparrer
sparring
sparrow
sparrow's
sparrows
spars
sparse
sparsely
sparseness
sparser
sparsest
spas
spasm
spasm's
spasmed
spasming
spasmodic
spasms
spastic
spastics
spat
spat's
spate
spate's
spates
spatial
spats
spatted
spatter
spattered
spattering
spatters
spatting
spatula
spatula's
spatulas
spawn
spawn's
spawned
spawning
spawns
spay
spayed
spaying
spays
speak
speaker
speaker's
speakers
speaking
speaks
spear
spear's
speared
spearhead
spearhead's
spearheaded
spearheading
spearheads
spearing
spearmint
spearmint's
spears
special
specialer
specialisation
specialisation's
specialisations
specialise
specialised
specialises
specialising
specialist
specialist's
specialists
specialities
speciality
speciality's
specially
specials
species
specific
specifically
specification
specification's
specifications
specifics
specified
specifier
specifier's
specifies
specify
specifying
specimen
specimen's
specimens
specious
speck
speck's
specked
specking
speckle
speckled
speckles
speckling
specks
spectacle
spectacle's
spectacles
spectacular
spectacularly
spectaculars
spectator
spectator's
spectators
spectra
spectra's
spectre
spectre's
spectres
spectrum
spectrum's
spectrums
speculate
speculated
speculates
speculating
speculation
speculation's
speculations
speculative
speculator
speculator's
speculators
sped
speech
speech's
speeched
speeches
speeching
speechless
speed
speed's
speedboat
speedboat's
speedboats
speeded
speedier
speediest
speedily
speeding
speedometer
speedometer's
speedometers
speeds
speedway
speedway's
speedways
speedy
spell
spellbind
spellbinding
spellbinds
spellbound
speller
speller's
spelling
spelling's
spellings
spells
spelt
spend
spending
spends
spendthrift
spendthrift's
spendthrifts
spent
sperm
sperm's
sperms
spew
spewed
spewing
spews
sphere
sphere's
spheres
spherical
sphinges
sphinx
sphinx's
sphinxes
spice
spice's
spiced
spices
spicier
spiciest
spicing
spicy
spider
spider's
spiders
spied
spiel
spiel's
spieled
spieling
spiels
spies
spiffied
spiffier
spiffies
spiffiest
spiffy
spiffying
spigot
spigot's
spigots
spike
spike's
spiked
spikes
spiking
spill
spilling
spills
spilt
spin
spinach
spinach's
spinal
spinals
spindlier
spindliest
spindly
spine
spine's
spineless
spines
spinning
spinning's
spins
spinster
spinster's
spinsters
spiral
spiralled
spiralling
spirals
spire
spire's
spires
spirit
spirit's
spirited
spiriting
spirits
spiritual
spiritually
spirituals
spit
spite
spite's
spited
spiteful
spitefuller
spitefullest
spites
spiting
spits
spitted
spitting
spittle
spittle's
splash
splashed
splashes
splashier
splashiest
splashing
splashy
splat
splat's
splats
splatted
splatter
splattered
splattering
splatters
splatting
splay
splayed
splaying
splays
spleen
spleen's
spleens
splendid
splendider
splendidest
splendidly
splendour
splendour's
splice
spliced
splices
splicing
splint
splint's
splinted
splinter
splinter's
splintered
splintering
splinters
splinting
splints
split
splits
splits's
splitting
splittings
splurge
splurge's
splurged
splurges
splurging
spoil
spoiling
spoils
spoilsport
spoilsport's
spoilsports
spoilt
spoke
spoken
spokes
spokesman
spokesman's
spokesmen
spokespeople
spokesperson
spokespersons
spokeswoman
spokeswoman's
spokeswomen
sponge
sponge's
sponged
sponges
spongier
spongiest
sponging
spongy
sponsor
sponsor's
sponsored
sponsoring
sponsors
sponsorship
spontaneity
spontaneity's
spontaneous
spontaneously
spoof
spoof's
spoofed
spoofing
spoofs
spook
spook's
spooked
spookier
spookiest
spooking
spooks
spooky
spool
spool's
spooled
spooling
spools
spoon
spoon's
spooned
spoonful
spoonful's
spoonfuls
spooning
spoons
spoonsful
sporadic
sporadically
spore
spores
sporran
sporran's
sport
sport's
sported
sportier
sportiest
sporting
sports
sportscast
sportscast's
sportscasting
sportscasts
sportsman
sportsman's
sportsmanship
sportsmanship's
sportsmen
sportswear
sportswear's
sporty
spot
spot's
spotless
spotlight
spotlight's
spotlighted
spotlighting
spotlights
spots
spotted
spottier
spottiest
spotting
spotting's
spotty
spouse
spouse's
spouses
spout
spouted
spouting
spouts
sprain
sprained
spraining
sprains
sprang
sprangs
sprawl
sprawled
sprawling
sprawls
spray
spray's
sprayed
spraying
sprays
spread
spreading
spreads
spreadsheet
spreadsheets
spree
spree's
spreed
spreeing
sprees
sprier
spriest
sprig
sprig's
sprigs
spring
springboard
springboard's
springboards
springier
springiest
springing
springing's
springs
springtime
springtime's
springy
sprinkle
sprinkled
sprinkler
sprinkler's
sprinklers
sprinkles
sprinkling
sprinkling's
sprinklings
sprint
sprint's
sprinted
sprinter
sprinters
sprinting
sprints
sprout
sprouted
sprouting
sprouts
spruce
spruce's
spruced
sprucer
spruces
sprucest
sprucing
sprung
spry
spryer
spryest
spud
spud's
spuds
spun
spunk
spunk's
spunked
spunkier
spunkies
spunkiest
spunking
spunks
spunky
spur
spur's
spurious
spurn
spurned
spurning
spurns
spurred
spurring
spurs
spurt
spurted
spurting
spurts
sputter
sputtered
sputtering
sputters
spy
spy's
spying
squabble
squabbled
squabbles
squabbling
squad
squad's
squadded
squadding
squadron
squadron's
squadrons
squads
squalid
squalider
squalidest
squall
squall's
squalled
squalling
squalls
squalor
squalor's
squander
squandered
squandering
squanders
square
square's
squared
squarely
squarer
squares
squarest
squaring
squash
squashed
squashes
squashing
squat
squats
squatted
squatter
squatter's
squattered
squattering
squatters
squattest
squatting
squawk
squawk's
squawked
squawking
squawks
squeak
squeak's
squeaked
squeakier
squeakiest
squeaking
squeaks
squeaky
squeal
squeal's
squealed
squealing
squeals
squeamish
squeeze
squeezed
squeezes
squeezing
squelch
squelched
squelches
squelching
squid
squid's
squidded
squidding
squids
squint
squinted
squinter
squintest
squinting
squints
squire
squire's
squired
squires
squiring
squirm
squirmed
squirming
squirms
squirrel
squirrel's
squirrelled
squirrelling
squirrels
squirt
squirted
squirting
squirts
stab
stabbed
stabbing
stabbings
stabilise
stabilised
stabilises
stabilising
stability
stability's
stable
stable's
stabled
stabler
stables
stablest
stabling
stabs
stack
stack's
stacked
stacking
stacks
stadia
stadia's
stadium
stadium's
stadiums
staff
staff's
staffed
staffer
staffer's
staffers
staffing
staffs
stag
stag's
stage
stage's
stagecoach
stagecoach's
stagecoaches
staged
stages
stagger
staggered
staggering
staggeringly
staggerings
staggers
staging
staging's
stagings
stagnant
stagnate
stagnated
stagnates
stagnating
stagnation
stagnation's
stags
staid
staider
staidest
stain
stained
staining
stains
stair
stair's
staircase
staircase's
staircases
stairs
stairway
stairway's
stairways
stake
stake's
staked
stakeout
stakeout's
stakeouts
stakes
staking
stale
staled
stalemate
stalemate's
stalemated
stalemates
stalemating
staler
stales
stalest
staling
stalk
stalk's
stalked
stalker
stalker's
stalkers
stalking
stalkings
stalks
stall
stall's
stalled
stalling
stallion
stallion's
stallions
stalls
stalwart
stalwarts
stamina
stamina's
stammer
stammered
stammering
stammers
stamp
stamped
stampede
stampede's
stampeded
stampedes
stampeding
stamping
stamps
stance
stance's
stances
stanch
stanched
stancher
stanches
stanchest
stanching
stand
standard
standard's
standardisation
standardisation's
standardise
standardised
standardises
standardising
standards
standby
standbys
standing
standing's
standings
standoff
standoff's
standoffs
standout
standout's
standouts
standpoint
standpoint's
standpoints
stands
standstill
standstill's
standstills
stank
stanks
stanza
stanza's
stanzas
staple
staple's
stapled
stapler
stapler's
staplers
staples
stapling
star
star's
starboard
starboard's
starch
starch's
starched
starches
starchier
starchiest
starching
starchy
stardom
stardom's
stare
stared
stares
starfish
starfish's
starfishes
staring
stark
starked
starker
starkest
starking
starks
starlight
starlight's
starred
starrier
starriest
starring
starry
stars
start
started
starter
starter's
starters
starting
startle
startled
startles
startling
startlingly
starts
starvation
starvation's
starve
starved
starves
starving
starvings
stash
stashed
stashes
stashing
state
state's
stated
statelier
stateliest
stately
statement
statement's
statements
stater
states
statesman
statesman's
statesmanlike
statesmanship
statesmanship's
statesmen
statewide
static
stating
station
station's
stationary
stationed
stationery
stationery's
stationing
stations
statistic
statistic's
statistical
statistically
statistician
statistician's
statisticians
statistics
stats
statue
statue's
statues
stature
stature's
statures
status
status's
statuses
statute
statute's
statutes
statutory
staunch
staunched
stauncher
staunches
staunchest
staunching
staunchly
stave
stave's
staved
staves
staving
stay
stayed
staying
stays
steadfast
steadied
steadier
steadies
steadiest
steadily
steady
steadying
steak
steak's
steaks
steal
stealing
stealing's
steals
stealth
stealth's
stealthier
stealthiest
stealthily
stealthy
steam
steam's
steamboat
steamboat's
steamboats
steamed
steamier
steamies
steamiest
steaming
steamroll
steamrolled
steamroller
steamroller's
steamrollered
steamrollering
steamrollers
steamrolling
steamrolls
steams
steamy
steel
steel's
steeled
steeling
steels
steep
steeped
steeper
steepest
steeping
steeple
steeple's
steeples
steeply
steepness
steeps
steer
steered
steering
steers
stellar
stem
stem's
stemmed
stemming
stems
stench
stench's
stenched
stenches
stenching
stencil
stencil's
stencilled
stencilling
stencils
stenographer
stenographer's
stenographers
stenography
stenography's
step
step's
stepbrother
stepbrother's
stepbrothers
stepchild
stepchild's
stepchildren
stepdaughter
stepdaughter's
stepdaughters
stepfather
stepfather's
stepfathers
stepladder
stepladder's
stepladders
stepmother
stepmother's
stepmothers
stepped
stepping
steps
stepsister
stepsister's
stepsisters
stepson
stepson's
stepsons
stereo
stereos
stereotype
stereotype's
stereotyped
stereotypes
stereotypical
stereotyping
sterile
sterilisation
sterilisation's
sterilise
sterilised
sterilises
sterilising
sterility
sterility's
sterling
sterling's
stern
sterned
sterner
sternest
sterning
sternly
sternness
sterns
steroid
steroid's
steroids
stethoscope
stethoscope's
stethoscopes
stew
stew's
steward
steward's
stewarded
stewardess
stewardess's
stewardesses
stewarding
stewards
stewed
stewing
stews
stick
stick's
sticker
sticker's
stickers
stickied
stickier
stickies
stickiest
sticking
stickler
stickler's
sticklers
sticks
sticky
stickying
stiff
stiffed
stiffen
stiffened
stiffening
stiffens
stiffer
stiffest
stiffing
stiffly
stiffness
stiffness's
stiffs
stifle
stifled
stifles
stifling
stiflings
stigma
stigma's
stigmas
stigmata
stigmatise
stigmatised
stigmatises
stigmatising
still
stillbirth
stillbirth's
stillbirths
stillborn
stillborns
stilled
stiller
stillest
stilling
stillness
stillness's
stills
stilt
stilt's
stilted
stilts
stimulant
stimulant's
stimulants
stimulate
stimulated
stimulates
stimulating
stimulation
stimulation's
stimuli
stimuli's
stimulus
stimulus's
sting
stinger
stinger's
stingers
stingier
stingiest
stinginess
stinginess's
stinging
stings
stingy
stink
stinker
stinker's
stinkers
stinking
stinkings
stinks
stint
stinted
stinting
stints
stipend
stipend's
stipends
stipulate
stipulated
stipulates
stipulating
stipulation
stipulation's
stipulations
stir
stirred
stirring
stirrup
stirrup's
stirrups
stirs
stitch
stitch's
stitched
stitches
stitching
stitching's
stock
stock's
stockade
stockade's
stockaded
stockades
stockading
stockbroker
stockbroker's
stockbrokers
stocked
stockholder
stockholder's
stockholders
stockier
stockiest
stocking
stocking's
stockings
stockpile
stockpiled
stockpiles
stockpiling
stocks
stocky
stockyard
stockyard's
stockyards
stodgier
stodgiest
stodgy
stoic
stoic's
stoical
stoicism
stoicism's
stoics
stoke
stoked
stokes
stoking
stole
stolen
stoles
stolid
stolider
stolidest
stolidly
stomach
stomach's
stomachache
stomachache's
stomachaches
stomached
stomaching
stomachs
stomp
stomped
stomping
stomps
stone
stone's
stoned
stones
stonewall
stonewalled
stonewalling
stonewalls
stoney
stonier
stoniest
stoning
stony
stood
stool
stool's
stools
stoop
stooped
stooping
stoops
stop
stopgap
stopgap's
stopgaps
stoplight
stoplight's
stoplights
stopover
stopover's
stopovers
stoppage
stoppage's
stoppages
stopped
stopper
stopper's
stoppered
stoppering
stoppers
stopping
stopping's
stops
stops's
stopwatch
stopwatch's
stopwatches
storage
storage's
store
store's
stored
storehouse
storehouse's
storehouses
storekeeper
storekeeper's
storekeepers
storeroom
storeroom's
storerooms
stores
storey
storey's
storeys
stories
storing
stork
stork's
storks
storm
storm's
stormed
stormier
stormiest
storming
storms
stormy
story
story's
storyteller
storyteller's
storytellers
stout
stouter
stoutest
stove
stove's
stoves
stow
stowaway
stowaway's
stowaways
stowed
stowing
stows
straddle
straddled
straddles
straddling
straggle
straggled
straggler
stragglers
straggles
straggling
straight
straighted
straighten
straightened
straightening
straightens
straighter
straightest
straightforward
straightforwardly
straightforwards
straighting
straights
strain
strained
strainer
strainer's
strainers
straining
strains
strait
strait's
straited
straiting
straitjacket
straitjacket's
straitjacketed
straitjacketing
straitjackets
straits
strand
stranded
stranding
strands
strange
strangely
strangeness
strangeness's
stranger
stranger's
strangered
strangering
strangers
strangest
strangle
strangled
stranglehold
stranglehold's
strangleholds
strangles
strangling
strangulation
strangulation's
strap
strap's
strapless
straplesses
strapped
strapping
straps
strata
strata's
stratagem
stratagem's
stratagems
strategic
strategically
strategics
strategies
strategy
strategy's
stratified
stratifies
stratify
stratifying
stratosphere
stratosphere's
stratospheres
stratum
stratum's
stratums
straw
straw's
strawberries
strawberry
strawberry's
strawed
strawing
straws
stray
strayed
straying
strays
streak
streak's
streaked
streakier
streakiest
streaking
streaks
streaky
stream
stream's
streamed
streamer
streamer's
streamers
streaming
streaming's
streamline
streamline's
streamlined
streamlines
streamlining
streams
street
street's
streetcar
streetcar's
streetcars
streetlight
streetlight's
streetlights
streets
strength
strength's
strengthen
strengthened
strengthening
strengthens
strengths
strenuous
strenuously
stress
stress's
stressed
stresses
stressful
stressing
stretch
stretched
stretcher
stretcher's
stretchers
stretches
stretching
strew
strewed
strewing
strewn
strews
stricken
strict
stricter
strictest
strictly
strictness
stridden
stride
stride's
strident
strides
striding
strife
strife's
strike
striker
striker's
strikers
strikes
striking
strikingly
strikings
string
string's
stringent
stringier
stringiest
stringing
strings
stringy
strip
stripe
stripe's
striped
stripes
striping
stripped
stripper
stripper's
strippers
stripping
strips
stript
striptease
striptease's
stripteased
stripteases
stripteasing
strive
strived
striven
strives
striving
strode
stroke
stroke's
stroked
strokes
stroking
stroll
strolled
stroller
stroller's
strollers
strolling
strolls
strong
stronger
strongest
stronghold
stronghold's
strongholds
strongly
strove
struck
structural
structuralist
structuralist's
structure
structure's
structured
structures
structuring
struggle
struggled
struggles
struggling
strum
strummed
strumming
strums
strung
strut
struts
strutted
strutting
stub
stub's
stubbed
stubbier
stubbies
stubbiest
stubbing
stubble
stubble's
stubborn
stubborned
stubborner
stubbornest
stubborning
stubbornly
stubbornness
stubbornness's
stubborns
stubby
stubs
stuck
stud
stud's
studded
studding
student
student's
students
studentship
studentship's
studied
studies
studio
studio's
studios
studious
studs
study
studying
stuff
stuffed
stuffier
stuffiest
stuffing
stuffing's
stuffs
stuffy
stumble
stumbled
stumbles
stumbling
stump
stump's
stumped
stumping
stumps
stun
stung
stunk
stunned
stunning
stuns
stunt
stunted
stunting
stunts
stupefied
stupefies
stupefy
stupefying
stupendous
stupid
stupider
stupidest
stupidities
stupidity
stupidity's
stupidly
stupids
stupor
stupor's
stupors
sturdier
sturdiest
sturdiness
sturdiness's
sturdy
stutter
stuttered
stuttering
stutters
style
style's
styled
styles
styling
stylish
stylistic
stylus
stylus's
stymie
stymied
stymieing
stymies
stymy
stymying
suave
suaver
suavest
sub
sub's
subbed
subbing
subcommittee
subcommittees
subconscious
subconsciously
subculture
subculture's
subcultures
subdivide
subdivided
subdivides
subdividing
subdivision
subdivision's
subdivisions
subdue
subdued
subdues
subduing
subgroup
subgroup's
subject
subject's
subjected
subjecting
subjective
subjectively
subjectives
subjects
subjugate
subjugated
subjugates
subjugating
subjunctive
subjunctives
sublet
sublets
subletting
sublime
sublimed
sublimer
sublimes
sublimest
subliminal
subliming
submarine
submarine's
submarines
submerge
submerged
submerges
submerging
submersion
submersion's
submission
submission's
submissions
submissive
submit
submits
submitted
submitting
subnormal
subordinate
subordinated
subordinates
subordinating
subordination
subordination's
subpoena
subpoena's
subpoenaed
subpoenaing
subpoenas
subprogram
subroutine
subroutine's
subroutines
subs
subscribe
subscribed
subscriber
subscriber's
subscribers
subscribes
subscribing
subscript
subscription
subscription's
subscriptions
subscripts
subsection
subsection's
subsections
subsequent
subsequently
subsequents
subservience
subservience's
subservient
subservients
subset
subset's
subsets
subside
subsided
subsides
subsidiaries
subsidiary
subsidies
subsiding
subsidise
subsidised
subsidises
subsidising
subsidy
subsidy's
subsist
subsisted
subsistence
subsistence's
subsisting
subsists
substance
substance's
substances
substandard
substantial
substantially
substantiate
substantiated
substantiates
substantiating
substitute
substituted
substitutes
substituting
substitution
substitution's
substitutions
subsystem
subterfuge
subterfuge's
subterfuges
subterranean
subtitle
subtitles
subtle
subtler
subtlest
subtleties
subtlety
subtlety's
subtly
subtract
subtracted
subtracting
subtraction
subtraction's
subtractions
subtracts
suburb
suburb's
suburban
suburbans
suburbia
suburbia's
suburbs
subversive
subversives
subvert
subverted
subverting
subverts
subway
subway's
subways
succeed
succeeded
succeeding
succeeds
success
success's
successes
successful
successfully
succession
succession's
successions
successive
successively
successor
successor's
successors
succinct
succincter
succinctest
succinctly
succour
succour's
succoured
succouring
succours
succulent
succulents
succumb
succumbed
succumbing
succumbs
such
suck
sucked
sucker
sucker's
suckered
suckering
suckers
sucking
suckle
suckled
suckles
suckling
sucks
suction
suction's
suctioned
suctioning
suctions
sudden
suddenly
suddenness
suddenness's
suds
sue
sued
suede
suede's
sues
suffer
suffered
sufferer
sufferer's
sufferers
suffering
suffering's
sufferings
suffers
suffice
sufficed
suffices
sufficiency
sufficiency's
sufficient
sufficiently
sufficing
suffix
suffix's
suffixed
suffixes
suffixing
suffocate
suffocated
suffocates
suffocating
suffocatings
suffocation
suffrage
suffrage's
sugar
sugar's
sugared
sugarier
sugariest
sugaring
sugars
sugary
suggest
suggested
suggester
suggester's
suggestible
suggesting
suggestion
suggestion's
suggestions
suggestive
suggestively
suggests
suicidal
suicide
suicide's
suicides
suing
suit
suit's
suitability
suitable
suitably
suitcase
suitcase's
suitcases
suite
suite's
suited
suites
suiting
suitor
suitor's
suitors
suits
sulk
sulked
sulkier
sulkies
sulkiest
sulking
sulks
sulky
sullen
sullener
sullenest
sullenly
sulphur
sulphur's
sultan
sultan's
sultans
sultrier
sultriest
sultry
sum
sum's
summaries
summarily
summarise
summarised
summarises
summarising
summary
summary's
summed
summer
summer's
summered
summerier
summeriest
summering
summers
summertime
summertime's
summery
summing
summit
summit's
summits
summon
summoned
summoning
summons
summons's
summonsed
summonses
summonsing
sumptuous
sums
sun
sun's
sunbathe
sunbathed
sunbathes
sunbathing
sunbathing's
sunblock
sunblocks
sunburn
sunburn's
sunburned
sunburning
sunburns
sunburnt
sundae
sundae's
sundaes
sundial
sundial's
sundials
sundown
sundown's
sundowns
sundries
sundry
sunflower
sunflower's
sunflowers
sung
sunglasses
sunk
sunken
sunks
sunlight
sunlight's
sunlit
sunned
sunnier
sunnies
sunniest
sunning
sunny
sunrise
sunrise's
sunrises
sunrising
suns
sunscreen
sunscreens
sunset
sunset's
sunsets
sunsetting
sunshine
sunshine's
suntan
suntan's
suntanned
suntanning
suntans
sunup
sunup's
sup
super
superb
superber
superbest
superbly
supercomputer
supercomputers
supered
superficial
superficially
superficials
superfluous
superhighway
superhighway's
superhighways
superhuman
superimpose
superimposed
superimposes
superimposing
supering
superintendent
superintendent's
superintendents
superior
superiority
superiority's
superiors
superlative
superlatives
supermarket
supermarket's
supermarkets
supernatural
supernaturals
superpower
superpower's
superpowers
supers
superscript
superscripts
supersede
superseded
supersedes
superseding
supersonic
supersonics
superstar
superstar's
superstars
superstition
superstition's
superstitions
superstitious
superstructure
superstructure's
superstructures
supervise
supervised
supervises
supervising
supervision
supervision's
supervisions
supervisor
supervisor's
supervisors
supervisory
supper
supper's
suppers
supplant
supplanted
supplanting
supplants
supple
supplement
supplement's
supplemental
supplementary
supplemented
supplementing
supplements
suppler
supplest
supplied
supplier
supplier's
suppliers
supplies
supply
supplying
support
supported
supporter
supporter's
supporters
supporting
supportive
supports
suppose
supposed
supposedly
supposes
supposing
supposings
supposition
supposition's
suppositions
suppress
suppressed
suppresses
suppressing
suppression
suppression's
supremacy
supremacy's
supreme
supremely
supremer
supremest
surcharge
surcharge's
surcharged
surcharges
surcharging
sure
surefire
surely
surer
sures
surest
surf
surf's
surface
surface's
surfaced
surfaces
surfacing
surfboard
surfboard's
surfboarded
surfboarding
surfboards
surfed
surfer
surfer's
surfers
surfing
surfing's
surfs
surge
surge's
surged
surgeon
surgeon's
surgeons
surgeries
surgery
surgery's
surges
surgical
surgically
surging
surlier
surliest
surly
surmise
surmised
surmises
surmising
surmount
surmounted
surmounting
surmounts
surname
surname's
surnames
surpass
surpassed
surpasses
surpassing
surplus
surplus's
surplused
surpluses
surplusing
surplussed
surplussing
surprise
surprised
surprises
surprising
surprisingly
surprisings
surreal
surrealistic
surreals
surrender
surrendered
surrendering
surrenders
surreptitious
surrogate
surrogate's
surrogates
surround
surrounded
surrounding
surrounding's
surroundings
surrounds
surveillance
surveillance's
survey
surveyed
surveying
surveyor
surveyor's
surveyors
surveys
survival
survival's
survivals
survive
survived
survives
surviving
survivor
survivor's
survivors
susceptible
suspect
suspected
suspecting
suspects
suspend
suspended
suspender
suspenders
suspending
suspends
suspense
suspense's
suspension
suspension's
suspensions
suspicion
suspicion's
suspicions
suspicious
suspiciously
sustain
sustainable
sustained
sustaining
sustains
sustenance
sustenance's
swab
swab's
swabbed
swabbing
swabs
swagger
swaggered
swaggerer
swaggering
swaggers
swallow
swallowed
swallowing
swallows
swam
swamp
swamp's
swamped
swampier
swampiest
swamping
swamps
swampy
swan
swan's
swank
swanked
swanker
swankest
swanking
swanks
swans
swap
swapped
swapping
swaps
swarm
swarm's
swarmed
swarming
swarms
swarthier
swarthiest
swarthy
swat
swatch
swatch's
swatches
swathe
swathed
swathes
swathing
swats
swatted
swatting
sway
swayed
swaying
sways
swear
swearing
swears
sweat
sweat's
sweated
sweater
sweater's
sweaters
sweatier
sweatiest
sweating
sweatpants
sweats
sweatshirt
sweatshirts
sweatshop
sweatshop's
sweatshops
sweaty
sweep
sweeper
sweeper's
sweepers
sweeping
sweepings
sweeps
sweeps's
sweepstake
sweepstakes
sweet
sweeten
sweetened
sweetener
sweetener's
sweeteners
sweetening
sweetens
sweeter
sweetest
sweetheart
sweetheart's
sweethearts
sweetie
sweetie's
sweeties
sweetly
sweetness
sweetness's
sweets
swell
swelled
sweller
swellest
swelling
swelling's
swellings
swells
swelter
sweltered
sweltering
swelterings
swelters
swept
swerve
swerved
swerves
swerving
swift
swifted
swifter
swiftest
swifting
swiftly
swifts
swig
swig's
swigged
swigging
swigs
swill
swilled
swilling
swills
swim
swimmer
swimmers
swimming
swimming's
swims
swimsuit
swimsuit's
swimsuits
swindle
swindled
swindler
swindler's
swindlers
swindles
swindling
swine
swine's
swines
swing
swinging
swings
swipe
swiped
swipes
swiping
swirl
swirled
swirling
swirls
swish
swished
swisher
swishes
swishest
swishing
switch
switch's
switchable
switchboard
switchboard's
switchboards
switched
switcher
switches
switching
swivel
swivel's
swivelled
swivelling
swivels
swollen
swoon
swooned
swooning
swoons
swoop
swooped
swooping
swoops
sword
sword's
sworded
swordfish
swordfish's
swordfishes
swording
swords
swore
sworn
swum
swung
sycamore
sycamore's
sycamores
sycophant
sycophant's
sycophants
syllabi
syllabi's
syllable
syllable's
syllables
syllabus
syllabus's
syllabuses
symbol
symbol's
symbolic
symbolically
symbolics
symbolise
symbolised
symbolises
symbolising
symbolism
symbolism's
symbols
symmetric
symmetrical
symmetrically
symmetry
symmetry's
sympathetic
sympathetically
sympathetics
sympathies
sympathise
sympathised
sympathiser
sympathiser's
sympathisers
sympathises
sympathising
sympathy
sympathy's
symphonic
symphonies
symphony
symphony's
symptom
symptom's
symptomatic
symptoms
synagogue
synagogue's
synagogues
synapse
synapses
sync
synced
synchronisation
synchronisation's
synchronise
synchronised
synchronises
synchronising
synchronous
syncing
syncs
syndicate
syndicate's
syndicated
syndicates
syndicating
syndication
syndrome
syndrome's
syndromes
synod
synod's
synods
synonym
synonym's
synonymous
synonyms
synopses
synopsis
synopsis's
synopsised
synopsises
synopsising
syntactic
syntactically
syntax
syntax's
syntheses
synthesis
synthesis's
synthesise
synthesised
synthesiser
synthesiser's
synthesisers
synthesises
synthesising
synthetic
synthetically
synthetics
syphilis
syphilis's
syphilised
syphilises
syphilising
syphon
syphon's
syphoned
syphoning
syphons
syringe
syringe's
syringed
syringes
syringing
syrup
syrup's
system
system's
systematic
systematically
systematics
systems
t
tab
tab's
tabbed
tabbies
tabbing
tabby
tabernacle
tabernacle's
tabernacles
table
table's
tablecloth
tablecloth's
tablecloths
tabled
tables
tablespoon
tablespoon's
tablespoonful
tablespoonful's
tablespoonfuls
tablespoons
tablespoonsful
tablet
tablet's
tablets
tabling
tabloid
tabloid's
tabloids
taboo
tabooed
tabooing
taboos
tabs
tabulate
tabulated
tabulates
tabulating
tabulation
tabulation's
taces
tacit
tacitly
taciturn
tack
tack's
tacked
tackier
tackies
tackiest
tackiness
tackiness's
tacking
tackle
tackle's
tackled
tackles
tackling
tackling's
tacks
tacky
taco
taco's
tacos
tact
tact's
tactful
tactfully
tactic
tactic's
tactical
tactically
tactics
tactless
tactlessly
tad
tad's
tadpole
tadpole's
tadpoles
tads
taffies
taffy
taffy's
tag
tag's
tagged
tagging
tags
tail
tail's
tailed
tailgate
tailgate's
tailgated
tailgates
tailgating
tailing
taillight
taillight's
taillights
tailor
tailor's
tailored
tailoring
tailors
tailpipe
tailpipe's
tailpipes
tails
tailspin
tailspin's
tailspins
taint
tainted
tainting
taints
take
taken
takeoff
takeoff's
takeoffs
takeout
takeouts
takeover
takeover's
takeovers
taker
takers
takes
taking
takings
talc
talc's
tale
tale's
talent
talent's
talented
talented's
talents
tales
talisman
talisman's
talismans
talk
talkative
talked
talker
talker's
talkers
talking
talks
tall
taller
tallest
tallied
tallies
tallow
tallow's
tally
tallying
talon
talon's
talons
tambourine
tambourine's
tambourines
tame
tamed
tamely
tameness
tamer
tames
tamest
taming
tamper
tampered
tampering
tampers
tampon
tampon's
tampons
tan
tan's
tandem
tandem's
tandems
tang
tang's
tangent
tangent's
tangential
tangents
tangerine
tangerine's
tangerines
tangible
tangibles
tangier
tangies
tangiest
tangle
tangle's
tangled
tangles
tangling
tango
tango's
tangoed
tangoing
tangos
tangs
tangy
tank
tank's
tankard
tankard's
tankards
tanked
tanker
tanker's
tankers
tanking
tanks
tanned
tanner
tannest
tanning
tans
tantalise
tantalised
tantalises
tantalising
tantalisingly
tantamount
tantrum
tantrum's
tantrums
tap
tap's
tape
tape's
taped
taper
tapered
tapering
tapers
tapes
tapestries
tapestry
tapestry's
tapeworm
tapeworm's
tapeworms
taping
tapped
tapping
tapping's
taps
taps's
tar
tar's
tarantula
tarantula's
tarantulae
tarantulas
tardier
tardies
tardiest
tardiness
tardy
target
target's
targeted
targeting
targets
tariff
tariff's
tariffs
tarmac
tarmacked
tarmacking
tarmacs
tarnish
tarnished
tarnishes
tarnishing
tarot
tarot's
tarots
tarp
tarp's
tarpaulin
tarpaulin's
tarpaulins
tarps
tarred
tarried
tarrier
tarries
tarriest
tarring
tarry
tarrying
tars
tart
tart's
tartan
tartan's
tartans
tartar
tartar's
tartars
tarted
tarter
tartest
tarting
tarts
task
task's
tasked
tasking
tasks
tassel
tassel's
tasselled
tasselling
tassells
taste
taste's
tasted
tasteful
tastefully
tasteless
taster
taster's
tasters
tastes
tastier
tastiest
tasting
tasty
tatter
tattered
tattered's
tattering
tatters
tattle
tattled
tattles
tattletale
tattletale's
tattletales
tattling
tattoo
tattoo's
tattooed
tattooing
tattoos
tatty
taught
taunt
taunted
taunting
taunts
taut
tauted
tauter
tautest
tauting
tautly
tautology
tautology's
tauts
tavern
tavern's
taverns
tawdrier
tawdriest
tawdry
tawnier
tawniest
tawny
tawny's
tax
tax's
taxable
taxation
taxation's
taxed
taxes
taxi
taxi's
taxicab
taxicab's
taxicabs
taxidermy
taxidermy's
taxied
taxies
taxiing
taxing
taxings
taxis
taxpayer
taxpayer's
taxpayers
taxying
tea
tea's
teach
teacher
teacher's
teachers
teaches
teaching
teaching's
teachings
teacup
teacup's
teacups
teaed
teaing
teak
teak's
teakettle
teakettle's
teakettles
teaks
team
team's
teamed
teaming
teammate
teammate's
teammates
teams
teamster
teamster's
teamsters
teamwork
teamwork's
teapot
teapot's
teapots
tear
tear's
teardrop
teardrop's
teardrops
teared
tearful
teargas
teargases
teargassed
teargasses
teargassing
tearing
tears
teas
tease
teased
teases
teasing
teaspoon
teaspoon's
teaspoonful
teaspoonful's
teaspoonfuls
teaspoons
teaspoonsful
teat
teat's
teats
technical
technicalities
technicality
technicality's
technically
technicals
technician
technician's
technicians
technique
technique's
techniques
technological
technologically
technologies
technologist
technologist's
technologists
technology
technology's
tedious
tediously
tedium
tedium's
tee
tee's
teed
teeing
teem
teemed
teeming
teems
teen
teenage
teenaged
teenager
teenager's
teenagers
teens
tees
teeter
teetered
teetering
teeters
teeth
teeth's
teethe
teethed
teethes
teething
teething's
teetotal
teetotaller
teetotaller's
teetotallers
telecommunications
telecommute
telecommuted
telecommuter
telecommuters
telecommutes
telecommuting
telegram
telegram's
telegrams
telegraph
telegraph's
telegraphed
telegraphing
telegraphs
telepathic
telepathy
telepathy's
telephone
telephone's
telephoned
telephones
telephoning
telescope
telescope's
telescoped
telescopes
telescopic
telescoping
telethon
telethon's
telethons
teletype
televise
televised
televises
televising
television
television's
televisions
tell
teller
teller's
tellered
tellering
tellers
telling
tells
telltale
telltale's
telltales
temp
temp's
temped
temper
temper's
temperament
temperament's
temperamental
temperaments
temperance
temperance's
temperate
temperated
temperates
temperating
temperature
temperature's
temperatures
tempered
tempering
tempers
tempest
tempest's
tempests
tempestuous
tempi
temping
template
template's
templates
temple
temple's
temples
tempo
tempo's
temporal
temporaries
temporarily
temporary
tempos
temps
tempt
temptation
temptation's
temptations
tempted
tempting
temptings
tempts
ten
ten's
tenable
tenacious
tenacity
tenancies
tenancy
tenancy's
tenant
tenant's
tenanted
tenanting
tenants
tend
tended
tendencies
tendency
tendency's
tender
tendered
tenderer
tenderest
tenderhearted
tendering
tenderise
tenderised
tenderises
tenderising
tenderly
tenderness
tenderness's
tenders
tending
tendon
tendon's
tendons
tendril
tendril's
tendrils
tends
tenement
tenement's
tenements
tenet
tenet's
tenets
tennis
tennis's
tenor
tenor's
tenors
tens
tense
tensed
tenser
tenses
tensest
tensing
tension
tension's
tensions
tensors
tent
tent's
tentacle
tentacle's
tentacles
tentative
tentatively
tentatives
tented
tenth
tenths
tenting
tents
tenuous
tenure
tenure's
tenured
tenures
tenuring
tepee
tepee's
tepees
tepid
tequila
tequila's
tequilas
term
term's
termed
terminal
terminally
terminals
terminate
terminated
terminates
terminating
termination
termination's
terminations
terminator
terminator's
terminators
terming
termini
terminologies
terminology
terminology's
terminus
terminus's
terminuses
termite
termite's
termites
termly
terms
terrace
terrace's
terraced
terraces
terracing
terrain
terrain's
terrains
terrestrial
terrestrials
terrible
terribly
terrier
terrier's
terriers
terrific
terrified
terrifies
terrify
terrifying
territorial
territorials
territories
territory
territory's
terror
terror's
terrorise
terrorised
terrorises
terrorising
terrorism
terrorism's
terrorist
terrorist's
terrorists
terrors
terse
tersely
terseness
terseness's
terser
tersest
test
testable
testament
testament's
testaments
tested
tester
testers
testes
testes's
testicle
testicle's
testicles
testier
testiest
testified
testifies
testify
testifying
testimonial
testimonial's
testimonials
testimonies
testimony
testimony's
testing
testis
tests
testy
tetanus
tetanus's
tether
tether's
tethered
tethering
tethers
text
text's
textbook
textbook's
textbooks
textile
textile's
textiles
texts
textual
textually
texture
texture's
textures
than
thank
thanked
thankful
thankfuller
thankfullest
thankfully
thanking
thankless
thanks
that
that's
thatch
thatch's
thatched
thatcher
thatches
thatching
thaw
thawed
thawing
thaws
the
theatre
theatre's
theatres
theatrical
thee
theft
theft's
thefts
their
theirs
theist
theists
them
thematic
thematics
theme
theme's
themes
themselves
then
thence
theologian
theologian's
theologians
theological
theologies
theology
theology's
theorem
theorem's
theorems
theoretic
theoretical
theoretically
theoretician
theoretician's
theoreticians
theories
theorise
theorised
theorises
theorising
theorist
theorist's
theorists
theory
theory's
therapeutic
therapies
therapist
therapist's
therapists
therapy
therapy's
there
there's
thereabout
thereabouts
thereafter
thereby
therefore
therein
thereof
thereon
thereupon
thermal
thermals
thermodynamics
thermodynamics's
thermometer
thermometer's
thermometers
thermonuclear
thermostat
thermostat's
thermostats
thesauri
thesaurus
thesaurus's
thesauruses
these
theses
thesis
thesis's
theta
theta's
they
they'd
they'll
they're
they've
thick
thicken
thickened
thickening
thickens
thicker
thickest
thicket
thicket's
thickets
thickly
thickness
thickness's
thicknesses
thief
thief's
thieve
thieves
thigh
thigh's
thighs
thimble
thimble's
thimbled
thimbles
thimbling
thin
thing
thing's
thingamajig
thingamajigs
things
think
thinker
thinker's
thinkers
thinking
thinking's
thinks
thinly
thinned
thinner
thinner's
thinnest
thinning
thins
third
thirded
thirding
thirds
thirst
thirst's
thirsted
thirstier
thirstiest
thirstily
thirsting
thirsts
thirsty
thirteen
thirteen's
thirteens
thirteenth
thirteenths
thirties
thirtieth
thirtieths
thirty
thirty's
this
thistle
thistle's
thistles
thong
thong's
thongs
thorn
thorn's
thornier
thorniest
thorns
thorny
thorough
thoroughbred
thoroughbreds
thorougher
thoroughest
thoroughfare
thoroughfare's
thoroughfares
thoroughly
thoroughness
thoroughness's
those
thou
though
thought
thoughtful
thoughtfully
thoughtfulness
thoughtless
thoughtlessly
thoughtlessness
thoughtlessness's
thoughts
thous
thousand
thousand's
thousands
thousandth
thousandths
thrash
thrashed
thrashes
thrashing
thrashing's
thrashings
thread
thread's
threadbare
threaded
threading
threads
threat
threat's
threaten
threatened
threatening
threateningly
threatenings
threatens
threats
three
three's
threes
thresh
threshed
thresher
thresher's
threshers
threshes
threshing
threshold
threshold's
thresholds
threw
thrice
thrift
thrift's
thriftier
thriftiest
thrifts
thrifty
thrill
thrill's
thrilled
thriller
thriller's
thrillers
thrilling
thrills
thrive
thrived
thriven
thrives
thriving
thrivings
throat
throat's
throatier
throatiest
throats
throaty
throb
throbbed
throbbing
throbs
throne
throne's
thrones
throng
throng's
thronged
thronging
throngs
throttle
throttle's
throttled
throttles
throttling
through
throughout
throughput
throughput's
throve
throw
throwaway
throwaway's
throwaways
throwback
throwback's
throwbacks
throwing
thrown
throws
thrust
thrusting
thrusts
thud
thud's
thudded
thudding
thuds
thug
thug's
thugs
thumb
thumb's
thumbed
thumbing
thumbnail
thumbnail's
thumbnails
thumbs
thumbtack
thumbtack's
thumbtacks
thump
thump's
thumped
thumping
thumps
thunder
thunder's
thunderbolt
thunderbolt's
thunderbolts
thundered
thundering
thunderous
thunders
thunderstorm
thunderstorm's
thunderstorms
thunderstruck
thus
thwart
thwarted
thwarting
thwarts
thy
thyme
thyme's
thyroid
thyroids
tiara
tiara's
tiaras
tic
tic's
ticced
ticcing
tick
tick's
ticked
ticket
ticket's
ticketed
ticketing
tickets
ticking
ticking's
tickle
tickled
tickles
tickling
ticklish
ticks
tics
tidal
tidbit
tidbit's
tidbits
tide
tided
tides
tidied
tidier
tidies
tidiest
tiding
tidy
tidying
tidying's
tie
tiebreaker
tiebreaker's
tiebreakers
tied
tieing
tier
tier's
tiers
ties
tiff
tiff's
tiffed
tiffing
tiffs
tiger
tiger's
tigers
tight
tighten
tightened
tightening
tightens
tighter
tightest
tightfisted
tightly
tightness
tightness's
tightrope
tightrope's
tightropes
tights
tightwad
tightwad's
tightwads
tilde
tilde's
tile
tile's
tiled
tiles
tiling
till
tilled
tilling
tills
tilt
tilted
tilting
tilts
timber
timber's
timbers
time
time's
timed
timekeeper
timekeeper's
timekeepers
timeless
timelier
timeliest
timely
timer
timer's
timers
times
timescale
timescales
timetable
timetable's
timetabled
timetables
timetabling
timezone
timid
timider
timidest
timidity
timidity's
timidly
timing
timing's
timings
tin
tin's
tinder
tinder's
tinderbox
tinderbox's
tinderboxes
tinfoil
tinfoil's
ting
tinge
tinged
tingeing
tinges
tinging
tingle
tingled
tingles
tingling
tings
tinier
tiniest
tinker
tinker's
tinkered
tinkering
tinkers
tinkle
tinkled
tinkles
tinkling
tinned
tinnier
tinnies
tinniest
tinning
tinny
tins
tinsel
tinsel's
tinselled
tinselling
tinsels
tint
tint's
tinted
tinting
tints
tiny
tip
tipped
tipping
tips
tipsier
tipsiest
tipsy
tiptoe
tiptoed
tiptoeing
tiptoes
tirade
tirade's
tirades
tire
tire's
tired
tireder
tiredest
tiredness
tireless
tires
tiresome
tiring
tirings
tissue
tissue's
tissues
tit
tit's
titillate
titillated
titillates
titillating
title
title's
titled
titles
titling
tits
titted
titter
tittered
tittering
titters
titting
tizzies
tizzy
tizzy's
to
toad
toad's
toads
toadstool
toadstool's
toadstools
toast
toast's
toasted
toaster
toaster's
toasters
toastier
toasties
toastiest
toasting
toasts
toasty
tobacco
tobacco's
tobaccoes
tobacconist
tobacconist's
tobacconists
tobaccos
toboggan
toboggan's
tobogganed
tobogganing
toboggans
today
today's
toddle
toddled
toddler
toddler's
toddlers
toddles
toddling
toe
toe's
toed
toehold
toehold's
toeholds
toeing
toenail
toenail's
toenails
toes
toffee
toffee's
toffees
tofu
tog
toga
toga's
togae
togas
together
togetherness
togetherness's
toggle
toggle's
toggled
toggles
toggling
togs
toil
toil's
toiled
toilet
toilet's
toileted
toileting
toiletries
toiletry
toilets
toiling
toils
token
token's
tokenism
tokenism's
tokens
told
tolerable
tolerably
tolerance
tolerance's
tolerances
tolerant
tolerate
tolerated
tolerates
tolerating
toll
tollbooth
tollbooth's
tollbooths
tolled
tollgate
tollgate's
tollgates
tolling
tolls
tomahawk
tomahawk's
tomahawked
tomahawking
tomahawks
tomato
tomato's
tomatoes
tomb
tomb's
tombed
tombing
tomboy
tomboy's
tomboys
tombs
tombstone
tombstone's
tombstones
tomcat
tomcat's
tomcats
tome
tome's
tomes
tomfooleries
tomfoolery
tomfoolery's
tomorrow
tomorrow's
tomorrows
ton
ton's
tonal
tone
tone's
toned
tones
tong
tongs
tongue
tongue's
tongued
tongues
tonguing
tonic
tonic's
tonics
tonight
tonight's
toning
tonnage
tonnage's
tonnages
tonne
tonnes
tons
tonsil
tonsil's
tonsillitis
tonsillitis's
tonsils
too
took
tool
tool's
toolbar
toolbars
tooled
tooling
toolkit
tools
toot
tooted
tooth
tooth's
toothache
toothache's
toothaches
toothbrush
toothbrush's
toothbrushes
toothpaste
toothpaste's
toothpastes
toothpick
toothpick's
toothpicks
tooting
toots
top
top's
topaz
topaz's
topazes
topic
topic's
topical
topics
topless
topographer
topographer's
topographers
topographies
topography
topography's
topology
topology's
topped
topping
topping's
toppings
topple
toppled
topples
toppling
tops
torch
torch's
torched
torches
torching
tore
torment
tormented
tormenting
tormentor
tormentor's
tormentors
torments
torn
tornado
tornado's
tornadoes
tornados
torpedo
torpedo's
torpedoed
torpedoes
torpedoing
torpedos
torque
torque's
torrent
torrent's
torrential
torrents
torrid
torrider
torridest
torsi
torso
torso's
torsoes
torsos
tort
tort's
tortilla
tortilla's
tortillas
tortoise
tortoise's
tortoises
torts
tortuous
torture
tortured
torturer
torturers
tortures
torturing
toss
tossed
tosses
tossing
tost
tot
tot's
total
total's
totalitarian
totalitarianism
totalitarianism's
totalitarians
totalities
totality
totality's
totalled
totalling
totally
totals
tote
toted
totem
totem's
totems
totes
toting
tots
totted
totter
tottered
tottering
totters
totting
toucan
toucan's
toucans
touch
touchdown
touchdown's
touchdowns
touched
touches
touchier
touchiest
touching
touchings
touchstone
touchstone's
touchstones
touchy
tough
toughed
toughen
toughened
toughening
toughens
tougher
toughest
toughing
toughness
toughness's
toughs
toupee
toupee's
toupees
tour
tour's
toured
touring
tourism
tourism's
tourist
tourist's
tourists
tournament
tournament's
tournaments
tourniquet
tourniquet's
tourniquets
tours
tousle
tousled
tousles
tousling
tout
touted
touting
touts
tow
toward
towards
towed
towel
towel's
towelled
towelling
towellings
towels
tower
tower's
towered
towering
towers
towing
town
town's
townhouse
townhouses
towns
township
township's
townships
townspeople
townspeople's
tows
toxic
toxicity
toxicity's
toxicology
toxicology's
toxin
toxin's
toxins
toy
toy's
toyed
toying
toys
trace
trace's
traced
tracer
tracer's
tracers
traces
tracing
tracing's
track
track's
tracked
tracking
tracks
tract
tract's
traction
traction's
tractor
tractor's
tractors
tracts
trade
trade's
traded
trademark
trademark's
trademarked
trademarking
trademarks
trader
trader's
traders
trades
trading
tradition
tradition's
traditional
traditionalist
traditionalist's
traditionalists
traditionally
traditions
traffic
traffic's
trafficked
trafficking
traffics
tragedies
tragedy
tragedy's
tragic
tragically
tragics
trail
trailblazer
trailblazer's
trailblazers
trailed
trailer
trailer's
trailered
trailering
trailers
trailing
trails
train
trained
trainee
trainee's
trainees
trainer
trainer's
trainers
training
training's
trains
trait
trait's
traitor
traitor's
traitorous
traitors
traits
trajectories
trajectory
trajectory's
tramp
tramped
tramping
trample
trampled
tramples
trampling
trampoline
trampoline's
trampolined
trampolines
trampolining
tramps
trance
trance's
trances
tranquil
tranquiler
tranquilest
tranquilise
tranquilised
tranquiliser
tranquiliser's
tranquilisers
tranquilises
tranquilising
tranquility
tranquiller
tranquillest
tranquillity
transact
transacted
transacting
transaction
transaction's
transactions
transacts
transatlantic
transcend
transcended
transcendence
transcendence's
transcendental
transcending
transcends
transcontinental
transcribe
transcribed
transcribes
transcribing
transcript
transcript's
transcription
transcription's
transcriptions
transcripts
transfer
transferable
transferred
transferring
transfers
transform
transformation
transformation's
transformations
transformed
transformer
transformer's
transformers
transforming
transforms
transfusion
transfusion's
transfusions
transgress
transgressed
transgresses
transgressing
transgression
transgression's
transgressions
transient
transients
transistor
transistor's
transistors
transit
transit's
transited
transiting
transition
transition's
transitional
transitioned
transitioning
transitions
transitive
transitives
transitory
transits
transitted
transitting
translate
translated
translates
translating
translation
translation's
translations
translator
translator's
translators
transliteration
translucence
translucence's
translucent
transmission
transmission's
transmissions
transmit
transmits
transmitted
transmitter
transmitter's
transmitters
transmitting
transparencies
transparency
transparency's
transparent
transparently
transpire
transpired
transpires
transpiring
transplant
transplanted
transplanting
transplants
transport
transportable
transportation
transportation's
transported
transporting
transports
transpose
transposed
transposes
transposing
transsexual
transsexual's
transsexuals
transverse
transversed
transverses
transversing
transvestite
transvestite's
transvestites
trap
trap's
trapdoor
trapeze
trapeze's
trapezed
trapezes
trapezing
trapezoid
trapezoid's
trapezoids
trapped
trapper
trapper's
trappers
trapping
trappings
traps
trash
trash's
trashcan
trashcan's
trashed
trashes
trashier
trashiest
trashing
trashy
trauma
trauma's
traumas
traumata
traumatic
traumatise
traumatised
traumatises
traumatising
travel
travelled
traveller
traveller's
travellers
travelling
travellings
travels
traverse
traversed
traverses
traversing
travestied
travesties
travesty
travesty's
travestying
trawl
trawl's
trawled
trawler
trawler's
trawlers
trawling
trawls
tray
tray's
trays
treacheries
treacherous
treachery
treachery's
treacle
treacle's
tread
treading
treadmill
treadmill's
treadmills
treads
treason
treason's
treasure
treasure's
treasured
treasurer
treasurer's
treasurers
treasures
treasuries
treasuring
treasury
treasury's
treat
treat's
treatable
treated
treaties
treating
treatise
treatise's
treatises
treatment
treatment's
treatments
treats
treaty
treaty's
treble
trebled
trebles
trebling
tree
tree's
treed
treeing
trees
treetop
treetop's
treetops
trek
trekked
trekking
treks
trellis
trellis's
trellised
trellises
trellising
tremble
trembled
trembles
trembling
tremendous
tremendously
tremor
tremor's
tremors
trench
trench's
trenchant
trenched
trenches
trenching
trend
trend's
trended
trendier
trendies
trendiest
trending
trends
trendy
trepidation
trepidation's
trespass
trespassed
trespasser
trespasser's
trespassers
trespasses
trespassing
trestle
trestle's
trestles
trial
trial's
trialled
trialling
trials
triangle
triangle's
triangles
triangular
tribal
tribe
tribe's
tribes
tribulation
tribulation's
tribulations
tribunal
tribunal's
tribunals
tributaries
tributary
tributary's
tribute
tribute's
tributes
triceps
triceps's
tricepses
trick
trick's
tricked
trickery
trickery's
trickier
trickiest
tricking
trickle
trickled
trickles
trickling
tricks
trickster
trickster's
tricksters
tricky
tricycle
tricycle's
tricycled
tricycles
tricycling
trident
trident's
tridents
tried
tries
trifle
trifle's
trifled
trifles
trifling
trigger
trigger's
triggered
triggering
triggers
trigonometry
trigonometry's
trike
trike's
triked
trikes
triking
trill
trill's
trilled
trilling
trillion
trillion's
trillions
trills
trilogies
trilogy
trilogy's
trim
trimester
trimester's
trimesters
trimmed
trimmer
trimmest
trimming
trimmings
trims
trinity
trinity's
trinket
trinket's
trinkets
trio
trio's
trios
trip
trip's
tripe
tripe's
triple
tripled
triples
triplet
triplet's
triplets
triplicate
triplicated
triplicates
triplicating
tripling
tripod
tripod's
tripods
tripos
tripos's
tripped
tripping
trips
trite
triter
trites
tritest
triumph
triumph's
triumphant
triumphantly
triumphed
triumphing
triumphs
trivia
trivial
trivialise
trivialised
trivialises
trivialising
triviality
triviality's
trivially
trod
trodden
trodes
troll
trolled
trolley
trolley's
trolleys
trolling
trolls
trombone
trombone's
trombones
tromp
tromped
tromping
tromps
troop
troop's
trooped
trooper
trooper's
troopers
trooping
troops
trophied
trophies
trophy
trophy's
trophying
tropic
tropic's
tropical
tropicals
tropics
trot
trots
trotted
trotting
troubadour
troubadour's
troubadours
trouble
trouble's
troubled
troublemaker
troublemaker's
troublemakers
troubles
troubleshoot
troubleshooted
troubleshooter
troubleshooter's
troubleshooters
troubleshooting
troubleshoots
troubleshot
troublesome
troubling
trough
trough's
troughs
trounce
trounced
trounces
trouncing
troupe
troupe's
trouped
troupes
trouping
trouser
trouser's
trousers
trout
trout's
trouts
trowel
trowel's
trowelled
trowelling
trowels
truancy
truancy's
truant
truant's
truanted
truanting
truants
truce
truce's
truces
truck
truck's
trucked
trucker
trucker's
truckers
trucking
trucking's
truckload
truckload's
truckloads
trucks
truculent
trudge
trudged
trudges
trudging
true
trued
trueing
truer
trues
truest
truffle
truffle's
truffles
truing
truism
truism's
truisms
truly
trump
trump's
trumped
trumpet
trumpet's
trumpeted
trumpeter
trumpeter's
trumpeters
trumpeting
trumpets
trumping
trumps
truncate
truncated
truncates
truncating
truncation
truncation's
trundle
trundled
trundles
trundling
trunk
trunk's
trunked
trunking
trunks
trust
trust's
trusted
trustee
trustee's
trustees
trustful
trustier
trusties
trustiest
trusting
trusts
trustworthier
trustworthiest
trustworthy
trusty
trusty's
truth
truth's
truthful
truthfully
truthfulness
truths
try
trying
tryings
tryout
tryout's
tryouts
ts
tsar
tsar's
tsars
tub
tub's
tuba
tuba's
tubae
tubas
tubbier
tubbiest
tubby
tube
tube's
tubed
tuberculosis
tuberculosis's
tubes
tubing
tubing's
tubs
tubular
tuck
tucked
tucking
tucks
tuft
tuft's
tufted
tufting
tufts
tug
tugboat
tugboat's
tugboats
tugged
tugging
tugs
tuition
tuition's
tulip
tulip's
tulips
tumble
tumbled
tumbler
tumbler's
tumblers
tumbles
tumbling
tummies
tummy
tummy's
tumour
tumour's
tumours
tumult
tumult's
tumulted
tumulting
tumults
tumultuous
tuna
tuna's
tunas
tundra
tundra's
tundras
tune
tune's
tuned
tuneful
tuner
tuner's
tuners
tunes
tunic
tunic's
tunics
tuning
tuning's
tunnel
tunnel's
tunnelled
tunnelling
tunnellings
tunnels
turban
turban's
turbans
turbine
turbine's
turbines
turbulence
turbulence's
turbulent
turd
turd's
turds
tureen
tureen's
tureens
turf
turf's
turfed
turfing
turfs
turgid
turkey
turkey's
turkeys
turmoil
turmoil's
turmoiled
turmoiling
turmoils
turn
turnaround
turnaround's
turnarounds
turncoat
turncoat's
turncoats
turned
turner
turner's
turning
turning's
turnip
turnip's
turniped
turniping
turnips
turnout
turnout's
turnouts
turnover
turnover's
turnovers
turnpike
turnpike's
turnpikes
turnround
turns
turnstile
turnstile's
turnstiles
turntable
turntable's
turntables
turpentine
turpentine's
turquoise
turquoise's
turquoises
turret
turret's
turrets
turtle
turtle's
turtleneck
turtleneck's
turtlenecks
turtles
turves
tush
tushed
tushes
tushing
tusk
tusk's
tusks
tussle
tussled
tussles
tussling
tutor
tutor's
tutored
tutorial
tutorial's
tutorials
tutoring
tutors
tux
tuxedo
tuxedo's
tuxedoes
tuxedos
tuxes
twang
twang's
twanged
twanging
twangs
tweak
tweaked
tweaking
tweaks
twee
tweed
tweed's
tweet
tweeted
tweeting
tweets
tweezers
twelfth
twelfths
twelve
twelve's
twelves
twenties
twentieth
twentieths
twenty
twenty's
twerp
twerp's
twerps
twice
twiddle
twiddled
twiddles
twiddling
twig
twig's
twigged
twigging
twigs
twilight
twilight's
twin
twine
twine's
twined
twines
twinge
twinge's
twinged
twingeing
twinges
twinging
twining
twinkle
twinkled
twinkles
twinkling
twinned
twinning
twins
twirl
twirled
twirling
twirls
twist
twisted
twister
twister's
twisters
twisting
twists
twit
twitch
twitched
twitches
twitching
twits
twitted
twitter
twittered
twittering
twitters
twitting
two
two's
twos
tycoon
tycoon's
tycoons
tying
tyke
tyke's
tykes
type
type's
typecast
typecasting
typecasts
typed
typeface
typeface's
typefaces
types
typescript
typescript's
typeset
typesets
typesetter
typesetter's
typesetting
typesetting's
typewrite
typewriter
typewriter's
typewriters
typewrites
typewriting
typewritten
typewrote
typhoid
typhoid's
typhoon
typhoon's
typhoons
typhus
typhus's
typical
typically
typified
typifies
typify
typifying
typing
typist
typist's
typists
typo
typo's
typographic
typographical
typos
tyrannical
tyrannies
tyrannise
tyrannised
tyrannises
tyrannising
tyranny
tyranny's
tyrant
tyrant's
tyrants
tyre
tyre's
tyred
tyres
tyring
u
ubiquitous
ubiquity
udder
udder's
udders
ugh
uglied
uglier
uglies
ugliest
ugliness
ugliness's
ugly
uglying
uh
ulcer
ulcer's
ulcered
ulcering
ulcers
ulterior
ultimata
ultimate
ultimated
ultimately
ultimates
ultimating
ultimatum
ultimatum's
ultimatums
ultra
ultrasonic
ultrasonics
ultrasound
ultrasound's
ultrasounds
ultraviolet
ultraviolet's
um
umbrella
umbrella's
umbrellaed
umbrellaing
umbrellas
umpire
umpire's
umpired
umpires
umpiring
umpteen
umpteenth
unabashed
unabated
unable
unabridged
unabridgeds
unacceptable
unacceptably
unaccepted
unaccompanied
unaccountable
unaccountably
unadulterated
unaffected
unaided
unaltered
unambiguous
unambiguously
unanimity
unanimity's
unanimous
unanimously
unanswerable
unanswered
unarmed
unassigned
unassuming
unattached
unattainable
unattended
unattractive
unauthorised
unavailable
unavoidable
unavoidably
unaware
unawares
unbalanced
unbearable
unbearably
unbeatable
unbeaten
unbecoming
unbelievable
unbelievably
unbeliever
unbelievers
unbiased
unbiassed
unblock
unblocked
unblocking
unblocks
unborn
unbounded
unbreakable
unbridled
unbroken
unburden
unburdened
unburdening
unburdens
unbutton
unbuttoned
unbuttoning
unbuttons
uncannier
uncanniest
uncannily
uncanny
unceasing
uncertain
uncertainly
uncertainties
uncertainty
uncertainty's
unchallenged
unchanged
uncharacteristic
uncharacteristically
uncharitable
uncharted
unchecked
unchristian
uncle
uncle's
unclean
uncleaner
uncleanest
unclear
unclearer
unclearest
uncled
uncles
uncling
uncomfortable
uncomfortably
uncommon
uncommoner
uncommonest
uncommonly
uncompromising
unconcerned
unconditional
unconditionally
unconfirmed
unconnected
unconscionable
unconscious
unconsciously
unconsciousness
unconsciousness's
unconstitutional
uncontrollable
uncontrollably
uncontrolled
uncontroversial
unconventional
unconvinced
unconvincing
uncountable
uncouth
uncover
uncovered
uncovering
uncovers
uncultured
uncut
undamaged
undaunted
undecidable
undecided
undecideds
undefined
undemocratic
undeniable
undeniably
under
underage
underbrush
underbrush's
underbrushed
underbrushes
underbrushing
underclass
underclassman
underclassmen
undercover
undercurrent
undercurrent's
undercurrents
undercut
undercuts
undercutting
underdog
underdog's
underdogs
underestimate
underestimated
underestimates
underestimating
underflow
underflow's
underfoot
undergarment
undergarment's
undergarments
undergo
undergoes
undergoing
undergone
undergrad
undergrad's
undergrads
undergraduate
undergraduate's
undergraduates
underground
underground's
undergrounds
undergrowth
undergrowth's
underhanded
underlain
underlay
underlays
underlie
underlies
underline
underlined
underlines
underlining
underlying
undermine
undermined
undermines
undermining
underneath
underneaths
undernourished
underpaid
underpants
underpass
underpass's
underpasses
underpay
underpaying
underpays
underprivileged
underrate
underrated
underrates
underrating
underscore
underscored
underscores
underscoring
undershirt
undershirt's
undershirts
underside
underside's
undersides
understaffed
understand
understandable
understandably
understanding
understanding's
understandings
understands
understate
understated
understatement
understatement's
understatements
understates
understating
understood
understudied
understudies
understudy
understudying
undertake
undertaken
undertaker
undertaker's
undertakers
undertakes
undertaking
undertaking's
undertakings
undertone
undertone's
undertones
undertook
undertow
undertow's
undertows
underwater
underwear
underwear's
underweight
underwent
underworld
underworld's
underworlds
underwrite
underwrites
underwriting
underwritten
underwrote
undeserved
undesirable
undesirables
undetected
undetermined
undeveloped
undid
undisclosed
undisturbed
undo
undocumented
undoes
undoing
undoing's
undoings
undone
undoubted
undoubtedly
undress
undressed
undresses
undressing
undue
unduly
undying
unearth
unearthed
unearthing
unearthly
unearths
unease
unease's
uneasier
uneasiest
uneasily
uneasiness
uneasiness's
uneasy
uneconomic
uneconomical
uneducated
unemployable
unemployed
unemployment
unemployment's
unending
unenlightened
unequal
unequalled
unequally
unequals
unequivocal
unerring
unethical
uneven
unevener
unevenest
unevenly
uneventful
unexpected
unexpectedly
unexplained
unfailing
unfair
unfairer
unfairest
unfairly
unfairness
unfaithful
unfamiliar
unfashionable
unfasten
unfastened
unfastening
unfastens
unfavourable
unfeasible
unfeeling
unfilled
unfinished
unfit
unfits
unfitted
unfitting
unfold
unfolded
unfolding
unfolds
unforeseen
unforgettable
unforgivable
unfortunate
unfortunately
unfortunates
unfounded
unfriendlier
unfriendliest
unfriendly
unfunny
unfurl
unfurled
unfurling
unfurls
ungainlier
ungainliest
ungainly
ungodlier
ungodliest
ungodly
ungrammatical
ungrateful
ungratefully
unhappier
unhappiest
unhappily
unhappiness
unhappiness's
unhappy
unhealthier
unhealthiest
unhealthy
unheard
unhelpful
unholier
unholiest
unholy
unhook
unhooked
unhooking
unhooks
unicorn
unicorn's
unicorns
unicycle
unicycle's
unidentified
unification
unification's
unified
unifies
uniform
uniform's
uniformed
uniformer
uniformest
uniforming
uniformity
uniformity's
uniformly
uniforms
unify
unifying
unilateral
unilaterally
unimaginative
unimportant
unimpressed
uninformative
uninformed
uninhabitable
uninhibited
uninitiated
uninspired
uninspiring
uninsured
unintelligent
unintelligible
unintended
unintentional
unintentionally
uninterested
uninteresting
union
union's
unionise
unionised
unionises
unionising
unions
unique
uniquely
uniqueness
uniquer
uniquest
unisex
unison
unison's
unit
unit's
unite
united
unites
unities
uniting
units
unity
unity's
universal
universally
universals
universe
universe's
universes
universities
university
university's
unjust
unjustifiable
unjustified
unjustly
unkempt
unkind
unkinder
unkindest
unkindlier
unkindliest
unkindly
unkindness
unknowingly
unknown
unknowns
unlabelled
unlawful
unleaded
unleash
unleashed
unleashes
unleashing
unless
unlike
unlikelier
unlikeliest
unlikely
unlikes
unlimited
unlisted
unload
unloaded
unloading
unloads
unlock
unlocked
unlocking
unlocks
unluckier
unluckiest
unlucky
unman
unmanned
unmanning
unmans
unmarked
unmarried
unmask
unmasked
unmasking
unmasks
unmistakable
unmistakably
unmitigated
unmodified
unmoved
unnamed
unnatural
unnaturally
unnecessarily
unnecessary
unnerve
unnerved
unnerves
unnerving
unnoticed
unobtainable
unobtrusive
unoccupied
unofficial
unofficially
unoriginal
unorthodox
unpack
unpacked
unpacking
unpacks
unpaid
unparallelled
unpick
unpleasant
unpleasantly
unpleasantness
unpleasantness's
unplug
unplugged
unplugging
unplugs
unpopular
unpopularity
unpopularity's
unprecedented
unpredictable
unprepared
unprincipled
unprintable
unprivileged
unproductive
unprofessional
unprofitable
unprotected
unproven
unprovoked
unpublished
unqualified
unquestionable
unquestionably
unquestioned
unravel
unravelled
unravelling
unravels
unread
unreadable
unreal
unrealistic
unreasonable
unreasonably
unrecognised
unrelated
unrelenting
unreliability
unreliability's
unreliable
unremarkable
unrepeatable
unrepresentative
unreserved
unreservedly
unresolved
unresponsive
unrest
unrest's
unrested
unresting
unrestrained
unrestricted
unrests
unrivalled
unroll
unrolled
unrolling
unrolls
unruffled
unrulier
unruliest
unruliness
unruliness's
unruly
unsafe
unsafer
unsafest
unsaid
unsanitary
unsatisfactory
unsatisfied
unsavoury
unsay
unsaying
unsays
unscathed
unscheduled
unscientific
unscrew
unscrewed
unscrewing
unscrews
unscrupulous
unseasonable
unseat
unseated
unseating
unseats
unseemlier
unseemliest
unseemly
unseen
unseens
unset
unsettle
unsettled
unsettles
unsettling
unsightlier
unsightliest
unsightly
unsigned
unskilled
unsolicited
unsolved
unsophisticated
unsound
unsounder
unsoundest
unspeakable
unspecified
unspoken
unsportsmanlike
unstable
unstabler
unstablest
unsteadier
unsteadiest
unsteady
unstoppable
unstructured
unstuck
unsubstantiated
unsuccessful
unsuccessfully
unsuitable
unsuited
unsung
unsupportable
unsupported
unsure
unsuspecting
untangle
untangled
untangles
untangling
untenable
unthinkable
unthinking
unthinkingly
untidier
untidiest
untidy
untie
untied
unties
until
untiled
untiles
untiling
untilled
untimelier
untimeliest
untimely
untiring
unto
untold
untouchable
untouchables
untouched
untoward
untrained
untried
untrue
untruer
untruest
untrustworthy
untruthful
untying
unusable
unused
unusual
unusually
unveil
unveiled
unveiling
unveils
unwanted
unwarranted
unwary
unwashed
unwelcome
unwell
unwell's
unwieldier
unwieldiest
unwieldy
unwilling
unwillingness
unwind
unwinding
unwinds
unwise
unwiser
unwisest
unwitting
unwittingly
unworkable
unworthy
unwound
unwrap
unwrapped
unwrapping
unwraps
unwritten
unyielding
unzip
unzipped
unzipping
unzips
up
upbeat
upbeat's
upbeats
upbringing
upbringing's
upbringings
upchuck
upchucked
upchucking
upchucks
upcoming
update
updated
updates
updating
upend
upended
upending
upends
upfront
upgrade
upgraded
upgrades
upgrading
upheaval
upheaval's
upheavals
upheld
uphill
uphills
uphold
upholding
upholds
upholster
upholstered
upholsterer
upholsterer's
upholsterers
upholstering
upholsters
upholstery
upholstery's
upkeep
upkeep's
uplift
uplifted
uplifting
upliftings
uplifts
upload
upon
upped
upper
uppercase
upperclassman
upperclassman's
upperclassmen
uppermost
uppers
upping
uppity
upright
uprights
uprising
uprising's
uprisings
uproar
uproar's
uproars
uproot
uprooted
uprooting
uproots
ups
upscale
upset
upsets
upsetting
upsetting's
upshot
upshot's
upshots
upside
upside's
upstage
upstaged
upstages
upstaging
upstairs
upstanding
upstart
upstart's
upstarted
upstarting
upstarts
upstate
upstream
upstreamed
upstreaming
upstreams
upsurge
upsurged
upsurges
upsurging
upswing
upswing's
upswings
uptake
uptake's
uptakes
uptight
uptown
upturn
upturned
upturning
upturns
upward
upwardly
upwards
uranium
uranium's
urban
urbane
urbaner
urbanest
urchin
urchin's
urchins
urge
urged
urgency
urgency's
urgent
urgently
urges
urging
urinate
urinated
urinates
urinating
urine
urine's
urn
urn's
urned
urning
urns
us
usable
usage
usage's
usages
use
used
useful
usefully
usefulness
usefulness's
useless
uselessly
uselessness
uselessness's
user
user's
users
uses
usher
usher's
ushered
ushering
ushers
using
usual
usually
usurp
usurped
usurping
usurps
utensil
utensil's
utensils
uteri
uterus
uterus's
uteruses
utilisation
utilisation's
utilise
utilised
utilises
utilising
utilitarian
utilitarianism
utilitarianism's
utilities
utility
utility's
utmost
utopia
utopian
utopians
utopias
utter
utterance
utterance's
utterances
uttered
utterer
utterest
uttering
utterly
utters
v
vacancies
vacancy
vacancy's
vacant
vacantly
vacate
vacated
vacates
vacating
vacation
vacation's
vacationed
vacationer
vacationers
vacationing
vacations
vaccinate
vaccinated
vaccinates
vaccinating
vaccination
vaccination's
vaccinations
vaccine
vaccine's
vaccines
vacillate
vacillated
vacillates
vacillating
vacua
vacuous
vacuum
vacuum's
vacuumed
vacuuming
vacuums
vagabond
vagabond's
vagabonded
vagabonding
vagabonds
vagaries
vagary
vagina
vagina's
vaginae
vaginal
vaginas
vagrant
vagrant's
vagrants
vague
vagued
vagueing
vaguely
vagueness
vagueness's
vaguer
vagues
vaguest
vain
vainer
vainest
vainly
valedictorian
valedictorian's
valedictorians
valentine
valentine's
valentines
valet
valet's
valeted
valeting
valets
valiant
valiantly
valid
validate
validated
validates
validating
validation
validation's
validity
validity's
validly
valise
valise's
valises
valley
valley's
valleys
valour
valour's
valuable
valuables
value
value's
valued
valueless
values
valuing
valve
valve's
valved
valves
valving
vampire
vampire's
vampired
vampires
vampiring
van
van's
vandal
vandal's
vandalise
vandalised
vandalises
vandalising
vandalism
vandalism's
vandals
vane
vane's
vanes
vanguard
vanguard's
vanguards
vanilla
vanilla's
vanillas
vanish
vanished
vanishes
vanishing
vanishings
vanities
vanity
vanity's
vanned
vanning
vanquish
vanquished
vanquishes
vanquishing
vans
vapour
vapour's
vapourise
vapourised
vapourises
vapourising
vapours
variability
variability's
variable
variables
variance
variance's
variances
variant
variants
variation
variation's
variations
varied
varies
varieties
variety
variety's
various
variously
varnish
varnish's
varnished
varnishes
varnishing
varsities
varsity
varsity's
vary
varying
vase
vase's
vasectomies
vasectomy
vasectomy's
vases
vast
vaster
vastest
vastly
vastness
vastness's
vasts
vat
vat's
vats
vatted
vatting
vault
vault's
vaulted
vaulting
vaults
veal
veal's
vealed
vealing
veals
vector
vector's
vectors
veer
veered
veering
veers
vegan
vegan's
vegans
vegetable
vegetable's
vegetables
vegetarian
vegetarian's
vegetarianism
vegetarianism's
vegetarians
vegetation
vegetation's
veggie
veggies
vehement
vehemently
vehicle
vehicle's
vehicles
vehicular
veil
veil's
veiled
veiling
veils
vein
vein's
veined
veining
veins
velocities
velocity
velocity's
velour
velour's
velvet
velvet's
velveted
velvetier
velvetiest
velveting
velvets
velvety
vend
vended
vendetta
vendetta's
vendettas
vending
vendor
vendor's
vendors
vends
veneer
veneer's
veneered
veneering
veneers
venerable
venerate
venerated
venerates
venerating
veneration
veneration's
vengeance
vengeance's
vengeful
venison
venison's
venom
venom's
venomous
vent
vent's
vented
ventilate
ventilated
ventilates
ventilating
ventilation
ventilation's
ventilator
ventilator's
ventilators
venting
ventricle
ventricle's
ventricles
ventriloquism
ventriloquism's
ventriloquist
ventriloquist's
ventriloquists
vents
venture
ventured
ventures
venturing
venue
venue's
venues
veracity
veracity's
veranda
veranda's
verandas
verb
verb's
verbal
verballed
verballing
verbally
verbals
verbatim
verbiage
verbiage's
verbose
verbosity
verbosity's
verbs
verdict
verdict's
verdicts
verge
verge's
verged
verges
verging
verier
veriest
verification
verified
verifies
verify
verifying
veritable
vermin
vermin's
vernacular
vernaculars
versatile
versatility
versatility's
verse
verse's
versed
verses
versing
version
version's
versions
versus
vertebra
vertebra's
vertebrae
vertebras
vertebrate
vertebrate's
vertebrates
vertical
vertically
verticals
vertices
vertices's
vertigo
vertigo's
verve
verve's
very
vessel
vessel's
vessels
vest
vest's
vested
vestibule
vestibule's
vestibules
vestige
vestige's
vestiges
vesting
vestment
vestment's
vestments
vests
vet
vet's
veteran
veteran's
veterans
veterinarian
veterinarian's
veterinarians
veterinaries
veterinary
veto
veto's
vetoed
vetoes
vetoing
vets
vetted
vetting
vex
vexation
vexation's
vexations
vexed
vexes
vexing
via
viability
viability's
viable
viaduct
viaduct's
viaducts
vial
vial's
vials
vibe
vibes
vibrant
vibrate
vibrated
vibrates
vibrating
vibration
vibration's
vibrations
vicar
vicar's
vicarious
vicariously
vicars
vice
vice's
viced
vices
vicing
vicinity
vicinity's
vicious
viciously
victim
victim's
victimisation
victimisation's
victimise
victimised
victimises
victimising
victims
victor
victor's
victories
victorious
victors
victory
victory's
video
video's
videocassette
videocassettes
videoed
videoing
videos
videotape
videotaped
videotapes
videotaping
vie
vied
vies
view
view's
viewed
viewer
viewer's
viewers
viewing
viewing's
viewings
viewpoint
viewpoint's
viewpoints
views
vigil
vigil's
vigilance
vigilance's
vigilant
vigilante
vigilante's
vigilantes
vigils
vigorous
vigorously
vigour
vigour's
vile
viler
vilest
vilified
vilifies
vilify
vilifying
villa
villa's
villae
village
village's
villager
villager's
villagers
villages
villain
villain's
villainies
villainous
villains
villainy
villainy's
villas
vindicate
vindicated
vindicates
vindicating
vindication
vindication's
vindications
vindictive
vine
vine's
vined
vinegar
vinegar's
vines
vineyard
vineyard's
vineyards
vining
vintage
vintage's
vintages
vinyl
vinyl's
vinyls
viola
viola's
violas
violate
violated
violates
violating
violation
violations
violence
violence's
violent
violently
violet
violet's
violets
violin
violin's
violinist
violinist's
violinists
violins
viper
viper's
vipers
viral
virgin
virgin's
virginity
virginity's
virgins
virile
virility
virility's
virtual
virtually
virtue
virtue's
virtues
virtuosi
virtuoso
virtuoso's
virtuosos
virtuous
virtuously
virulent
virus
virus's
viruses
visa
visa's
visaed
visage
visage's
visages
visaing
visas
viscosity
viscosity's
viscous
vise
vise's
vised
vises
visibility
visibility's
visible
visibly
vising
vision
vision's
visionaries
visionary
visioned
visioning
visions
visit
visitation
visitation's
visitations
visited
visiting
visitor
visitor's
visitors
visits
visor
visor's
visors
vista
vista's
vistaed
vistaing
vistas
visual
visualise
visualised
visualises
visualising
visually
visuals
vital
vitality
vitality's
vitally
vitals
vitamin
vitamin's
vitamins
vitriolic
vivacious
vivaciously
vivacity
vivacity's
vivid
vivider
vividest
vividly
vivisection
vivisection's
vocabularies
vocabulary
vocabulary's
vocal
vocalist
vocalist's
vocalists
vocals
vocation
vocation's
vocational
vocations
vociferous
vociferously
vodka
vodka's
vogue
vogue's
vogued
vogueing
vogues
voguing
voice
voice's
voiced
voices
voicing
void
voided
voiding
voids
volatile
volatility
volatility's
volcanic
volcanics
volcano
volcano's
volcanoes
volcanos
voled
voling
volition
volition's
volley
volley's
volleyball
volleyball's
volleyballs
volleyed
volleying
volleys
volt
volt's
voltage
voltage's
voltages
volts
volume
volume's
volumed
volumes
voluming
voluminous
voluntaries
voluntarily
voluntary
volunteer
volunteer's
volunteered
volunteering
volunteers
voluptuous
vomit
vomited
vomiting
vomits
voodoo
voodoo's
voodooed
voodooing
voodoos
voracious
voracity
voracity's
vortex
vortex's
vortexes
vortices
vortices's
vote
vote's
voted
voter
voter's
voters
votes
voting
vouch
vouched
voucher
voucher's
vouchers
vouches
vouching
vow
vow's
vowed
vowel
vowel's
vowels
vowing
vows
voyage
voyage's
voyaged
voyager
voyager's
voyagers
voyages
voyaging
voyeur
voyeur's
voyeurism
voyeurism's
voyeurs
vs
vulgar
vulgarer
vulgarest
vulgarities
vulgarity
vulgarity's
vulnerabilities
vulnerability
vulnerable
vulture
vulture's
vultures
vying
w
wackier
wackiest
wacky
wad
wad's
wadded
wadding
waddle
waddled
waddles
waddling
wade
waded
wades
wading
wads
wafer
wafer's
wafers
waffle
waffle's
waffled
waffles
waffling
waft
wafted
wafting
wafts
wag
wage
wage's
waged
wager
wager's
wagered
wagering
wagers
wages
wagged
wagging
waggon
waggon's
waggons
waging
wags
waif
waif's
waifed
waifing
waifs
wail
wailed
wailing
wails
waist
waist's
waistband
waistband's
waistbands
waisted
waisting
waistline
waistline's
waistlines
waists
wait
waited
waiter
waiter's
waiters
waiting
waitress
waitress's
waitresses
waits
waive
waived
waiver
waiver's
waivers
waives
waiving
wake
wake's
waked
waken
waken's
wakened
wakening
wakens
wakes
waking
walk
walked
walker
walker's
walkers
walking
walkout
walkout's
walkouts
walks
wall
wall's
walled
wallet
wallet's
wallets
walling
wallop
walloped
walloping
wallops
wallow
wallowed
wallowing
wallows
wallpaper
wallpaper's
wallpapered
wallpapering
wallpapers
walls
walnut
walnut's
walnuts
walrus
walrus's
walruses
waltz
waltz's
waltzed
waltzes
waltzing
wan
wand
wand's
wander
wandered
wanderer
wanderer's
wanderers
wandering
wanders
wands
wane
waned
wanes
waning
wanna
wannabe
wannabes
wanner
wannest
want
wanted
wanting
wantings
wanton
wantoned
wantoner
wantoning
wantons
wants
war
warble
warbled
warbles
warbling
ward
ward's
warded
warden
warden's
wardened
wardening
wardens
warding
wardrobe
wardrobe's
wardrobes
wards
ware
ware's
warehouse
warehouse's
warehoused
warehouses
warehousing
wares
warfare
warfare's
warhead
warhead's
warheads
warier
wariest
warily
warlike
warlock
warlock's
warlocks
warlord
warlord's
warlords
warm
warmed
warmer
warmer's
warmest
warming
warmly
warmonger
warmonger's
warmongering
warmongering's
warmongers
warms
warmth
warmth's
warn
warned
warning
warning's
warnings
warns
warp
warpath
warpath's
warpaths
warped
warping
warps
warrant
warrant's
warranted
warrantied
warranties
warranting
warrants
warranty
warranty's
warrantying
warred
warren
warren's
warrens
warring
warring's
warrior
warrior's
warriors
wars
warship
warship's
warships
wart
wart's
wartime
wartime's
warts
wary
was
wases
wash
washable
washables
washbasin
washbasin's
washbasins
washcloth
washcloth's
washcloths
washed
washer
washer's
washered
washering
washers
washes
washing
washing's
washout
washout's
washouts
washroom
washroom's
washrooms
wasn't
wasp
wasp's
wasps
wastage
wastage's
waste
wastebasket
wastebasket's
wastebaskets
wasted
wasteful
wastefully
wasteland
wasteland's
wastelands
wastes
wasting
watch
watchdog
watchdog's
watchdogs
watched
watches
watchful
watching
watchmaker
watchmaker's
watchmakers
watchman
watchman's
watchmen
watchword
watchword's
watchwords
water
water's
waterbed
waterbeds
watercolour
watercolour's
watercolours
watered
waterfall
waterfall's
waterfalls
waterfront
waterfront's
waterfronts
waterier
wateriest
watering
watering's
waterlogged
watermark
watermark's
watermarked
watermarking
watermarks
watermelon
watermelon's
watermelons
waterproof
waterproofed
waterproofing
waterproofs
waters
watershed
watershed's
watersheds
watertight
waterway
waterway's
waterways
waterworks
waterworks's
watery
watt
watt's
watter
wattest
watts
wave
waved
waveform
waveform's
wavelength
wavelength's
wavelengths
waver
wavered
wavering
wavers
waves
wavier
waviest
waving
wavy
wax
wax's
waxed
waxes
waxier
waxiest
waxiness
waxiness's
waxing
waxy
way
way's
waylaid
waylay
waylaying
waylays
ways
wayside
wayside's
waysides
wayward
we
we'd
we'll
we're
we've
weak
weaken
weakened
weakening
weakens
weaker
weakest
weaklier
weakliest
weakling
weakling's
weakly
weakness
weakness's
weaknesses
wealth
wealth's
wealthier
wealthiest
wealthy
wean
weaned
weaning
weans
weapon
weapon's
weaponry
weaponry's
weapons
wear
wearied
wearier
wearies
weariest
wearily
weariness
weariness's
wearing
wearisome
wears
weary
wearying
weasel
weasel's
weaselled
weaselling
weasels
weather
weather's
weathered
weathering
weathers
weave
weaved
weaver
weaver's
weavers
weaves
weaving
web
web's
webbed
webbing
webs
website
websites
wed
wedded
wedder
wedding
wedding's
weddings
wedge
wedge's
wedged
wedges
wedging
wedlock
wedlock's
weds
wee
weed
weed's
weeded
weedier
weediest
weeding
weeds
weedy
weeing
week
week's
weekday
weekday's
weekdays
weekend
weekend's
weekended
weekending
weekends
weeklies
weekly
weeknight
weeknight's
weeknights
weeks
weep
weeping
weeps
weer
wees
weest
weigh
weighed
weighing
weighs
weight
weight's
weighted
weightier
weightiest
weighting
weighting's
weightless
weightlessness
weightlessness's
weightlifter
weightlifters
weightlifting
weightlifting's
weights
weighty
weird
weirded
weirder
weirdest
weirding
weirdness
weirdness's
weirdo
weirdo's
weirdos
weirds
welcome
welcomed
welcomes
welcoming
weld
welded
welder
welder's
welders
welding
welds
welfare
welfare's
well
welled
welling
wellington
wells
welsh
welshed
welshes
welshing
welt
welt's
welted
welter
weltered
weltering
welters
welting
welts
went
wept
were
weren't
werewolf
werewolf's
werewolves
west
west's
westbound
wested
westerlies
westerly
western
westerner
westerner's
westerners
westernise
westernised
westernises
westernising
westerns
westing
wests
westward
westwards
wet
wetback
wetback's
wetbacks
wets
wetted
wetter
wettest
wetting
whack
whacked
whacking
whacks
whale
whale's
whaled
whaler
whaler's
whalers
whales
whaling
whaling's
wham
wham's
whammed
whamming
whams
wharf
wharf's
wharves
what
what's
whatchamacallit
whatchamacallits
whatever
whats
whatsoever
wheat
wheat's
wheedle
wheedled
wheedles
wheedling
wheel
wheel's
wheelbarrow
wheelbarrow's
wheelbarrows
wheelchair
wheelchair's
wheelchairs
wheeled
wheeling
wheels
wheeze
wheezed
wheezes
wheezing
when
whence
whenever
whens
where
whereabouts
whereas
whereby
wherein
wheres
whereupon
wherever
wherewithal
wherewithal's
whet
whether
whets
whetted
whetting
whew
whewed
whewing
whews
which
whichever
whiff
whiff's
whiffed
whiffing
whiffs
while
whiled
whiles
whiling
whilst
whim
whim's
whimmed
whimming
whimper
whimpered
whimpering
whimpers
whims
whimsical
whine
whine's
whined
whiner
whiners
whines
whining
whinnied
whinnier
whinnies
whinniest
whinny
whinnying
whip
whiplash
whiplash's
whiplashes
whipped
whipping
whipping's
whippings
whips
whips's
whir
whirl
whirled
whirling
whirlpool
whirlpool's
whirlpools
whirls
whirlwind
whirlwind's
whirlwinds
whirr
whirred
whirring
whirrs
whirs
whisk
whisked
whisker
whisker's
whiskered
whiskers
whiskey
whiskey's
whiskeys
whiskies
whisking
whisks
whisky
whisky's
whiskys
whisper
whispered
whispering
whispers
whistle
whistled
whistles
whistling
whistling's
white
whiten
whitened
whitening
whitens
whiter
whites
whitest
whitewash
whitewash's
whitewashed
whitewashes
whitewashing
whittle
whittled
whittles
whittling
whizz
whizzed
whizzes
whizzing
who
who'd
who'll
who're
who's
who've
whoa
whodunit
whodunit's
whodunits
whoever
whole
wholehearted
wholeheartedly
wholes
wholesale
wholesale's
wholesaled
wholesaler
wholesaler's
wholesalers
wholesales
wholesaling
wholesome
wholly
whom
whoop
whooped
whooping
whoops
whoosh
whoosh's
whooshed
whooshes
whooshing
whopper
whopper's
whoppers
whore
whore's
whores
whose
why
whys
wick
wick's
wicked
wickeder
wickedest
wickedly
wickedness
wickedness's
wicker
wicker's
wickers
wicket
wicket's
wickets
wicks
wide
widely
widen
widened
widening
widens
wider
widespread
widest
widow
widow's
widowed
widower
widower's
widowers
widowing
widows
width
width's
widths
wield
wielded
wielding
wields
wiener
wiener's
wieners
wife
wife's
wig
wig's
wigged
wigging
wiggle
wiggled
wiggles
wiggling
wigs
wigwam
wigwam's
wigwams
wild
wildcat
wildcats
wildcatted
wildcatting
wilded
wilder
wilderness
wilderness's
wildernesses
wildest
wildfire
wildfire's
wildfires
wilding
wildlife
wildlife's
wildly
wildness
wildness's
wilds
wile
wiles
wilful
wilfully
wilier
wiliest
will
willed
willing
willinger
willingest
willingly
willingness
willingness's
willow
willow's
willowier
willowiest
willows
willowy
willpower
willpower's
wills
wilt
wilted
wilting
wilts
wily
wimp
wimped
wimpier
wimpiest
wimping
wimps
wimpy
win
wince
winced
winces
winch
winch's
winched
winches
winching
wincing
wind
wind's
windbreaker
windbreakers
winded
windfall
windfall's
windfalls
windier
windiest
winding
winding's
windmill
windmill's
windmilled
windmilling
windmills
window
window's
windowing
windowpane
windowpane's
windowpanes
windows
windowsill
windowsill's
windowsills
windpipe
windpipe's
windpipes
winds
windscreen
windscreen's
windscreens
windshield
windshield's
windshields
windsurf
windsurfed
windsurfing
windsurfs
windswept
windy
wine
wine's
wined
wineglass
wineglass's
wineglasses
wines
wing
wing's
winged
wingers
winging
wings
wingspan
wingspan's
wingspans
wingtip
wingtips
wining
wink
winked
winking
winks
winner
winner's
winners
winning
winnings
wino
wino's
winos
wins
winsome
winsomer
winsomest
winter
winter's
wintered
wintering
winters
wintertime
wintertime's
wintrier
wintriest
wintry
wipe
wiped
wiper
wiper's
wipers
wipes
wiping
wire
wire's
wired
wires
wiretap
wiretap's
wiretapped
wiretapping
wiretaps
wirier
wiriest
wiring
wiring's
wiry
wisdom
wisdom's
wise
wisecrack
wisecrack's
wisecracked
wisecracking
wisecracks
wiselier
wiseliest
wisely
wiser
wises
wisest
wish
wishbone
wishbone's
wishbones
wished
wishes
wishful
wishing
wisp
wisp's
wispier
wispiest
wisps
wispy
wist
wistful
wistfully
wit
wit's
witch
witch's
witchcraft
witchcraft's
witched
witches
witching
wite
with
withdraw
withdrawal
withdrawal's
withdrawals
withdrawing
withdrawn
withdraws
withdrew
withe
withed
wither
withered
withering
withers
withes
withheld
withhold
withholding
withholds
within
withing
without
withs
withstand
withstanding
withstands
withstood
witless
witness
witness's
witnessed
witnesses
witnessing
wits
witticism
witticism's
witticisms
wittier
wittiest
witting
witty
wive
wives
wives's
wizard
wizard's
wizards
wizened
wobble
wobbled
wobbles
wobblier
wobblies
wobbliest
wobbling
wobbly
woe
woe's
woebegone
woes
wok
wok's
woke
woken
woks
wolf
wolf's
wolfed
wolfing
wolfs
wolves
wolves's
woman
woman's
womanhood
womanhood's
womankind
womankind's
womb
womb's
wombat
wombat's
wombats
wombs
women
women's
won
won't
wonder
wonder's
wondered
wonderful
wonderfully
wondering
wonderland
wonderland's
wonderlands
wonders
wondrous
wont
wont's
woo
wood
wood's
woodchuck
woodchuck's
woodchucks
wooded
wooden
woodener
woodenest
woodier
woodies
woodiest
wooding
woodland
woodland's
woodlands
woodpecker
woodpecker's
woodpeckers
woods
woodsman
woodsman's
woodsmen
woodwind
woodwinds
woodwork
woodwork's
woody
wooed
woof
woof's
woofed
woofing
woofs
wooing
wool
wool's
woolie
woolier
woolies
wooliest
woollen
woollens
woollier
woollies
woolliest
woolly
wooly
woos
woozier
wooziest
woozy
word
word's
worded
wordier
wordiest
wording
wording's
wordings
words
wordy
wore
work
work's
workable
workaholic
workaholics
workbench
workbench's
workbenches
workbook
workbook's
workbooks
worked
worker
worker's
workers
workfare
workforce
working
working's
workings
workload
workload's
workloads
workman
workman's
workmanlike
workmanship
workmanship's
workmen
workout
workout's
workouts
workplace
works
worksheet
worksheets
workshop
workshop's
workshops
workstation
workstations
world
world's
worldlier
worldliest
worldly
worlds
worldwide
worm
worm's
wormed
wormhole
wormholes
worming
worms
worn
worried
worries
worrisome
worry
worrying
worryings
worse
worsen
worsened
worsening
worsens
worship
worshipped
worshipper
worshippers
worshipping
worships
worst
worsted
worsting
worsts
worth
worthier
worthies
worthiest
worthless
worthwhile
worthy
wost
wot
would
would've
wouldn't
woulds
wound
wound's
wounded
wounder
wounding
wounds
wove
woven
wovens
wow
wowed
wowing
wows
wrangle
wrangled
wrangler
wrangler's
wranglers
wrangles
wrangling
wrap
wrapped
wrapper
wrapper's
wrappers
wrapping
wrapping's
wrappings
wraps
wrapt
wrath
wrath's
wrathed
wrathing
wraths
wreak
wreaked
wreaking
wreaks
wreath
wreath's
wreathe
wreathed
wreathes
wreathing
wreaths
wreck
wreckage
wreckage's
wrecked
wrecker
wrecker's
wrecking
wrecks
wren
wren's
wrench
wrench's
wrenched
wrenches
wrenching
wrens
wrest
wrested
wresting
wrestle
wrestled
wrestler
wrestler's
wrestlers
wrestles
wrestling
wrestling's
wrests
wretch
wretch's
wretched
wretcheder
wretchedest
wretches
wried
wrier
wries
wriest
wriggle
wriggled
wriggles
wriggling
wright
wright's
wring
wringer
wringer's
wringers
wringing
wrings
wrinkle
wrinkle's
wrinkled
wrinkles
wrinkling
wrist
wrist's
wrists
wristwatch
wristwatch's
wristwatches
writ
writ's
writable
write
writer
writer's
writers
writes
writhe
writhed
writhes
writhing
writing
writing's
writings
writs
written
wrong
wrongdoer
wrongdoer's
wrongdoers
wrongdoing
wrongdoing's
wrongdoings
wronged
wronger
wrongest
wrongful
wrongfully
wronging
wrongly
wrongs
wrote
wrought
wrung
wry
wryer
wryest
wrying
wryly
x
xenophobia
xenophobia's
xenophobic
xylophone
xylophone's
xylophones
y
y'all
ya
yacht
yacht's
yachted
yachting
yachts
yak
yak's
yakked
yakking
yaks
yam
yam's
yams
yank
yanked
yanking
yanks
yap
yapped
yapping
yaps
yard
yard's
yards
yardstick
yardstick's
yardsticks
yarmulke
yarmulke's
yarmulkes
yarn
yarn's
yarns
yawn
yawned
yawning
yawns
yeah
yeahs
year
year's
yearbook
yearbook's
yearbooks
yearlies
yearling
yearling's
yearly
yearn
yearned
yearning
yearning's
yearnings
yearns
years
yeast
yeast's
yeasts
yell
yelled
yelling
yellow
yellow's
yellowed
yellower
yellowest
yellowing
yellowish
yellows
yells
yelp
yelped
yelping
yelps
yen
yen's
yens
yep
yeps
yes
yeses
yessed
yessing
yest
yesterday
yesterday's
yesterdays
yet
yeti
yeti's
yew
yew's
yews
yield
yielded
yielding
yields
yippee
yippees
yo
yodel
yodelled
yodelling
yodels
yoga
yoga's
yogurt
yogurt's
yogurts
yoke
yoke's
yoked
yokel
yokel's
yokels
yokes
yoking
yolk
yolk's
yolks
yonder
you
you'd
you'll
you're
you've
young
younger
youngest
youngster
youngster's
youngsters
your
yours
yourself
yourselves
yous
youth
youth's
youthful
youths
yowl
yowled
yowling
yowls
yuck
yucked
yuckier
yuckiest
yucking
yucks
yucky
yum
yummier
yummiest
yummy
yuppie
yuppies
yuppy
z
zanied
zanier
zanies
zaniest
zany
zanying
zap
zapped
zapping
zaps
zeal
zeal's
zealous
zealously
zebra
zebra's
zebras
zenith
zenith's
zeniths
zero
zero's
zeroed
zeroes
zeroing
zeros
zest
zest's
zests
zeta
zeta's
zigzag
zigzag's
zigzagged
zigzagging
zigzags
zillion
zillion's
zillions
zinc
zinc's
zinced
zincing
zincked
zincking
zincs
zip
zip's
zipped
zipper
zipper's
zippered
zippering
zippers
zipping
zips
zit
zits
zodiac
zodiac's
zodiacs
zombie
zombie's
zombies
zone
zone's
zoned
zones
zoning
zoo
zoo's
zoological
zoologist
zoologist's
zoologists
zoology
zoology's
zoom
zoomed
zooming
zooms
zoos
zucchini
zucchini's
zucchinis
clair
clair's
clairs
You have received this book through Project Gutenberg
Disclaimer:
All persons concerned disclaim any and all reponsbility
that this etext is perfectly accurate. No pretenses in
any manner are made that this text should be thought of
as an authoritative edition in any respect.
This book was TYPED in by Judy Boss
eng003@zeus.unomaha.edu on Internet
eng003@unoma1 on Bitnet
(Judy now has a scanner)
Another edition of Paradise Lost could also be available shortly.
(We still have to complete our copyright analysis to insure these
releases do not infringe on anyone's copyrights.)
Further information about Project Gutenberg is available at:
hart@vmd.cso.uiuc.edu on Internet
hart@uiucvmd on Bitnet
or send a SASLE (Self Address Stamped Legal Envelope) to:
Prof. Michael S. Hart
c/o Project Gutenberg
405 West Elm Street
Urbana, IL 61801-3231
PARADISE LOST
BOOK I.
Of Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,
With loss of EDEN, till one greater Man
Restore us, and regain the blissful Seat,
Sing Heav'nly Muse, that on the secret top
Of OREB, or of SINAI, didst inspire
That Shepherd, who first taught the chosen Seed,
In the Beginning how the Heav'ns and Earth
Rose out of CHAOS: Or if SION Hill
Delight thee more, and SILOA'S Brook that flow'd
Fast by the Oracle of God; I thence
Invoke thy aid to my adventrous Song,
That with no middle flight intends to soar
Above th' AONIAN Mount, while it pursues
Things unattempted yet in Prose or Rhime.
And chiefly Thou O Spirit, that dost prefer
Before all Temples th' upright heart and pure,
Instruct me, for Thou know'st; Thou from the first
Wast present, and with mighty wings outspread
Dove-like satst brooding on the vast Abyss
And mad'st it pregnant: What in me is dark
Illumine, what is low raise and support;
That to the highth of this great Argument
I may assert th' Eternal Providence,
And justifie the wayes of God to men.
Say first, for Heav'n hides nothing from thy view
Nor the deep Tract of Hell, say first what cause
Mov'd our Grand Parents in that happy State,
Favour'd of Heav'n so highly, to fall off
From their Creator, and transgress his Will
For one restraint, Lords of the World besides?
Who first seduc'd them to that fowl revolt?
Th' infernal Serpent; he it was, whose guile
Stird up with Envy and Revenge, deceiv'd
The Mother of Mankinde, what time his Pride
Had cast him out from Heav'n, with all his Host
Of Rebel Angels, by whose aid aspiring
To set himself in Glory above his Peers,
He trusted to have equal'd the most High,
If he oppos'd; and with ambitious aim
Against the Throne and Monarchy of God
Rais'd impious War in Heav'n and Battel proud
With vain attempt. Him the Almighty Power
Hurld headlong flaming from th' Ethereal Skie
With hideous ruine and combustion down
To bottomless perdition, there to dwell
In Adamantine Chains and penal Fire,
Who durst defie th' Omnipotent to Arms.
Nine times the Space that measures Day and Night
To mortal men, he with his horrid crew
Lay vanquisht, rowling in the fiery Gulfe
Confounded though immortal: But his doom
Reserv'd him to more wrath; for now the thought
Both of lost happiness and lasting pain
Torments him; round he throws his baleful eyes
That witness'd huge affliction and dismay
Mixt with obdurate pride and stedfast hate:
At once as far as Angels kenn he views
The dismal Situation waste and wilde,
A Dungeon horrible, on all sides round
As one great Furnace flam'd, yet from those flames
No light, but rather darkness visible
Serv'd only to discover sights of woe,
Regions of sorrow, doleful shades, where peace
And rest can never dwell, hope never comes
That comes to all; but torture without end
Still urges, and a fiery Deluge, fed
With ever-burning Sulphur unconsum'd:
Such place Eternal Justice had prepar'd
For those rebellious, here their Prison ordain'd
In utter darkness, and their portion set
As far remov'd from God and light of Heav'n
As from the Center thrice to th' utmost Pole.
O how unlike the place from whence they fell!
There the companions of his fall, o'rewhelm'd
With Floods and Whirlwinds of tempestuous fire,
He soon discerns, and weltring by his side
One next himself in power, and next in crime,
Long after known in PALESTINE, and nam'd
BEELZEBUB. To whom th' Arch-Enemy,
And thence in Heav'n call'd Satan, with bold words
Breaking the horrid silence thus began.
If thou beest he; But O how fall'n! how chang'd
From him, who in the happy Realms of Light
Cloth'd with transcendent brightnes didst outshine
Myriads though bright: If he whom mutual league,
United thoughts and counsels, equal hope,
And hazard in the Glorious Enterprize,
Joynd with me once, now misery hath joynd
In equal ruin: into what Pit thou seest
From what highth fal'n, so much the stronger provd
He with his Thunder: and till then who knew
The force of those dire Arms? yet not for those
Nor what the Potent Victor in his rage
Can else inflict do I repent or change,
Though chang'd in outward lustre; that fixt mind
And high disdain, from sence of injur'd merit,
That with the mightiest rais'd me to contend,
And to the fierce contention brought along
Innumerable force of Spirits arm'd
That durst dislike his reign, and me preferring,
His utmost power with adverse power oppos'd
In dubious Battel on the Plains of Heav'n,
And shook his throne. What though the field be lost?
All is not lost; the unconquerable Will,
And study of revenge, immortal hate,
And courage never to submit or yield:
And what is else not to be overcome?
That Glory never shall his wrath or might
Extort from me. To bow and sue for grace
With suppliant knee, and deifie his power
Who from the terrour of this Arm so late
Doubted his Empire, that were low indeed,
That were an ignominy and shame beneath
This downfall; since by Fate the strength of Gods
And this Empyreal substance cannot fail,
Since through experience of this great event
In Arms not worse, in foresight much advanc't,
We may with more successful hope resolve
To wage by force or guile eternal Warr
Irreconcileable, to our grand Foe,
Who now triumphs, and in th' excess of joy
Sole reigning holds the Tyranny of Heav'n.
So spake th' Apostate Angel, though in pain,
Vaunting aloud, but rackt with deep despare:
And him thus answer'd soon his bold Compeer.
O Prince, O Chief of many Throned Powers,
That led th' imbattelld Seraphim to Warr
Under thy conduct, and in dreadful deeds
Fearless, endanger'd Heav'ns perpetual King;
And put to proof his high Supremacy,
Whether upheld by strength, or Chance, or Fate,
Too well I see and rue the dire event,
That with sad overthrow and foul defeat
Hath lost us Heav'n, and all this mighty Host
In horrible destruction laid thus low,
As far as Gods and Heav'nly Essences
Can Perish: for the mind and spirit remains
Invincible, and vigour soon returns,
Though all our Glory extinct, and happy state
Here swallow'd up in endless misery.
But what if he our Conquerour, (whom I now
Of force believe Almighty, since no less
Then such could hav orepow'rd such force as ours)
Have left us this our spirit and strength intire
Strongly to suffer and support our pains,
That we may so suffice his vengeful ire,
Or do him mightier service as his thralls
By right of Warr, what e're his business be
Here in the heart of Hell to work in Fire,
Or do his Errands in the gloomy Deep;
What can it then avail though yet we feel
Strength undiminisht, or eternal being
To undergo eternal punishment?
Whereto with speedy words th' Arch-fiend reply'd.
Fall'n Cherube, to be weak is miserable
Doing or Suffering: but of this be sure,
To do ought good never will be our task,
But ever to do ill our sole delight,
As being the contrary to his high will
Whom we resist. If then his Providence
Out of our evil seek to bring forth good,
Our labour must be to pervert that end,
And out of good still to find means of evil;
Which oft times may succeed, so as perhaps
Shall grieve him, if I fail not, and disturb
His inmost counsels from their destind aim.
But see the angry Victor hath recall'd
His Ministers of vengeance and pursuit
Back to the Gates of Heav'n: The Sulphurous Hail
Shot after us in storm, oreblown hath laid
The fiery Surge, that from the Precipice
Of Heav'n receiv'd us falling, and the Thunder,
Wing'd with red Lightning and impetuous rage,
Perhaps hath spent his shafts, and ceases now
To bellow through the vast and boundless Deep.
Let us not slip th' occasion, whether scorn,
Or satiate fury yield it from our Foe.
Seest thou yon dreary Plain, forlorn and wilde,
The seat of desolation, voyd of light,
Save what the glimmering of these livid flames
Casts pale and dreadful? Thither let us tend
From off the tossing of these fiery waves,
There rest, if any rest can harbour there,
And reassembling our afflicted Powers,
Consult how we may henceforth most offend
Our Enemy, our own loss how repair,
How overcome this dire Calamity,
What reinforcement we may gain from Hope,
If not what resolution from despare.
Thus Satan talking to his neerest Mate
With Head up-lift above the wave, and Eyes
That sparkling blaz'd, his other Parts besides
Prone on the Flood, extended long and large
Lay floating many a rood, in bulk as huge
As whom the Fables name of monstrous size,
TITANIAN, or EARTH-BORN, that warr'd on JOVE,
BRIARIOS or TYPHON, whom the Den
By ancient TARSUS held, or that Sea-beast
LEVIATHAN, which God of all his works
Created hugest that swim th' Ocean stream:
Him haply slumbring on the NORWAY foam
The Pilot of some small night-founder'd Skiff,
Deeming some Island, oft, as Sea-men tell,
With fixed Anchor in his skaly rind
Moors by his side under the Lee, while Night
Invests the Sea, and wished Morn delayes:
So stretcht out huge in length the Arch-fiend lay
Chain'd on the burning Lake, nor ever thence
Had ris'n or heav'd his head, but that the will
And high permission of all-ruling Heaven
Left him at large to his own dark designs,
That with reiterated crimes he might
Heap on himself damnation, while he sought
Evil to others, and enrag'd might see
How all his malice serv'd but to bring forth
Infinite goodness, grace and mercy shewn
On Man by him seduc't, but on himself
Treble confusion, wrath and vengeance pour'd.
Forthwith upright he rears from off the Pool
His mighty Stature; on each hand the flames
Drivn backward slope their pointing spires, & rowld
In billows, leave i'th' midst a horrid Vale.
Then with expanded wings he stears his flight
Aloft, incumbent on the dusky Air
That felt unusual weight, till on dry Land
He lights, if it were Land that ever burn'd
With solid, as the Lake with liquid fire;
And such appear'd in hue, as when the force
Of subterranean wind transports a Hill
Torn from PELORUS, or the shatter'd side
Of thundring AETNA, whose combustible
And fewel'd entrals thence conceiving Fire,
Sublim'd with Mineral fury, aid the Winds,
And leave a singed bottom all involv'd
With stench and smoak: Such resting found the sole
Of unblest feet. Him followed his next Mate,
Both glorying to have scap't the STYGIAN flood
As Gods, and by their own recover'd strength,
Not by the sufferance of supernal Power.
Is this the Region, this the Soil, the Clime,
Said then the lost Arch Angel, this the seat
That we must change for Heav'n, this mournful gloom
For that celestial light? Be it so, since hee
Who now is Sovran can dispose and bid
What shall be right: fardest from him is best
Whom reason hath equald, force hath made supream
Above his equals. Farewel happy Fields
Where Joy for ever dwells: Hail horrours, hail
Infernal world, and thou profoundest Hell
Receive thy new Possessor: One who brings
A mind not to be chang'd by Place or Time.
The mind is its own place, and in it self
Can make a Heav'n of Hell, a Hell of Heav'n.
What matter where, if I be still the same,
And what I should be, all but less then hee
Whom Thunder hath made greater? Here at least
We shall be free; th' Almighty hath not built
Here for his envy, will not drive us hence:
Here we may reign secure, and in my choyce
To reign is worth ambition though in Hell:
Better to reign in Hell, then serve in Heav'n.
But wherefore let we then our faithful friends,
Th' associates and copartners of our loss
Lye thus astonisht on th' oblivious Pool,
And call them not to share with us their part
In this unhappy Mansion, or once more
With rallied Arms to try what may be yet
Regaind in Heav'n, or what more lost in Hell?
So SATAN spake, and him BEELZEBUB
Thus answer'd. Leader of those Armies bright,
Which but th' Omnipotent none could have foyld,
If once they hear that voyce, their liveliest pledge
Of hope in fears and dangers, heard so oft
In worst extreams, and on the perilous edge
Of battel when it rag'd, in all assaults
Their surest signal, they will soon resume
New courage and revive, though now they lye
Groveling and prostrate on yon Lake of Fire,
As we erewhile, astounded and amaz'd,
No wonder, fall'n such a pernicious highth.
He scarce had ceas't when the superiour Fiend
Was moving toward the shore; his ponderous shield
Ethereal temper, massy, large and round,
Behind him cast; the broad circumference
Hung on his shoulders like the Moon, whose Orb
Through Optic Glass the TUSCAN Artist views
At Ev'ning from the top of FESOLE,
Or in VALDARNO, to descry new Lands,
Rivers or Mountains in her spotty Globe.
His Spear, to equal which the tallest Pine
Hewn on NORWEGIAN hills, to be the Mast
Of some great Ammiral, were but a wand,
He walkt with to support uneasie steps
Over the burning Marle, not like those steps
On Heavens Azure, and the torrid Clime
Smote on him sore besides, vaulted with Fire;
Nathless he so endur'd, till on the Beach
Of that inflamed Sea, he stood and call'd
His Legions, Angel Forms, who lay intrans't
Thick as Autumnal Leaves that strow the Brooks
In VALLOMBROSA, where th' ETRURIAN shades
High overarch't imbowr; or scatterd sedge
Afloat, when with fierce Winds ORION arm'd
Hath vext the Red-Sea Coast, whose waves orethrew
BUSIRIS and his MEMPHIAN Chivalrie,
VVhile with perfidious hatred they pursu'd
The Sojourners of GOSHEN, who beheld
From the safe shore their floating Carkases
And broken Chariot Wheels, so thick bestrown
Abject and lost lay these, covering the Flood,
Under amazement of their hideous change.
He call'd so loud, that all the hollow Deep
Of Hell resounded. Princes, Potentates,
Warriers, the Flowr of Heav'n, once yours, now lost,
If such astonishment as this can sieze
Eternal spirits; or have ye chos'n this place
After the toyl of Battel to repose
Your wearied vertue, for the ease you find
To slumber here, as in the Vales of Heav'n?
Or in this abject posture have ye sworn
To adore the Conquerour? who now beholds
Cherube and Seraph rowling in the Flood
With scatter'd Arms and Ensigns, till anon
His swift pursuers from Heav'n Gates discern
Th' advantage, and descending tread us down
Thus drooping, or with linked Thunderbolts
Transfix us to the bottom of this Gulfe.
Awake, arise, or be for ever fall'n.
They heard, and were abasht, and up they sprung
Upon the wing, as when men wont to watch
On duty, sleeping found by whom they dread,
Rouse and bestir themselves ere well awake.
Nor did they not perceave the evil plight
In which they were, or the fierce pains not feel;
Yet to their Generals Voyce they soon obeyd
Innumerable. As when the potent Rod
Of AMRAMS Son in EGYPTS evill day
Wav'd round the Coast, up call'd a pitchy cloud
Of LOCUSTS, warping on the Eastern Wind,
That ore the Realm of impious PHAROAH hung
Like Night, and darken'd all the Land of NILE:
So numberless were those bad Angels seen
Hovering on wing under the Cope of Hell
'Twixt upper, nether, and surrounding Fires;
Till, as a signal giv'n, th' uplifted Spear
Of their great Sultan waving to direct
Thir course, in even ballance down they light
On the firm brimstone, and fill all the Plain;
A multitude, like which the populous North
Pour'd never from her frozen loyns, to pass
RHENE or the DANAW, when her barbarous Sons
Came like a Deluge on the South, and spread
Beneath GIBRALTAR to the LYBIAN sands.
Forthwith from every Squadron and each Band
The Heads and Leaders thither hast where stood
Their great Commander; Godlike shapes and forms
Excelling human, Princely Dignities,
And Powers that earst in Heaven sat on Thrones;
Though of their Names in heav'nly Records now
Be no memorial, blotted out and ras'd
By thir Rebellion, from the Books of Life.
Nor had they yet among the Sons of EVE
Got them new Names, till wandring ore the Earth,
Through Gods high sufferance for the tryal of man,
By falsities and lyes the greatest part
Of Mankind they corrupted to forsake
God their Creator, and th' invisible
Glory of him, that made them, to transform
Oft to the Image of a Brute, adorn'd
With gay Religions full of Pomp and Gold,
And Devils to adore for Deities:
Then were they known to men by various Names,
And various Idols through the Heathen World.
Say, Muse, their Names then known, who first, who last,
Rous'd from the slumber, on that fiery Couch,
At thir great Emperors call, as next in worth
Came singly where he stood on the bare strand,
While the promiscuous croud stood yet aloof?
The chief were those who from the Pit of Hell
Roaming to seek their prey on earth, durst fix
Their Seats long after next the Seat of God,
Their Altars by his Altar, Gods ador'd
Among the Nations round, and durst abide
JEHOVAH thundring out of SION, thron'd
Between the Cherubim; yea, often plac'd
Within his Sanctuary it self their Shrines,
Abominations; and with cursed things
His holy Rites, and solemn Feasts profan'd,
And with their darkness durst affront his light.
First MOLOCH, horrid King besmear'd with blood
Of human sacrifice, and parents tears,
Though for the noyse of Drums and Timbrels loud
Their childrens cries unheard, that past through fire
To his grim Idol. Him the AMMONITE
Worshipt in RABBA and her watry Plain,
In ARGOB and in BASAN, to the stream
Of utmost ARNON. Nor content with such
Audacious neighbourhood, the wisest heart
Of SOLOMON he led by fraud to build
His Temple right against the Temple of God
On that opprobrious Hill, and made his Grove
The pleasant Vally of HINNOM, TOPHET thence
And black GEHENNA call'd, the Type of Hell.
Next CHEMOS, th' obscene dread of MOABS Sons,
From AROER to NEBO, and the wild
Of Southmost ABARIM; in HESEBON
And HERONAIM, SEONS Realm, beyond
The flowry Dale of SIBMA clad with Vines,
And ELEALE to th' ASPHALTICK Pool.
PEOR his other Name, when he entic'd
ISRAEL in SITTIM on their march from NILE
To do him wanton rites, which cost them woe.
Yet thence his lustful Orgies he enlarg'd
Even to that Hill of scandal, by the Grove
Of MOLOCH homicide, lust hard by hate;
Till good JOSIAH drove them thence to Hell.
With these came they, who from the bordring flood
Of old EUPHRATES to the Brook that parts
EGYPT from SYRIAN ground, had general Names
Of BAALIM and ASHTAROTH, those male,
These Feminine. For Spirits when they please
Can either Sex assume, or both; so soft
And uncompounded is their Essence pure,
Not ti'd or manacl'd with joynt or limb,
Nor founded on the brittle strength of bones,
Like cumbrous flesh; but in what shape they choose
Dilated or condens't, bright or obscure,
Can execute their aerie purposes,
And works of love or enmity fulfill.
For those the Race of ISRAEL oft forsook
Their living strength, and unfrequented left
His righteous Altar, bowing lowly down
To bestial Gods; for which their heads as low
Bow'd down in Battel, sunk before the Spear
Of despicable foes. With these in troop
Came ASTORETH, whom the PHOENICIANS call'd
ASTARTE, Queen of Heav'n, with crescent Horns;
To whose bright Image nightly by the Moon
SIDONIAN Virgins paid their Vows and Songs,
In SION also not unsung, where stood
Her Temple on th' offensive Mountain, built
By that uxorious King, whose heart though large,
Beguil'd by fair Idolatresses, fell
To Idols foul. THAMMUZ came next behind,
Whose annual wound in LEBANON allur'd
The SYRIAN Damsels to lament his fate
In amorous dittyes all a Summers day,
While smooth ADONIS from his native Rock
Ran purple to the Sea, suppos'd with blood
Of THAMMUZ yearly wounded: the Love-tale
Infected SIONS daughters with like heat,
Whose wanton passions in the sacred Porch
EZEKIEL saw, when by the Vision led
His eye survay'd the dark Idolatries
Of alienated JUDAH. Next came one
Who mourn'd in earnest, when the Captive Ark
Maim'd his brute Image, head and hands lopt off
In his own Temple, on the grunsel edge,
Where he fell flat, and sham'd his Worshipers:
DAGON his Name, Sea Monster, upward Man
And downward Fish: yet had his Temple high
Rear'd in AZOTUS, dreaded through the Coast
Of PALESTINE, in GATH and ASCALON,
And ACCARON and GAZA's frontier bounds.
Him follow'd RIMMON, whose delightful Seat
Was fair DAMASCUS, on the fertil Banks
Of ABBANA and PHARPHAR, lucid streams.
He also against the house of God was bold:
A Leper once he lost and gain'd a King,
AHAZ his sottish Conquerour, whom he drew
Gods Altar to disparage and displace
For one of SYRIAN mode, whereon to burn
His odious offrings, and adore the Gods
Whom he had vanquisht. After these appear'd
A crew who under Names of old Renown,
OSIRIS, ISIS, ORUS and their Train
With monstrous shapes and sorceries abus'd
Fanatic EGYPT and her Priests, to seek
Thir wandring Gods disguis'd in brutish forms
Rather then human. Nor did ISRAEL scape
Th' infection when their borrow'd Gold compos'd
The Calf in OREB: and the Rebel King
Doubl'd that sin in BETHEL and in DAN,
Lik'ning his Maker to the Grazed Ox,
JEHOVAH, who in one Night when he pass'd
From EGYPT marching, equal'd with one stroke
Both her first born and all her bleating Gods.
BELIAL came last, then whom a Spirit more lewd
Fell not from Heaven, or more gross to love
Vice for it self: To him no Temple stood
Or Altar smoak'd; yet who more oft then hee
In Temples and at Altars, when the Priest
Turns Atheist, as did ELY'S Sons, who fill'd
With lust and violence the house of God.
In Courts and Palaces he also Reigns
And in luxurious Cities, where the noyse
Of riot ascends above thir loftiest Towrs,
And injury and outrage: And when Night
Darkens the Streets, then wander forth the Sons
Of BELIAL, flown with insolence and wine.
Witness the Streets of SODOM, and that night
In GIBEAH, when hospitable Dores
Yielded thir Matrons to prevent worse rape.
These were the prime in order and in might;
The rest were long to tell, though far renown'd,
Th' IONIAN Gods, of JAVANS Issue held
Gods, yet confest later then Heav'n and Earth
Thir boasted Parents; TITAN Heav'ns first born
With his enormous brood, and birthright seis'd
By younger SATURN, he from mightier JOVE
His own and RHEA'S Son like measure found;
So JOVE usurping reign'd: these first in CREET
And IDA known, thence on the Snowy top
Of cold OLYMPUS rul'd the middle Air
Thir highest Heav'n; or on the DELPHIAN Cliff,
Or in DODONA, and through all the bounds
Of DORIC Land; or who with SATURN old
Fled over ADRIA to th' HESPERIAN Fields,
And ore the CELTIC roam'd the utmost Isles.
All these and more came flocking; but with looks
Down cast and damp, yet such wherein appear'd
Obscure som glimps of joy, to have found thir chief
Not in despair, to have found themselves not lost
In loss it self; which on his count'nance cast
Like doubtful hue: but he his wonted pride
Soon recollecting, with high words, that bore
Semblance of worth not substance, gently rais'd
Their fainted courage, and dispel'd their fears.
Then strait commands that at the warlike sound
Of Trumpets loud and Clarions be upreard
His mighty Standard; that proud honour claim'd
AZAZEL as his right, a Cherube tall:
Who forthwith from the glittering Staff unfurld
Th' Imperial Ensign, which full high advanc't
Shon like a Meteor streaming to the Wind
With Gemms and Golden lustre rich imblaz'd,
Seraphic arms and Trophies: all the while
Sonorous mettal blowing Martial sounds:
At which the universal Host upsent
A shout that tore Hells Concave, and beyond
Frighted the Reign of CHAOS and old Night.
All in a moment through the gloom were seen
Ten thousand Banners rise into the Air
With Orient Colours waving: with them rose
A Forrest huge of Spears: and thronging Helms
Appear'd, and serried Shields in thick array
Of depth immeasurable: Anon they move
In perfect PHALANX to the Dorian mood
Of Flutes and soft Recorders; such as rais'd
To highth of noblest temper Hero's old
Arming to Battel, and in stead of rage
Deliberate valour breath'd, firm and unmov'd
With dread of death to flight or foul retreat,
Nor wanting power to mitigate and swage
With solemn touches, troubl'd thoughts, and chase
Anguish and doubt and fear and sorrow and pain
From mortal or immortal minds. Thus they
Breathing united force with fixed thought
Mov'd on in silence to soft Pipes that charm'd
Thir painful steps o're the burnt soyle; and now
Advanc't in view they stand, a horrid Front
Of dreadful length and dazling Arms, in guise
Of Warriers old with order'd Spear and Shield,
Awaiting what command thir mighty Chief
Had to impose: He through the armed Files
Darts his experienc't eye, and soon traverse
The whole Battalion views, thir order due,
Thir visages and stature as of Gods,
Thir number last he summs. And now his heart
Distends with pride, and hardning in his strength
Glories: For never since created man,
Met such imbodied force, as nam'd with these
Could merit more then that small infantry
Warr'd on by Cranes: though all the Giant brood
Of PHLEGRA with th' Heroic Race were joyn'd
That fought at THEB'S and ILIUM, on each side
Mixt with auxiliar Gods; and what resounds
In Fable or ROMANCE of UTHERS Son
Begirt with BRITISH and ARMORIC Knights;
And all who since, Baptiz'd or Infidel
Jousted in ASPRAMONT or MONTALBAN,
DAMASCO, or MAROCCO, or TREBISOND,
Or whom BISERTA sent from AFRIC shore
When CHARLEMAIN with all his Peerage fell
By FONTARABBIA. Thus far these beyond
Compare of mortal prowess, yet observ'd
Thir dread Commander: he above the rest
In shape and gesture proudly eminent
Stood like a Towr; his form had yet not lost
All her Original brightness, nor appear'd
Less then Arch Angel ruind, and th' excess
Of Glory obscur'd: As when the Sun new ris'n
Looks through the Horizontal misty Air
Shorn of his Beams, or from behind the Moon
In dim Eclips disastrous twilight sheds
On half the Nations, and with fear of change
Perplexes Monarchs. Dark'n'd so, yet shon
Above them all th' Arch Angel: but his face
Deep scars of Thunder had intrencht, and care
Sat on his faded cheek, but under Browes
Of dauntless courage, and considerate Pride
Waiting revenge: cruel his eye, but cast
Signs of remorse and passion to behold
The fellows of his crime, the followers rather
(Far other once beheld in bliss) condemn'd
For ever now to have their lot in pain,
Millions of Spirits for his fault amerc't
Of Heav'n, and from Eternal Splendors flung
For his revolt, yet faithfull how they stood,
Thir Glory witherd. As when Heavens Fire
Hath scath'd the Forrest Oaks, or Mountain Pines,
With singed top their stately growth though bare
Stands on the blasted Heath. He now prepar'd
To speak; whereat their doubl'd Ranks they bend
From Wing to Wing, and half enclose him round
With all his Peers: attention held them mute.
Thrice he assayd, and thrice in spite of scorn,
Tears such as Angels weep, burst forth: at last
Words interwove with sighs found out their way.
O Myriads of immortal Spirits, O Powers
Matchless, but with th' Almighty, and that strife
Was not inglorious, though th' event was dire,
As this place testifies, and this dire change
Hateful to utter: but what power of mind
Foreseeing or presaging, from the Depth
Of knowledge past or present, could have fear'd,
How such united force of Gods, how such
As stood like these, could ever know repulse?
For who can yet beleeve, though after loss,
That all these puissant Legions, whose exile
Hath emptied Heav'n, shall faile to re-ascend
Self-rais'd, and repossess their native seat.
For me, be witness all the Host of Heav'n,
If counsels different, or danger shun'd
By me, have lost our hopes. But he who reigns
Monarch in Heav'n, till then as one secure
Sat on his Throne, upheld by old repute,
Consent or custome, and his Regal State
Put forth at full, but still his strength conceal'd,
Which tempted our attempt, and wrought our fall.
Henceforth his might we know, and know our own
So as not either to provoke, or dread
New warr, provok't; our better part remains
To work in close design, by fraud or guile
What force effected not: that he no less
At length from us may find, who overcomes
By force, hath overcome but half his foe.
Space may produce new Worlds; whereof so rife
There went a fame in Heav'n that he ere long
Intended to create, and therein plant
A generation, whom his choice regard
Should favour equal to the Sons of Heaven:
Thither, if but to prie, shall be perhaps
Our first eruption, thither or elsewhere:
For this Infernal Pit shall never hold
Caelestial Spirits in Bondage, nor th' Abysse
Long under darkness cover. But these thoughts
Full Counsel must mature: Peace is despaird,
For who can think Submission? Warr then, Warr
Open or understood must be resolv'd.
He spake: and to confirm his words, out-flew
Millions of flaming swords, drawn from the thighs
Of mighty Cherubim; the sudden blaze
Far round illumin'd hell: highly they rag'd
Against the Highest, and fierce with grasped arm's
Clash'd on their sounding shields the din of war,
Hurling defiance toward the vault of Heav'n.
There stood a Hill not far whose griesly top
Belch'd fire and rowling smoak; the rest entire
Shon with a glossie scurff, undoubted sign
That in his womb was hid metallic Ore,
The work of Sulphur. Thither wing'd with speed
A numerous Brigad hasten'd. As when bands
Of Pioners with Spade and Pickaxe arm'd
Forerun the Royal Camp, to trench a Field,
Or cast a Rampart. MAMMON led them on,
MAMMON, the least erected Spirit that fell
From heav'n, for ev'n in heav'n his looks & thoughts
Were always downward bent, admiring more
The riches of Heav'ns pavement, trod'n Gold,
Then aught divine or holy else enjoy'd
In vision beatific: by him first
Men also, and by his suggestion taught,
Ransack'd the Center, and with impious hands
Rifl'd the bowels of thir mother Earth
For Treasures better hid. Soon had his crew
Op'nd into the Hill a spacious wound
And dig'd out ribs of Gold. Let none admire
That riches grow in Hell; that soyle may best
Deserve the pretious bane. And here let those
Who boast in mortal things, and wondring tell
Of BABEL, and the works of MEMPHIAN Kings,
Learn how thir greatest Monuments of Fame,
And Strength and Art are easily outdone
By Spirits reprobate, and in an hour
What in an age they with incessant toyle
And hands innumerable scarce perform
Nigh on the Plain in many cells prepar'd,
That underneath had veins of liquid fire
Sluc'd from the Lake, a second multitude
With wondrous Art founded the massie Ore,
Severing each kinde, and scum'd the Bullion dross:
A third as soon had form'd within the ground
A various mould, and from the boyling cells
By strange conveyance fill'd each hollow nook,
As in an Organ from one blast of wind
To many a row of Pipes the sound-board breaths.
Anon out of the earth a Fabrick huge
Rose like an Exhalation, with the sound
Of Dulcet Symphonies and voices sweet,
Built like a Temple, where PILASTERS round
Were set, and Doric pillars overlaid
With Golden Architrave; nor did there want
Cornice or Freeze, with bossy Sculptures grav'n,
The Roof was fretted Gold. Not BABILON,
Nor great ALCAIRO such magnificence
Equal'd in all thir glories, to inshrine
BELUS or SERAPIS thir Gods, or seat
Thir Kings, when AEGYPT with ASSYRIA strove
In wealth and luxurie. Th' ascending pile
Stood fixt her stately highth, and strait the dores
Op'ning thir brazen foulds discover wide
Within, her ample spaces, o're the smooth
And level pavement: from the arched roof
Pendant by suttle Magic many a row
Of Starry Lamps and blazing Cressets fed
With Naphtha and ASPHALTUS yeilded light
As from a sky. The hasty multitude
Admiring enter'd, and the work some praise
And some the Architect: his hand was known
In Heav'n by many a Towred structure high,
Where Scepter'd Angels held thir residence,
And sat as Princes, whom the supreme King
Exalted to such power, and gave to rule,
Each in his Herarchie, the Orders bright.
Nor was his name unheard or unador'd
In ancient Greece; and in AUSONIAN land
Men call'd him MULCIBER; and how he fell
From Heav'n, they fabl'd, thrown by angry JOVE
Sheer o're the Chrystal Battlements: from Morn
To Noon he fell, from Noon to dewy Eve,
A Summers day; and with the setting Sun
Dropt from the Zenith like a falling Star,
On LEMNOS th' AEGAEAN Ile: thus they relate,
Erring; for he with this rebellious rout
Fell long before; nor aught avail'd him now
To have built in Heav'n high Towrs; nor did he scape
By all his Engins, but was headlong sent
With his industrious crew to build in hell.
Mean while the winged Haralds by command
Of Sovran power, with awful Ceremony
And Trumpets sound throughout the Host proclaim
A solemn Councel forthwith to be held
At PANDAEMONIUM, the high Capital
Of Satan and his Peers: thir summons call'd
From every and Band squared Regiment
By place or choice the worthiest; they anon
With hundreds and with thousands trooping came
Attended: all access was throng'd, the Gates
And Porches wide, but chief the spacious Hall
(Though like a cover'd field, where Champions bold
Wont ride in arm'd, and at the Soldans chair
Defi'd the best of Panim chivalry
To mortal combat or carreer with Lance)
Thick swarm'd, both on the ground and in the air,
Brusht with the hiss of russling wings. As Bees
In spring time, when the Sun with Taurus rides,
Poure forth thir populous youth about the Hive
In clusters; they among fresh dews and flowers
Flie to and fro, or on the smoothed Plank,
The suburb of thir Straw-built Cittadel,
New rub'd with Baume, expatiate and confer
Thir State affairs. So thick the aerie crowd
Swarm'd and were straitn'd; till the Signal giv'n,
Behold a wonder! they but now who seemd
In bigness to surpass Earths Giant Sons
Now less then smallest Dwarfs, in narrow room
Throng numberless, like that Pigmean Race
Beyond the INDIAN Mount, or Faerie Elves,
Whose midnight Revels, by a Forrest side
Or Fountain fome belated Peasant sees,
Or dreams he sees, while over head the Moon
Sits Arbitress, and neerer to the Earth
Wheels her pale course, they on thir mirth & dance
Intent, with jocond Music charm his ear;
At once with joy and fear his heart rebounds.
Thus incorporeal Spirits to smallest forms
Reduc'd thir shapes immense, and were at large,
Though without number still amidst the Hall
Of that infernal Court. But far within
And in thir own dimensions like themselves
The great Seraphic Lords and Cherubim
In close recess and secret conclave sat
A thousand Demy-Gods on golden seat's,
Frequent and full. After short silence then
And summons read, the great consult began.
THE END OF THE FIRST BOOK.
PARADISE LOST
BOOK II.
High on a Throne of Royal State, which far
Outshon the wealth of ORMUS and of IND,
Or where the gorgeous East with richest hand
Showrs on her Kings BARBARIC Pearl & Gold,
Satan exalted sat, by merit rais'd
To that bad eminence; and from despair
Thus high uplifted beyond hope, aspires
Beyond thus high, insatiate to pursue
Vain Warr with Heav'n, and by success untaught
His proud imaginations thus displaid.
Powers and Dominions, Deities of Heav'n,
For since no deep within her gulf can hold
Immortal vigor, though opprest and fall'n,
I give not Heav'n for lost. From this descent
Celestial vertues rising, will appear
More glorious and more dread then from no fall,
And trust themselves to fear no second fate:
Mee though just right, and the fixt Laws of Heav'n
Did first create your Leader, next, free choice,
With what besides, in Counsel or in Fight,
Hath bin achievd of merit, yet this loss
Thus farr at least recover'd, hath much more
Establisht in a safe unenvied Throne
Yeilded with full consent. The happier state
In Heav'n, which follows dignity, might draw
Envy from each inferior; but who here
Will envy whom the highest place exposes
Formost to stand against the Thunderers aime
Your bulwark, and condemns to greatest share
Of endless pain? where there is then no good
For which to strive, no strife can grow up there
From Faction; for none sure will claim in hell
Precedence, none, whose portion is so small
Of present pain, that with ambitious mind
Will covet more. With this advantage then
To union, and firm Faith, and firm accord,
More then can be in Heav'n, we now return
To claim our just inheritance of old,
Surer to prosper then prosperity
Could have assur'd us; and by what best way,
Whether of open Warr or covert guile,
We now debate; who can advise, may speak.
He ceas'd, and next him MOLOC, Scepter'd King
Stood up, the strongest and the fiercest Spirit
That fought in Heav'n; now fiercer by despair:
His trust was with th' Eternal to be deem'd
Equal in strength, and rather then be less
Car'd not to be at all; with that care lost
Went all his fear: of God, or Hell, or worse
He reckd not, and these words thereafter spake.
My sentence is for open Warr: Of Wiles,
More unexpert, I boast not: them let those
Contrive who need, or when they need, not now.
For while they sit contriving, shall the rest,
Millions that stand in Arms, and longing wait
The Signal to ascend, sit lingring here
Heav'ns fugitives, and for thir dwelling place
Accept this dark opprobrious Den of shame,
The Prison of his Tyranny who Reigns
By our delay? no, let us rather choose
Arm'd with Hell flames and fury all at once
O're Heav'ns high Towrs to force resistless way,
Turning our Tortures into horrid Arms
Against the Torturer; when to meet the noise
Of his Almighty Engin he shall hear
Infernal Thunder, and for Lightning see
Black fire and horror shot with equal rage
Among his Angels; and his Throne it self
Mixt with TARTAREAN Sulphur, and strange fire,
His own invented Torments. But perhaps
The way seems difficult and steep to scale
With upright wing against a higher foe.
Let such bethink them, if the sleepy drench
Of that forgetful Lake benumme not still,
That in our proper motion we ascend
Up to our native seat: descent and fall
To us is adverse. Who but felt of late
When the fierce Foe hung on our brok'n Rear
Insulting, and pursu'd us through the Deep,
With what compulsion and laborious flight
We sunk thus low? Th' ascent is easie then;
Th' event is fear'd; should we again provoke
Our stronger, some worse way his wrath may find
To our destruction: if there be in Hell
Fear to be worse destroy'd: what can be worse
Then to dwell here, driv'n out from bliss, condemn'd
In this abhorred deep to utter woe;
Where pain of unextinguishable fire
Must exercise us without hope of end
The Vassals of his anger, when the Scourge
Inexorably, and the torturing houre
Calls us to Penance? More destroy'd then thus
We should be quite abolisht and expire.
What fear we then? what doubt we to incense
His utmost ire? which to the highth enrag'd,
Will either quite consume us, and reduce
To nothing this essential, happier farr
Then miserable to have eternal being:
Or if our substance be indeed Divine,
And cannot cease to be, we are at worst
On this side nothing; and by proof we feel
Our power sufficient to disturb his Heav'n,
And with perpetual inrodes to Allarme,
Though inaccessible, his fatal Throne:
Which if not Victory is yet Revenge.
He ended frowning, and his look denounc'd
Desperate revenge, and Battel dangerous
To less then Gods. On th' other side up rose
BELIAL, in act more graceful and humane;
A fairer person lost not Heav'n; he seemd
For dignity compos'd and high exploit:
But all was false and hollow; though his Tongue
Dropt Manna, and could make the worse appear
The better reason, to perplex and dash
Maturest Counsels: for his thoughts were low;
To vice industrious, but to Nobler deeds
Timorous and slothful: yet he pleas'd the eare,
And with perswasive accent thus began.
I should be much for open Warr, O Peers,
As not behind in hate; if what was urg'd
Main reason to perswade immediate Warr,
Did not disswade me most, and seem to cast
Ominous conjecture on the whole success:
When he who most excels in fact of Arms,
In what he counsels and in what excels
Mistrustful, grounds his courage on despair
And utter dissolution, as the scope
Of all his aim, after some dire revenge.
First, what Revenge? the Towrs of Heav'n are fill'd
With Armed watch, that render all access
Impregnable; oft on the bordering Deep
Encamp thir Legions, or with obscure wing
Scout farr and wide into the Realm of night,
Scorning surprize. Or could we break our way
By force, and at our heels all Hell should rise
With blackest Insurrection, to confound
Heav'ns purest Light, yet our great Enemie
All incorruptible would on his Throne
Sit unpolluted, and th' Ethereal mould
Incapable of stain would soon expel
Her mischief, and purge off the baser fire
Victorious. Thus repuls'd, our final hope
Is flat despair: we must exasperate
Th' Almighty Victor to spend all his rage,
And that must end us, that must be our cure,
To be no more; sad cure; for who would loose,
Though full of pain, this intellectual being,
Those thoughts that wander through Eternity,
To perish rather, swallowd up and lost
In the wide womb of uncreated night,
Devoid of sense and motion? and who knows,
Let this be good, whether our angry Foe
Can give it, or will ever? how he can
Is doubtful; that he never will is sure.
Will he, so wise, let loose at once his ire,
Belike through impotence, or unaware,
To give his Enemies thir wish, and end
Them in his anger, whom his anger saves
To punish endless? wherefore cease we then?
Say they who counsel Warr, we are decreed,
Reserv'd and destin'd to Eternal woe;
Whatever doing, what can we suffer more,
What can we suffer worse? is this then worst,
Thus sitting, thus consulting, thus in Arms?
What when we fled amain, pursu'd and strook
With Heav'ns afflicting Thunder, and besought
The Deep to shelter us? this Hell then seem'd
A refuge from those wounds: or when we lay
Chain'd on the burning Lake? that sure was worse.
What if the breath that kindl'd those grim fires
Awak'd should blow them into sevenfold rage
And plunge us in the Flames? or from above
Should intermitted vengeance Arme again
His red right hand to plague us? what if all
Her stores were op'n'd, and this Firmament
Of Hell should spout her Cataracts of Fire,
Impendent horrors, threatning hideous fall
One day upon our heads; while we perhaps
Designing or exhorting glorious Warr,
Caught in a fierie Tempest shall be hurl'd
Each on his rock transfixt, the sport and prey
Of racking whirlwinds, or for ever sunk
Under yon boyling Ocean, wrapt in Chains;
There to converse with everlasting groans,
Unrespited, unpitied, unrepreevd,
Ages of hopeless end; this would be worse.
Warr therefore, open or conceal'd, alike
My voice disswades; for what can force or guile
With him, or who deceive his mind, whose eye
Views all things at one view? he from heav'ns highth
All these our motions vain, sees and derides;
Not more Almighty to resist our might
Then wise to frustrate all our plots and wiles.
Shall we then live thus vile, the race of Heav'n
Thus trampl'd, thus expell'd to suffer here
Chains & these Torments? better these then worse
By my advice; since fate inevitable
Subdues us, and Omnipotent Decree,
The Victors will. To suffer, as to doe,
Our strength is equal, nor the Law unjust
That so ordains: this was at first resolv'd,
If we were wise, against so great a foe
Contending, and so doubtful what might fall.
I laugh, when those who at the Spear are bold
And vent'rous, if that fail them, shrink and fear
What yet they know must follow, to endure
Exile, or ignominy, or bonds, or pain,
The sentence of thir Conquerour: This is now
Our doom; which if we can sustain and bear,
Our Supream Foe in time may much remit
His anger, and perhaps thus farr remov'd
Not mind us not offending, satisfi'd
With what is punish't; whence these raging fires
Will slack'n, if his breath stir not thir flames.
Our purer essence then will overcome
Thir noxious vapour, or enur'd not feel,
Or chang'd at length, and to the place conformd
In temper and in nature, will receive
Familiar the fierce heat, and void of pain;
This horror will grow milde, this darkness light,
Besides what hope the never-ending flight
Of future days may bring, what chance, what change
Worth waiting, since our present lot appeers
For happy though but ill, for ill not worst,
If we procure not to our selves more woe.
Thus BELIAL with words cloath'd in reasons garb
Counsel'd ignoble ease, and peaceful sloath,
Not peace: and after him thus MAMMON spake.
Either to disinthrone the King of Heav'n
We warr, if warr be best, or to regain
Our own right lost: him to unthrone we then
May hope, when everlasting Fate shall yeild
To fickle Chance, and CHAOS judge the strife:
The former vain to hope argues as vain
The latter: for what place can be for us
Within Heav'ns bound, unless Heav'ns Lord supream
We overpower? Suppose he should relent
And publish Grace to all, on promise made
Of new Subjection; with what eyes could we
Stand in his presence humble, and receive
Strict Laws impos'd, to celebrate his Throne
With warbl'd Hymns, and to his Godhead sing
Forc't Halleluiah's; while he Lordly sits
Our envied Sovran, and his Altar breathes
Ambrosial Odours and Ambrosial Flowers,
Our servile offerings. This must be our task
In Heav'n, this our delight; how wearisom
Eternity so spent in worship paid
To whom we hate. Let us not then pursue
By force impossible, by leave obtain'd
Unacceptable, though in Heav'n, our state
Of splendid vassalage, but rather seek
Our own good from our selves, and from our own
Live to our selves, though in this vast recess,
Free, and to none accountable, preferring
Hard liberty before the easie yoke
Of servile Pomp. Our greatness will appear
Then most conspicuous, when great things of small,
Useful of hurtful, prosperous of adverse
We can create, and in what place so e're
Thrive under evil, and work ease out of pain
Through labour and endurance. This deep world
Of darkness do we dread? How oft amidst
Thick clouds and dark doth Heav'ns all-ruling Sire
Choose to reside, his Glory unobscur'd,
And with the Majesty of darkness round
Covers his Throne; from whence deep thunders roar
Must'ring thir rage, and Heav'n resembles Hell?
As he our Darkness, cannot we his Light
Imitate when we please? This Desart soile
Wants not her hidden lustre, Gemms and Gold;
Nor want we skill or art, from whence to raise
Magnificence; and what can Heav'n shew more?
Our torments also may in length of time
Become our Elements, these piercing Fires
As soft as now severe, our temper chang'd
Into their temper; which must needs remove
The sensible of pain. All things invite
To peaceful Counsels, and the settl'd State
Of order, how in safety best we may
Compose our present evils, with regard
Of what we are and where, dismissing quite
All thoughts of Warr: ye have what I advise.
He scarce had finisht, when such murmur filld
Th' Assembly, as when hollow Rocks retain
The sound of blustring winds, which all night long
Had rous'd the Sea, now with hoarse cadence lull
Sea-faring men orewatcht, whose Bark by chance
Or Pinnace anchors in a craggy Bay
After the Tempest: Such applause was heard
As MAMMON ended, and his Sentence pleas'd,
Advising peace: for such another Field
They dreaded worse then Hell: so much the fear
Of Thunder and the Sword of MICHAEL
Wrought still within them; and no less desire
To found this nether Empire, which might rise
By pollicy, and long process of time,
In emulation opposite to Heav'n.
Which when BEELZEBUB perceiv'd, then whom,
SATAN except, none higher sat, with grave
Aspect he rose, and in his rising seem'd
A Pillar of State; deep on his Front engraven
Deliberation sat and publick care;
And Princely counsel in his face yet shon,
Majestick though in ruin: sage he stood
With ATLANTEAN shoulders fit to bear
The weight of mightiest Monarchies; his look
Drew audience and attention still as Night
Or Summers Noon-tide air, while thus he spake.
Thrones and imperial Powers, off-spring of heav'n,
Ethereal Vertues; or these Titles now
Must we renounce, and changing stile be call'd
Princes of Hell? for so the popular vote
Inclines, here to continue, and build up here
A growing Empire; doubtless; while we dream,
And know not that the King of Heav'n hath doom'd
This place our dungeon, not our safe retreat
Beyond his Potent arm, to live exempt
From Heav'ns high jurisdiction, in new League
Banded against his Throne, but to remaine
In strictest bondage, though thus far remov'd,
Under th' inevitable curb, reserv'd
His captive multitude: For he, be sure,
In highth or depth, still first and last will Reign
Sole King, and of his Kingdom loose no part
By our revolt, but over Hell extend
His Empire, and with Iron Scepter rule
Us here, as with his Golden those in Heav'n.
What sit we then projecting Peace and Warr?
Warr hath determin'd us, and foild with loss
Irreparable; tearms of peace yet none
Voutsaf't or sought; for what peace will be giv'n
To us enslav'd, but custody severe,
And stripes, and arbitrary punishment
Inflicted? and what peace can we return,
But to our power hostility and hate,
Untam'd reluctance, and revenge though slow,
Yet ever plotting how the Conquerour least
May reap his conquest, and may least rejoyce
In doing what we most in suffering feel?
Nor will occasion want, nor shall we need
With dangerous expedition to invade
Heav'n, whose high walls fear no assault or Siege,
Or ambush from the Deep. What if we find
Some easier enterprize? There is a place
(If ancient and prophetic fame in Heav'n
Err not) another World, the happy seat
Of som new Race call'd MAN, about this time
To be created like to us, though less
In power and excellence, but favour'd more
Of him who rules above; so was his will
Pronounc'd among the Gods, and by an Oath,
That shook Heav'ns whol circumference, confirm'd.
Thither let us bend all our thoughts, to learn
What creatures there inhabit, of what mould,
Or substance, how endu'd, and what thir Power,
And where thir weakness, how attempted best,
By force or suttlety: Though Heav'n be shut,
And Heav'ns high Arbitrator sit secure
In his own strength, this place may lye expos'd
The utmost border of his Kingdom, left
To their defence who hold it: here perhaps
Som advantagious act may be achiev'd
By sudden onset, either with Hell fire
To waste his whole Creation, or possess
All as our own, and drive as we were driven,
The punie habitants, or if not drive,
Seduce them to our Party, that thir God
May prove thir foe, and with repenting hand
Abolish his own works. This would surpass
Common revenge, and interrupt his joy
In our Confusion, and our Joy upraise
In his disturbance; when his darling Sons
Hurl'd headlong to partake with us, shall curse
Thir frail Originals, and faded bliss,
Faded so soon. Advise if this be worth
Attempting, or to sit in darkness here
Hatching vain Empires. Thus BEELZEBUB
Pleaded his devilish Counsel, first devis'd
By SATAN, and in part propos'd: for whence,
But from the Author of all ill could Spring
So deep a malice, to confound the race
Of mankind in one root, and Earth with Hell
To mingle and involve, done all to spite
The great Creatour? But thir spite still serves
His glory to augment. The bold design
Pleas'd highly those infernal States, and joy
Sparkl'd in all thir eyes; with full assent
They vote: whereat his speech he thus renews.
Well have ye judg'd, well ended long debate,
Synod of Gods, and like to what ye are,
Great things resolv'd; which from the lowest deep
Will once more lift us up, in spight of Fate,
Neerer our ancient Seat; perhaps in view
Of those bright confines, whence with neighbouring Arms
And opportune excursion we may chance
Re-enter Heav'n; or else in some milde Zone
Dwell not unvisited of Heav'ns fair Light
Secure, and at the brightning Orient beam
Purge off this gloom; the soft delicious Air,
To heal the scarr of these corrosive Fires
Shall breath her balme. But first whom shall we send
In search of this new world, whom shall we find
Sufficient? who shall tempt with wandring feet
The dark unbottom'd infinite Abyss
And through the palpable obscure find out
His uncouth way, or spread his aerie flight
Upborn with indefatigable wings
Over the vast abrupt, ere he arrive
The happy Ile; what strength, what art can then
Suffice, or what evasion bear him safe
Through the strict Senteries and Stations thick
Of Angels watching round? Here he had need
All circumspection, and we now no less
Choice in our suffrage; for on whom we send,
The weight of all and our last hope relies.
This said, he sat; and expectation held
His look suspence, awaiting who appeer'd
To second, or oppose, or undertake
The perilous attempt: but all sat mute,
Pondering the danger with deep thoughts; & each
In others count'nance red his own dismay
Astonisht: none among the choice and prime
Of those Heav'n-warring Champions could be found
So hardie as to proffer or accept
Alone the dreadful voyage; till at last
SATAN, whom now transcendent glory rais'd
Above his fellows, with Monarchal pride
Conscious of highest worth, unmov'd thus spake.
O Progeny of Heav'n, Empyreal Thrones,
With reason hath deep silence and demurr
Seis'd us, though undismaid: long is the way
And hard, that out of Hell leads up to Light;
Our prison strong, this huge convex of Fire,
Outrageous to devour, immures us round
Ninefold, and gates of burning Adamant
Barr'd over us prohibit all egress.
These past, if any pass, the void profound
Of unessential Night receives him next
Wide gaping, and with utter loss of being
Threatens him, plung'd in that abortive gulf.
If thence he scape into what ever world,
Or unknown Region, what remains him less
Then unknown dangers and as hard escape.
But I should ill become this Throne, O Peers,
And this Imperial Sov'ranty, adorn'd
With splendor, arm'd with power, if aught propos'd
And judg'd of public moment, in the shape
Of difficulty or danger could deterre
Me from attempting. Wherefore do I assume
These Royalties, and not refuse to Reign,
Refusing to accept as great a share
Of hazard as of honour, due alike
To him who Reigns, and so much to him due
Of hazard more, as he above the rest
High honourd sits? Go therfore mighty powers,
Terror of Heav'n, though fall'n; intend at home,
While here shall be our home, what best may ease
The present misery, and render Hell
More tollerable; if there be cure or charm
To respite or deceive, or slack the pain
Of this ill Mansion: intermit no watch
Against a wakeful Foe, while I abroad
Through all the coasts of dark destruction seek
Deliverance for us all: this enterprize
None shall partake with me. Thus saying rose
The Monarch, and prevented all reply,
Prudent, least from his resolution rais'd
Others among the chief might offer now
(Certain to be refus'd) what erst they feard;
And so refus'd might in opinion stand
His rivals, winning cheap the high repute
Which he through hazard huge must earn. But they
Dreaded not more th' adventure then his voice
Forbidding; and at once with him they rose;
Thir rising all at once was as the sound
Of Thunder heard remote. Towards him they bend
With awful reverence prone; and as a God
Extoll him equal to the highest in Heav'n:
Nor fail'd they to express how much they prais'd,
That for the general safety he despis'd
His own: for neither do the Spirits damn'd
Loose all thir vertue; least bad men should boast
Thir specious deeds on earth, which glory excites,
Or close ambition varnisht o're with zeal.
Thus they thir doubtful consultations dark
Ended rejoycing in thir matchless Chief:
As when from mountain tops the dusky clouds
Ascending, while the North wind sleeps, o'respread
Heav'ns chearful face, the lowring Element
Scowls ore the dark'nd lantskip Snow, or showre;
If chance the radiant Sun with farewell sweet
Extend his ev'ning beam, the fields revive,
The birds thir notes renew, and bleating herds
Attest thir joy, that hill and valley rings.
O shame to men! Devil with Devil damn'd
Firm concord holds, men onely disagree
Of Creatures rational, though under hope
Of heavenly Grace: and God proclaiming peace,
Yet live in hatred, enmitie, and strife
Among themselves, and levie cruel warres,
Wasting the Earth, each other to destroy:
As if (which might induce us to accord)
Man had not hellish foes anow besides,
That day and night for his destruction waite.
The STYGIAN Councel thus dissolv'd; and forth
In order came the grand infernal Peers,
Midst came thir mighty Paramount, and seemd
Alone th' Antagonist of Heav'n, nor less
Then Hells dread Emperour with pomp Supream,
And God-like imitated State; him round
A Globe of fierie Seraphim inclos'd
With bright imblazonrie, and horrent Arms.
Then of thir Session ended they bid cry
With Trumpets regal sound the great result:
Toward the four winds four speedy Cherubim
Put to thir mouths the sounding Alchymie
By Haralds voice explain'd: the hollow Abyss
Heard farr and wide, and all the host of Hell
With deafning shout, return'd them loud acclaim.
Thence more at ease thir minds and somwhat rais'd
By false presumptuous hope, the ranged powers
Disband, and wandring, each his several way
Pursues, as inclination or sad choice
Leads him perplext, where he may likeliest find
Truce to his restless thoughts, and entertain
The irksome hours, till his great Chief return.
Part on the Plain, or in the Air sublime
Upon the wing, or in swift race contend,
As at th' Olympian Games or PYTHIAN fields;
Part curb thir fierie Steeds, or shun the Goal
With rapid wheels, or fronted Brigads form.
As when to warn proud Cities warr appears
Wag'd in the troubl'd Skie, and Armies rush
To Battel in the Clouds, before each Van
Pric forth the Aerie Knights, and couch thir spears
Till thickest Legions close; with feats of Arms
From either end of Heav'n the welkin burns.
Others with vast TYPHOEAN rage more fell
Rend up both Rocks and Hills, and ride the Air
In whirlwind; Hell scarce holds the wilde uproar.
As when ALCIDES from OEALIA Crown'd
With conquest, felt th' envenom'd robe, and tore
Through pain up by the roots THESSALIAN Pines,
And LICHAS from the top of OETA threw
Into th' EUBOIC Sea. Others more milde,
Retreated in a silent valley, sing
With notes Angelical to many a Harp
Thir own Heroic deeds and hapless fall
By doom of Battel; and complain that Fate
Free Vertue should enthrall to Force or Chance.
Thir song was partial, but the harmony
(What could it less when Spirits immortal sing?)
Suspended Hell, and took with ravishment
The thronging audience. In discourse more sweet
(For Eloquence the Soul, Song charms the Sense,)
Others apart sat on a Hill retir'd,
In thoughts more elevate, and reason'd high
Of Providence, Foreknowledge, Will, and Fate,
Fixt Fate, free will, foreknowledge absolute,
And found no end, in wandring mazes lost.
Of good and evil much they argu'd then,
Of happiness and final misery,
Passion and Apathie, and glory and shame,
Vain wisdom all, and false Philosophie:
Yet with a pleasing sorcerie could charm
Pain for a while or anguish, and excite
Fallacious hope, or arm th' obdured brest
With stubborn patience as with triple steel.
Another part in Squadrons and gross Bands,
On bold adventure to discover wide
That dismal world, if any Clime perhaps
Might yeild them easier habitation, bend
Four ways thir flying March, along the Banks
Of four infernal Rivers that disgorge
Into the burning Lake thir baleful streams;
Abhorred STYX the flood of deadly hate,
Sad ACHERON of sorrow, black and deep;
COCYTUS, nam'd of lamentation loud
Heard on the ruful stream; fierce PHLEGETON
Whose waves of torrent fire inflame with rage.
Farr off from these a slow and silent stream,
LETHE the River of Oblivion roules
Her watrie Labyrinth, whereof who drinks,
Forthwith his former state and being forgets,
Forgets both joy and grief, pleasure and pain.
Beyond this flood a frozen Continent
Lies dark and wilde, beat with perpetual storms
Of Whirlwind and dire Hail, which on firm land
Thaws not, but gathers heap, and ruin seems
Of ancient pile; all else deep snow and ice,
A gulf profound as that SERBONIAN Bog
Betwixt DAMIATA and mount CASIUS old,
Where Armies whole have sunk: the parching Air
Burns frore, and cold performs th' effect of Fire.
Thither by harpy-footed Furies hail'd,
At certain revolutions all the damn'd
Are brought: and feel by turns the bitter change
Of fierce extreams, extreams by change more fierce,
From Beds of raging Fire to starve in Ice
Thir soft Ethereal warmth, and there to pine
Immovable, infixt, and frozen round,
Periods of time, thence hurried back to fire.
They ferry over this LETHEAN Sound
Both to and fro, thir sorrow to augment,
And wish and struggle, as they pass, to reach
The tempting stream, with one small drop to loose
In sweet forgetfulness all pain and woe,
All in one moment, and so neer the brink;
But fate withstands, and to oppose th' attempt
MEDUSA with GORGONIAN terror guards
The Ford, and of it self the water flies
All taste of living wight, as once it fled
The lip of TANTALUS. Thus roving on
In confus'd march forlorn, th' adventrous Bands
With shuddring horror pale, and eyes agast
View'd first thir lamentable lot, and found
No rest: through many a dark and drearie Vaile
They pass'd, and many a Region dolorous,
O're many a Frozen, many a Fierie Alpe,
Rocks, Caves, Lakes, Fens, Bogs, Dens, and shades of death,
A Universe of death, which God by curse
Created evil, for evil only good,
Where all life dies, death lives, and nature breeds,
Perverse, all monstrous, all prodigious things,
Abominable, inutterable, and worse
Then Fables yet have feign'd, or fear conceiv'd,
GORGONS and HYDRA'S, and CHIMERA'S dire.
Mean while the Adversary of God and Man,
SATAN with thoughts inflam'd of highest design,
Puts on swift wings, and toward the Gates of Hell
Explores his solitary flight; som times
He scours the right hand coast, som times the left,
Now shaves with level wing the Deep, then soares
Up to the fiery concave touring high.
As when farr off at Sea a Fleet descri'd
Hangs in the Clouds, by AEQUINOCTIAL Winds
Close sailing from BENGALA, or the Iles
Of TERNATE and TIDORE, whence Merchants bring
Thir spicie Drugs: they on the trading Flood
Through the wide ETHIOPIAN to the Cape
Ply stemming nightly toward the Pole. So seem'd
Farr off the flying Fiend: at last appeer
Hell bounds high reaching to the horrid Roof,
And thrice threefold the Gates; three folds were Brass
Three Iron, three of Adamantine Rock,
Impenitrable, impal'd with circling fire,
Yet unconsum'd. Before the Gates there sat
On either side a formidable shape;
The one seem'd Woman to the waste, and fair,
But ended foul in many a scaly fould
Voluminous and vast, a Serpent arm'd
With mortal sting: about her middle round
A cry of Hell Hounds never ceasing bark'd
With wide CERBEREAN mouths full loud, and rung
A hideous Peal: yet, when they list, would creep,
If aught disturb'd thir noyse, into her woomb,
And kennel there, yet there still bark'd and howl'd
Within unseen. Farr less abhorrd then these
Vex'd SCYLLA bathing in the Sea that parts
CALABRIA from the hoarce TRINACRIAN shore:
Nor uglier follow the Night-Hag, when call'd
In secret, riding through the Air she comes
Lur'd with the smell of infant blood, to dance
With LAPLAND Witches, while the labouring Moon
Eclipses at thir charms. The other shape,
If shape it might be call'd that shape had none
Distinguishable in member, joynt, or limb,
Or substance might be call'd that shadow seem'd,
For each seem'd either; black it stood as Night,
Fierce as ten Furies, terrible as Hell,
And shook a dreadful Dart; what seem'd his head
The likeness of a Kingly Crown had on.
SATAN was now at hand, and from his seat
The Monster moving onward came as fast,
With horrid strides, Hell trembled as he strode.
Th' undaunted Fiend what this might be admir'd,
Admir'd, not fear'd; God and his Son except,
Created thing naught vallu'd he nor shun'd;
And with disdainful look thus first began.
Whence and what art thou, execrable shape,
That dar'st, though grim and terrible, advance
Thy miscreated Front athwart my way
To yonder Gates? through them I mean to pass,
That be assur'd, without leave askt of thee:
Retire, or taste thy folly, and learn by proof,
Hell-born, not to contend with Spirits of Heav'n.
To whom the Goblin full of wrauth reply'd,
Art thou that Traitor Angel, art thou hee,
Who first broke peace in Heav'n and Faith, till then
Unbrok'n, and in proud rebellious Arms
Drew after him the third part of Heav'ns Sons
Conjur'd against the highest, for which both Thou
And they outcast from God, are here condemn'd
To waste Eternal daies in woe and pain?
And reck'n'st thou thy self with Spirits of Heav'n,
Hell-doomd, and breath'st defiance here and scorn,
Where I reign King, and to enrage thee more,
Thy King and Lord? Back to thy punishment,
False fugitive, and to thy speed add wings,
Least with a whip of Scorpions I pursue
Thy lingring, or with one stroke of this Dart
Strange horror seise thee, and pangs unfelt before.
So spake the grieslie terrour, and in shape,
So speaking and so threatning, grew ten fold
More dreadful and deform: on th' other side
Incenc't with indignation SATAN stood
Unterrifi'd, and like a Comet burn'd,
That fires the length of OPHIUCUS huge
In th' Artick Sky, and from his horrid hair
Shakes Pestilence and Warr. Each at the Head
Level'd his deadly aime; thir fatall hands
No second stroke intend, and such a frown
Each cast at th' other, as when two black Clouds
With Heav'ns Artillery fraught, come rattling on
Over the CASPIAN, then stand front to front
Hov'ring a space, till Winds the signal blow
To joyn thir dark Encounter in mid air:
So frownd the mighty Combatants, that Hell
Grew darker at thir frown, so matcht they stood;
For never but once more was either like
To meet so great a foe: and now great deeds
Had been achiev'd, whereof all Hell had rung,
Had not the Snakie Sorceress that sat
Fast by Hell Gate, and kept the fatal Key,
Ris'n, and with hideous outcry rush'd between.
O Father, what intends thy hand, she cry'd,
Against thy only Son? What fury O Son,
Possesses thee to bend that mortal Dart
Against thy Fathers head? and know'st for whom;
For him who sits above and laughs the while
At thee ordain'd his drudge, to execute
What e're his wrath, which he calls Justice, bids,
His wrath which one day will destroy ye both.
She spake, and at her words the hellish Pest
Forbore, then these to her SATAN return'd:
So strange thy outcry, and thy words so strange
Thou interposest, that my sudden hand
Prevented spares to tell thee yet by deeds
What it intends; till first I know of thee,
What thing thou art, thus double-form'd, and why
In this infernal Vaile first met thou call'st
Me Father, and that Fantasm call'st my Son?
I know thee not, nor ever saw till now
Sight more detestable then him and thee.
T' whom thus the Portress of Hell Gate reply'd;
Hast thou forgot me then, and do I seem
Now in thine eye so foul, once deemd so fair
In Heav'n, when at th' Assembly, and in sight
Of all the Seraphim with thee combin'd
In bold conspiracy against Heav'ns King,
All on a sudden miserable pain
Surpris'd thee, dim thine eyes, and dizzie swumm
In darkness, while thy head flames thick and fast
Threw forth, till on the left side op'ning wide,
Likest to thee in shape and count'nance bright,
Then shining heav'nly fair, a Goddess arm'd
Out of thy head I sprung: amazement seis'd
All th' Host of Heav'n; back they recoild affraid
At first, and call'd me SIN, and for a Sign
Portentous held me; but familiar grown,
I pleas'd, and with attractive graces won
The most averse, thee chiefly, who full oft
Thy self in me thy perfect image viewing
Becam'st enamour'd, and such joy thou took'st
With me in secret, that my womb conceiv'd
A growing burden. Mean while Warr arose,
And fields were fought in Heav'n; wherein remaind
(For what could else) to our Almighty Foe
Cleer Victory, to our part loss and rout
Through all the Empyrean: down they fell
Driv'n headlong from the Pitch of Heaven, down
Into this Deep, and in the general fall
I also; at which time this powerful Key
Into my hand was giv'n, with charge to keep
These Gates for ever shut, which none can pass
Without my op'ning. Pensive here I sat
Alone, but long I sat not, till my womb
Pregnant by thee, and now excessive grown
Prodigious motion felt and rueful throes.
At last this odious offspring whom thou seest
Thine own begotten, breaking violent way
Tore through my entrails, that with fear and pain
Distorted, all my nether shape thus grew
Transform'd: but he my inbred enemie
Forth issu'd, brandishing his fatal Dart
Made to destroy: I fled, and cry'd out DEATH;
Hell trembl'd at the hideous Name, and sigh'd
From all her Caves, and back resounded DEATH.
I fled, but he pursu'd (though more, it seems,
Inflam'd with lust then rage) and swifter far,
Me overtook his mother all dismaid,
And in embraces forcible and foule
Ingendring with me, of that rape begot
These yelling Monsters that with ceasless cry
Surround me, as thou sawst, hourly conceiv'd
And hourly born, with sorrow infinite
To me, for when they list into the womb
That bred them they return, and howle and gnaw
My Bowels, their repast; then bursting forth
Afresh with conscious terrours vex me round,
That rest or intermission none I find.
Before mine eyes in opposition sits
Grim DEATH my Son and foe, who sets them on,
And me his Parent would full soon devour
For want of other prey, but that he knows
His end with mine involvd; and knows that I
Should prove a bitter Morsel, and his bane,
When ever that shall be; so Fate pronounc'd.
But thou O Father, I forewarn thee, shun
His deadly arrow; neither vainly hope
To be invulnerable in those bright Arms,
Though temper'd heav'nly, for that mortal dint,
Save he who reigns above, none can resist.
She finish'd, and the suttle Fiend his lore
Soon learnd, now milder, and thus answerd smooth.
Dear Daughter, since thou claim'st me for thy Sire,
And my fair Son here showst me, the dear pledge
Of dalliance had with thee in Heav'n, and joys
Then sweet, now sad to mention, through dire change
Befalln us unforeseen, unthought of, know
I come no enemie, but to set free
From out this dark and dismal house of pain,
Both him and thee, and all the heav'nly Host
Of Spirits that in our just pretenses arm'd
Fell with us from on high: from them I go
This uncouth errand sole, and one for all
My self expose, with lonely steps to tread
Th' unfounded deep, & through the void immense
To search with wandring quest a place foretold
Should be, and, by concurring signs, ere now
Created vast and round, a place of bliss
In the Pourlieues of Heav'n, and therein plac't
A race of upstart Creatures, to supply
Perhaps our vacant room, though more remov'd,
Least Heav'n surcharg'd with potent multitude
Might hap to move new broiles: Be this or aught
Then this more secret now design'd, I haste
To know, and this once known, shall soon return,
And bring ye to the place where Thou and Death
Shall dwell at ease, and up and down unseen
Wing silently the buxom Air, imbalm'd
With odours; there ye shall be fed and fill'd
Immeasurably, all things shall be your prey.
He ceas'd, for both seemd highly pleasd, and Death
Grinnd horrible a gastly smile, to hear
His famine should be fill'd, and blest his mawe
Destin'd to that good hour: no less rejoyc'd
His mother bad, and thus bespake her Sire.
The key of this infernal Pit by due,
And by command of Heav'ns all-powerful King
I keep, by him forbidden to unlock
These Adamantine Gates; against all force
Death ready stands to interpose his dart,
Fearless to be o'rematcht by living might.
But what ow I to his commands above
Who hates me, and hath hither thrust me down
Into this gloom of TARTARUS profound,
To sit in hateful Office here confin'd,
Inhabitant of Heav'n, and heav'nlie-born,
Here in perpetual agonie and pain,
With terrors and with clamors compasst round
Of mine own brood, that on my bowels feed:
Thou art my Father, thou my Author, thou
My being gav'st me; whom should I obey
But thee, whom follow? thou wilt bring me soon
To that new world of light and bliss, among
The Gods who live at ease, where I shall Reign
At thy right hand voluptuous, as beseems
Thy daughter and thy darling, without end.
Thus saying, from her side the fatal Key,
Sad instrument of all our woe, she took;
And towards the Gate rouling her bestial train,
Forthwith the huge Porcullis high up drew,
Which but her self not all the STYGIAN powers
Could once have mov'd; then in the key-hole turns
Th' intricate wards, and every Bolt and Bar
Of massie Iron or sollid Rock with ease
Unfast'ns: on a sudden op'n flie
With impetuous recoile and jarring sound
Th' infernal dores, and on thir hinges great
Harsh Thunder, that the lowest bottom shook
Of EREBUS. She op'nd, but to shut
Excel'd her power; the Gates wide op'n stood,
That with extended wings a Bannerd Host
Under spread Ensigns marching might pass through
With Horse and Chariots rankt in loose array;
So wide they stood, and like a Furnace mouth
Cast forth redounding smoak and ruddy flame.
Before thir eyes in sudden view appear
The secrets of the hoarie deep, a dark
Illimitable Ocean without bound,
Without dimension, where length, breadth, and highth,
And time and place are lost; where eldest Night
And CHAOS, Ancestors of Nature, hold
Eternal ANARCHIE, amidst the noise
Of endless warrs and by confusion stand.
For hot, cold, moist, and dry, four Champions fierce
Strive here for Maistrie, and to Battel bring
Thir embryon Atoms; they around the flag
Of each his faction, in thir several Clanns,
Light-arm'd or heavy, sharp, smooth, swift or slow,
Swarm populous, unnumber'd as the Sands
Of BARCA or CYRENE'S torrid soil,
Levied to side with warring Winds, and poise
Thir lighter wings. To whom these most adhere,
Hee rules a moment; CHAOS Umpire sits,
And by decision more imbroiles the fray
By which he Reigns: next him high Arbiter
CHANCE governs all. Into this wilde Abyss,
The Womb of nature and perhaps her Grave,
Of neither Sea, nor Shore, nor Air, nor Fire,
But all these in thir pregnant causes mixt
Confus'dly, and which thus must ever fight,
Unless th' Almighty Maker them ordain
His dark materials to create more Worlds,
Into this wilde Abyss the warie fiend
Stood on the brink of Hell and look'd a while,
Pondering his Voyage; for no narrow frith
He had to cross. Nor was his eare less peal'd
With noises loud and ruinous (to compare
Great things with small) then when BELLONA storms,
With all her battering Engines bent to rase
Som Capital City, or less then if this frame
Of Heav'n were falling, and these Elements
In mutinie had from her Axle torn
The stedfast Earth. At last his Sail-broad Vannes
He spreads for flight, and in the surging smoak
Uplifted spurns the ground, thence many a League
As in a cloudy Chair ascending rides
Audacious, but that seat soon failing, meets
A vast vacuitie: all unawares
Fluttring his pennons vain plumb down he drops
Ten thousand fadom deep, and to this hour
Down had been falling, had not by ill chance
The strong rebuff of som tumultuous cloud
Instinct with Fire and Nitre hurried him
As many miles aloft: that furie stay'd,
Quencht in a Boggie SYRTIS, neither Sea,
Nor good dry Land: nigh founderd on he fares,
Treading the crude consistence, half on foot,
Half flying; behoves him now both Oare and Saile.
As when a Gryfon through the Wilderness
With winged course ore Hill or moarie Dale,
Pursues the ARIMASPIAN, who by stelth
Had from his wakeful custody purloind
The guarded Gold: So eagerly the fiend
Ore bog or steep, through strait, rough, dense, or rare,
With head, hands, wings, or feet pursues his way,
And swims or sinks, or wades, or creeps, or flyes:
At length a universal hubbub wilde
Of stunning sounds and voices all confus'd
Born through the hollow dark assaults his eare
With loudest vehemence: thither he plyes,
Undaunted to meet there what ever power
Or Spirit of the nethermost Abyss
Might in that noise reside, of whom to ask
Which way the neerest coast of darkness lyes
Bordering on light; when strait behold the Throne
Of CHAOS, and his dark Pavilion spread
Wide on the wasteful Deep; with him Enthron'd
Sat Sable-vested Night, eldest of things,
The consort of his Reign; and by them stood
ORCUS and ADES, and the dreaded name
Of DEMOGORGON; Rumor next and Chance,
And Tumult and Confusion all imbroild,
And Discord with a thousand various mouths.
T' whom SATAN turning boldly, thus. Ye Powers
And Spirits of this nethermost Abyss,
CHAOS and ANCIENT NIGHT, I come no Spie,
With purpose to explore or to disturb
The secrets of your Realm, but by constraint
Wandring this darksome desart, as my way
Lies through your spacious Empire up to light,
Alone, and without guide, half lost, I seek
What readiest path leads where your gloomie bounds
Confine with Heav'n; or if som other place
From your Dominion won, th' Ethereal King
Possesses lately, thither to arrive
I travel this profound, direct my course;
Directed, no mean recompence it brings
To your behoof, if I that Region lost,
All usurpation thence expell'd, reduce
To her original darkness and your sway
(Which is my present journey) and once more
Erect the Standerd there of ANCIENT NIGHT;
Yours be th' advantage all, mine the revenge.
Thus SATAN; and him thus the Anarch old
With faultring speech and visage incompos'd
Answer'd. I know thee, stranger, who thou art,
That mighty leading Angel, who of late
Made head against Heav'ns King, though overthrown.
I saw and heard, for such a numerous host
Fled not in silence through the frighted deep
With ruin upon ruin, rout on rout,
Confusion worse confounded; and Heav'n Gates
Pourd out by millions her victorious Bands
Pursuing. I upon my Frontieres here
Keep residence; if all I can will serve,
That little which is left so to defend
Encroacht on still through our intestine broiles
Weakning the Scepter of old Night: first Hell
Your dungeon stretching far and wide beneath;
Now lately Heaven and Earth, another World
Hung ore my Realm, link'd in a golden Chain
To that side Heav'n from whence your Legions fell:
If that way be your walk, you have not farr;
So much the neerer danger; goe and speed;
Havock and spoil and ruin are my gain.
He ceas'd; and SATAN staid not to reply,
But glad that now his Sea should find a shore,
With fresh alacritie and force renew'd
Springs upward like a Pyramid of fire
Into the wilde expanse, and through the shock
Of fighting Elements, on all sides round
Environ'd wins his way; harder beset
And more endanger'd, then when ARGO pass'd
Through BOSPORUS betwixt the justling Rocks:
Or when ULYSSES on the Larbord shunnd
CHARYBDIS, and by th' other whirlpool steard.
So he with difficulty and labour hard
Mov'd on, with difficulty and labour hee;
But hee once past, soon after when man fell,
Strange alteration! Sin and Death amain
Following his track, such was the will of Heav'n,
Pav'd after him a broad and beat'n way
Over the dark Abyss, whose boiling Gulf
Tamely endur'd a Bridge of wondrous length
From Hell continu'd reaching th' utmost Orbe
Of this frail World; by which the Spirits perverse
With easie intercourse pass to and fro
To tempt or punish mortals, except whom
God and good Angels guard by special grace.
But now at last the sacred influence
Of light appears, and from the walls of Heav'n
Shoots farr into the bosom of dim Night
A glimmering dawn; here Nature first begins
Her fardest verge, and CHAOS to retire
As from her outmost works a brok'n foe
With tumult less and with less hostile din,
That SATAN with less toil, and now with ease
Wafts on the calmer wave by dubious light
And like a weather-beaten Vessel holds
Gladly the Port, though Shrouds and Tackle torn;
Or in the emptier waste, resembling Air,
Weighs his spread wings, at leasure to behold
Farr off th' Empyreal Heav'n, extended wide
In circuit, undetermind square or round,
With Opal Towrs and Battlements adorn'd
Of living Saphire, once his native Seat;
And fast by hanging in a golden Chain
This pendant world, in bigness as a Starr
Of smallest Magnitude close by the Moon.
Thither full fraught with mischievous revenge,
Accurst, and in a cursed hour he hies.
THE END OF THE SECOND BOOK.
PARADISE LOST
BOOK III
HAil holy light, ofspring of Heav'n first-born,
Or of th' Eternal Coeternal beam
May I express thee unblam'd? since God is light,
And never but in unapproached light
Dwelt from Eternitie, dwelt then in thee,
Bright effluence of bright essence increate.
Or hear'st thou rather pure Ethereal stream,
Whose Fountain who shall tell? before the Sun,
Before the Heavens thou wert, and at the voice
Of God, as with a Mantle didst invest
The rising world of waters dark and deep,
Won from the void and formless infinite.
Thee I re-visit now with bolder wing,
Escap't the STYGIAN Pool, though long detain'd
In that obscure sojourn, while in my flight
Through utter and through middle darkness borne
With other notes then to th' ORPHEAN Lyre
I sung of CHAOS and ETERNAL NIGHT,
Taught by the heav'nly Muse to venture down
The dark descent, and up to reascend,
Though hard and rare: thee I revisit safe,
And feel thy sovran vital Lamp; but thou
Revisit'st not these eyes, that rowle in vain
To find thy piercing ray, and find no dawn;
So thick a drop serene hath quencht thir Orbs,
Or dim suffusion veild. Yet not the more
Cease I to wander where the Muses haunt
Cleer Spring, or shadie Grove, or Sunnie Hill,
Smit with the love of sacred song; but chief
Thee SION and the flowrie Brooks beneath
That wash thy hallowd feet, and warbling flow,
Nightly I visit: nor somtimes forget
Those other two equal'd with me in Fate,
So were I equal'd with them in renown,
Blind THAMYRIS and blind MAEONIDES,
And TIRESIAS and PHINEUS Prophets old.
Then feed on thoughts, that voluntarie move
Harmonious numbers; as the wakeful Bird
Sings darkling, and in shadiest Covert hid
Tunes her nocturnal Note. Thus with the Year
Seasons return, but not to me returns
Day, or the sweet approach of Ev'n or Morn,
Or sight of vernal bloom, or Summers Rose,
Or flocks, or herds, or human face divine;
But cloud in stead, and ever-during dark
Surrounds me, from the chearful waies of men
Cut off, and for the book of knowledg fair
Presented with a Universal blanc
Of Natures works to mee expung'd and ras'd,
And wisdome at one entrance quite shut out.
So much the rather thou Celestial light
Shine inward, and the mind through all her powers
Irradiate, there plant eyes, all mist from thence
Purge and disperse, that I may see and tell
Of things invisible to mortal sight.
Now had the Almighty Father from above,
From the pure Empyrean where he sits
High Thron'd above all highth, bent down his eye,
His own works and their works at once to view:
About him all the Sanctities of Heaven
Stood thick as Starrs, and from his sight receiv'd
Beatitude past utterance; on his right
The radiant image of his Glory sat,
His onely Son; On Earth he first beheld
Our two first Parents, yet the onely two
Of mankind, in the happie Garden plac't,
Reaping immortal fruits of joy and love,
Uninterrupted joy, unrivald love
In blissful solitude; he then survey'd
Hell and the Gulf between, and SATAN there
Coasting the wall of Heav'n on this side Night
In the dun Air sublime, and ready now
To stoop with wearied wings, and willing feet
On the bare outside of this World, that seem'd
Firm land imbosom'd without Firmament,
Uncertain which, in Ocean or in Air.
Him God beholding from his prospect high,
Wherein past, present, future he beholds,
Thus to his onely Son foreseeing spake.
Onely begotten Son, seest thou what rage
Transports our adversarie, whom no bounds
Prescrib'd, no barrs of Hell, nor all the chains
Heapt on him there, nor yet the main Abyss
Wide interrupt can hold; so bent he seems
On desperat revenge, that shall redound
Upon his own rebellious head. And now
Through all restraint broke loose he wings his way
Not farr off Heav'n, in the Precincts of light,
Directly towards the new created World,
And Man there plac't, with purpose to assay
If him by force he can destroy, or worse,
By som false guile pervert; and shall pervert;
For man will heark'n to his glozing lyes,
And easily transgress the sole Command,
Sole pledge of his obedience: So will fall
Hee and his faithless Progenie: whose fault?
Whose but his own? ingrate, he had of mee
All he could have; I made him just and right,
Sufficient to have stood, though free to fall.
Such I created all th' Ethereal Powers
And Spirits, both them who stood & them who faild;
Freely they stood who stood, and fell who fell.
Not free, what proof could they have givn sincere
Of true allegiance, constant Faith or Love,
Where onely what they needs must do, appeard,
Not what they would? what praise could they receive?
What pleasure I from such obedience paid,
When Will and Reason (Reason also is choice)
Useless and vain, of freedom both despoild,
Made passive both, had servd necessitie,
Not mee. They therefore as to right belongd,
So were created, nor can justly accuse
Thir maker, or thir making, or thir Fate;
As if Predestination over-rul'd
Thir will, dispos'd by absolute Decree
Or high foreknowledge; they themselves decreed
Thir own revolt, not I: if I foreknew,
Foreknowledge had no influence on their fault,
Which had no less prov'd certain unforeknown.
So without least impulse or shadow of Fate,
Or aught by me immutablie foreseen,
They trespass, Authors to themselves in all
Both what they judge and what they choose; for so
I formd them free, and free they must remain,
Till they enthrall themselves: I else must change
Thir nature, and revoke the high Decree
Unchangeable, Eternal, which ordain'd
Thir freedom, they themselves ordain'd thir fall.
The first sort by thir own suggestion fell,
Self-tempted, self-deprav'd: Man falls deceiv'd
By the other first: Man therefore shall find grace,
The other none: in Mercy and Justice both,
Through Heav'n and Earth, so shall my glorie excel,
But Mercy first and last shall brightest shine.
Thus while God spake, ambrosial fragrance fill'd
All Heav'n, and in the blessed Spirits elect
Sense of new joy ineffable diffus'd:
Beyond compare the Son of God was seen
Most glorious, in him all his Father shon
Substantially express'd, and in his face
Divine compassion visibly appeerd,
Love without end, and without measure Grace,
Which uttering thus he to his Father spake.
O Father, gracious was that word which clos'd
Thy sovran sentence, that Man should find grace;
For which both Heav'n and Earth shall high extoll
Thy praises, with th' innumerable sound
Of Hymns and sacred Songs, wherewith thy Throne
Encompass'd shall resound thee ever blest.
For should Man finally be lost, should Man
Thy creature late so lov'd, thy youngest Son
Fall circumvented thus by fraud, though joynd
With his own folly? that be from thee farr,
That farr be from thee, Father, who art Judge
Of all things made, and judgest onely right.
Or shall the Adversarie thus obtain
His end, and frustrate thine, shall he fulfill
His malice, and thy goodness bring to naught,
Or proud return though to his heavier doom,
Yet with revenge accomplish't and to Hell
Draw after him the whole Race of mankind,
By him corrupted? or wilt thou thy self
Abolish thy Creation, and unmake,
For him, what for thy glorie thou hast made?
So should thy goodness and thy greatness both
Be questiond and blaspheam'd without defence.
To whom the great Creatour thus reply'd.
O Son, in whom my Soul hath chief delight,
Son of my bosom, Son who art alone
My word, my wisdom, and effectual might,
All hast thou spok'n as my thoughts are, all
As my Eternal purpose hath decreed:
Man shall not quite be lost, but sav'd who will,
Yet not of will in him, but grace in me
Freely voutsaft; once more I will renew
His lapsed powers, though forfeit and enthrall'd
By sin to foul exorbitant desires;
Upheld by me, yet once more he shall stand
On even ground against his mortal foe,
By me upheld, that he may know how frail
His fall'n condition is, and to me ow
All his deliv'rance, and to none but me.
Some I have chosen of peculiar grace
Elect above the rest; so is my will:
The rest shall hear me call, and oft be warnd
Thir sinful state, and to appease betimes
Th' incensed Deitie, while offerd grace
Invites; for I will cleer thir senses dark,
What may suffice, and soft'n stonie hearts
To pray, repent, and bring obedience due.
To prayer, repentance, and obedience due,
Though but endevord with sincere intent,
Mine eare shall not be slow, mine eye not shut.
And I will place within them as a guide
My Umpire CONSCIENCE, whom if they will hear,
Light after light well us'd they shall attain,
And to the end persisting, safe arrive.
This my long sufferance and my day of grace
They who neglect and scorn, shall never taste;
But hard be hard'nd, blind be blinded more,
That they may stumble on, and deeper fall;
And none but such from mercy I exclude.
But yet all is not don; Man disobeying,
Disloyal breaks his fealtie, and sinns
Against the high Supremacie of Heav'n,
Affecting God-head, and so loosing all,
To expiate his Treason hath naught left,
But to destruction sacred and devote,
He with his whole posteritie must die,
Die hee or Justice must; unless for him
Som other able, and as willing, pay
The rigid satisfaction, death for death.
Say Heav'nly Powers, where shall we find such love,
Which of ye will be mortal to redeem
Mans mortal crime, and just th' unjust to save,
Dwels in all Heaven charitie so deare?
He ask'd, but all the Heav'nly Quire stood mute,
And silence was in Heav'n: on mans behalf
Patron or Intercessor none appeerd,
Much less that durst upon his own head draw
The deadly forfeiture, and ransom set.
And now without redemption all mankind
Must have bin lost, adjudg'd to Death and Hell
By doom severe, had not the Son of God,
In whom the fulness dwels of love divine,
His dearest mediation thus renewd.
Father, thy word is past, man shall find grace;
And shall grace not find means, that finds her way,
The speediest of thy winged messengers,
To visit all thy creatures, and to all
Comes unprevented, unimplor'd, unsought,
Happie for man, so coming; he her aide
Can never seek, once dead in sins and lost;
Attonement for himself or offering meet,
Indebted and undon, hath none to bring:
Behold mee then, mee for him, life for life
I offer, on mee let thine anger fall;
Account mee man; I for his sake will leave
Thy bosom, and this glorie next to thee
Freely put off, and for him lastly die
Well pleas'd, on me let Death wreck all his rage;
Under his gloomie power I shall not long
Lie vanquisht; thou hast givn me to possess
Life in my self for ever, by thee I live,
Though now to Death I yeild, and am his due
All that of me can die, yet that debt paid,
Thou wilt not leave me in the loathsom grave
His prey, nor suffer my unspotted Soule
For ever with corruption there to dwell;
But I shall rise Victorious, and subdue
My Vanquisher, spoild of his vanted spoile;
Death his deaths wound shall then receive, & stoop
Inglorious, of his mortall sting disarm'd.
I through the ample Air in Triumph high
Shall lead Hell Captive maugre Hell, and show
The powers of darkness bound. Thou at the sight
Pleas'd, out of Heaven shalt look down and smile,
While by thee rais'd I ruin all my Foes,
Death last, and with his Carcass glut the Grave:
Then with the multitude of my redeemd
Shall enter Heaven long absent, and returne,
Father, to see thy face, wherein no cloud
Of anger shall remain, but peace assur'd,
And reconcilement; wrauth shall be no more
Thenceforth, but in thy presence Joy entire.
His words here ended, but his meek aspect
Silent yet spake, and breath'd immortal love
To mortal men, above which only shon
Filial obedience: as a sacrifice
Glad to be offer'd, he attends the will
Of his great Father. Admiration seis'd
All Heav'n, what this might mean, & whither tend
Wondring; but soon th' Almighty thus reply'd:
O thou in Heav'n and Earth the only peace
Found out for mankind under wrauth, O thou
My sole complacence! well thou know'st how dear,
To me are all my works, nor Man the least
Though last created, that for him I spare
Thee from my bosom and right hand, to save,
By loosing thee a while, the whole Race lost.
Thou therefore whom thou only canst redeeme,
Thir Nature also to thy Nature joyne;
And be thy self Man among men on Earth,
Made flesh, when time shall be, of Virgin seed,
By wondrous birth: Be thou in ADAMS room
The Head of all mankind, though ADAMS Son.
As in him perish all men, so in thee
As from a second root shall be restor'd,
As many as are restor'd, without thee none.
His crime makes guiltie all his Sons, thy merit
Imputed shall absolve them who renounce
Thir own both righteous and unrighteous deeds,
And live in thee transplanted, and from thee
Receive new life. So Man, as is most just,
Shall satisfie for Man, be judg'd and die,
And dying rise, and rising with him raise
His Brethren, ransomd with his own dear life.
So Heav'nly love shal outdoo Hellish hate,
Giving to death, and dying to redeeme,
So dearly to redeem what Hellish hate
So easily destroy'd, and still destroyes
In those who, when they may, accept not grace.
Nor shalt thou by descending to assume
Mans Nature, less'n or degrade thine owne.
Because thou hast, though Thron'd in highest bliss
Equal to God, and equally enjoying
God-like fruition, quitted all to save
A World from utter loss, and hast been found
By Merit more then Birthright Son of God,
Found worthiest to be so by being Good,
Farr more then Great or High; because in thee
Love hath abounded more then Glory abounds,
Therefore thy Humiliation shall exalt
With thee thy Manhood also to this Throne;
Here shalt thou sit incarnate, here shalt Reigne
Both God and Man, Son both of God and Man,
Anointed universal King; all Power
I give thee, reign for ever, and assume
Thy Merits; under thee as Head Supream
Thrones, Princedoms, Powers, Dominions I reduce:
All knees to thee shall bow, of them that bide
In Heaven, or Earth, or under Earth in Hell;
When thou attended gloriously from Heav'n
Shalt in the Skie appeer, and from thee send
The summoning Arch-Angels to proclaime
Thy dread Tribunal: forthwith from all Windes
The living, and forthwith the cited dead
Of all past Ages to the general Doom
Shall hast'n, such a peal shall rouse thir sleep.
Then all thy Saints assembl'd, thou shalt judge
Bad men and Angels, they arraignd shall sink
Beneath thy Sentence; Hell, her numbers full,
Thenceforth shall be for ever shut. Mean while
The World shall burn, and from her ashes spring
New Heav'n and Earth, wherein the just shall dwell
And after all thir tribulations long
See golden days, fruitful of golden deeds,
With Joy and Love triumphing, and fair Truth.
Then thou thy regal Scepter shalt lay by,
For regal Scepter then no more shall need,
God shall be All in All. But all ye Gods,
Adore him, who to compass all this dies,
Adore the Son, and honour him as mee.
No sooner had th' Almighty ceas't, but all
The multitude of Angels with a shout
Loud as from numbers without number, sweet
As from blest voices, uttering joy, Heav'n rung
With Jubilee, and loud Hosanna's fill'd
Th' eternal Regions: lowly reverent
Towards either Throne they bow, & to the ground
With solemn adoration down they cast
Thir Crowns inwove with Amarant and Gold,
Immortal Amarant, a Flour which once
In Paradise, fast by the Tree of Life
Began to bloom, but soon for mans offence
To Heav'n remov'd where first it grew, there grows,
And flours aloft shading the Fount of Life,
And where the river of Bliss through midst of Heavn
Rowls o're ELISIAN Flours her Amber stream;
With these that never fade the Spirits Elect
Bind thir resplendent locks inwreath'd with beams,
Now in loose Garlands thick thrown off, the bright
Pavement that like a Sea of Jasper shon
Impurpl'd with Celestial Roses smil'd.
Then Crown'd again thir gold'n Harps they took,
Harps ever tun'd, that glittering by their side
Like Quivers hung, and with Praeamble sweet
Of charming symphonie they introduce
Thir sacred Song, and waken raptures high;
No voice exempt, no voice but well could joine
Melodious part, such concord is in Heav'n.
Thee Father first they sung Omnipotent,
Immutable, Immortal, Infinite,
Eternal King; thee Author of all being,
Fountain of Light, thy self invisible
Amidst the glorious brightness where thou sit'st
Thron'd inaccessible, but when thou shad'st
The full blaze of thy beams, and through a cloud
Drawn round about thee like a radiant Shrine,
Dark with excessive bright thy skirts appeer,
Yet dazle Heav'n, that brightest Seraphim
Approach not, but with both wings veil thir eyes.
Thee next they sang of all Creation first,
Begotten Son, Divine Similitude,
In whose conspicuous count'nance, without cloud
Made visible, th' Almighty Father shines,
Whom else no Creature can behold; on thee
Impresst the effulgence of his Glorie abides,
Transfus'd on thee his ample Spirit rests.
Hee Heav'n of Heavens and all the Powers therein
By thee created, and by thee threw down
Th' aspiring Dominations: thou that day
Thy Fathers dreadful Thunder didst not spare,
Nor stop thy flaming Chariot wheels, that shook
Heav'ns everlasting Frame, while o're the necks
Thou drov'st of warring Angels disarraid.
Back from pursuit thy Powers with loud acclaime
Thee only extold, Son of thy Fathers might,
To execute fierce vengeance on his foes,
Not so on Man; him through their malice fall'n,
Father of Mercie and Grace, thou didst not doome
So strictly, but much more to pitie encline:
No sooner did thy dear and onely Son
Perceive thee purpos'd not to doom frail Man
So strictly, but much more to pitie enclin'd,
He to appease thy wrauth, and end the strife
Of Mercy and Justice in thy face discern'd,
Regardless of the Bliss wherein hee sat
Second to thee, offerd himself to die
For mans offence. O unexampl'd love,
Love no where to be found less then Divine!
Hail Son of God, Saviour of Men, thy Name
Shall be the copious matter of my Song
Henceforth, and never shall my Harp thy praise
Forget, nor from thy Fathers praise disjoine.
Thus they in Heav'n, above the starry Sphear,
Thir happie hours in joy and hymning spent.
Mean while upon the firm opacous Globe
Of this round World, whose first convex divides
The luminous inferior Orbs, enclos'd
From CHAOS and th' inroad of Darkness old,
SATAN alighted walks: a Globe farr off
It seem'd, now seems a boundless Continent
Dark, waste, and wild, under the frown of Night
Starless expos'd, and ever-threatning storms
Of CHAOS blustring round, inclement skie;
Save on that side which from the wall of Heav'n
Though distant farr som small reflection gaines
Of glimmering air less vext with tempest loud:
Here walk'd the Fiend at large in spacious field.
As when a Vultur on IMAUS bred,
Whose snowie ridge the roving TARTAR bounds,
Dislodging from a Region scarce of prey
To gorge the flesh of Lambs or yeanling Kids
On Hills where Flocks are fed, flies toward the Springs
Of GANGES or HYDASPES, INDIAN streams;
But in his way lights on the barren plaines
Of SERICANA, where CHINESES drive
With Sails and Wind thir canie Waggons light:
So on this windie Sea of Land, the Fiend
Walk'd up and down alone bent on his prey,
Alone, for other Creature in this place
Living or liveless to be found was none,
None yet, but store hereafter from the earth
Up hither like Aereal vapours flew
Of all things transitorie and vain, when Sin
With vanity had filld the works of men:
Both all things vain, and all who in vain things
Built thir fond hopes of Glorie or lasting fame,
Or happiness in this or th' other life;
All who have thir reward on Earth, the fruits
Of painful Superstition and blind Zeal,
Naught seeking but the praise of men, here find
Fit retribution, emptie as thir deeds;
All th' unaccomplisht works of Natures hand,
Abortive, monstrous, or unkindly mixt,
Dissolvd on earth, fleet hither, and in vain,
Till final dissolution, wander here,
Not in the neighbouring Moon, as some have dreamd;
Those argent Fields more likely habitants,
Translated Saints, or middle Spirits hold
Betwixt th' Angelical and Human kinde:
Hither of ill-joynd Sons and Daughters born
First from the ancient World those Giants came
With many a vain exploit, though then renownd:
The builders next of BABEL on the Plain
Of SENNAAR, and still with vain designe
New BABELS, had they wherewithall, would build:
Others came single; hee who to be deemd
A God, leap'd fondly into AETNA flames,
EMPEDOCLES, and hee who to enjoy
PLATO'S ELYSIUM, leap'd into the Sea,
CLEOMBROTUS, and many more too long,
Embryo's and Idiots, Eremits and Friers
White, Black and Grey, with all thir trumperie.
Here Pilgrims roam, that stray'd so farr to seek
In GOLGOTHA him dead, who lives in Heav'n;
And they who to be sure of Paradise
Dying put on the weeds of DOMINIC,
Or in FRANCISCAN think to pass disguis'd;
They pass the Planets seven, and pass the fixt,
And that Crystalline Sphear whose ballance weighs
The Trepidation talkt, and that first mov'd;
And now Saint PETER at Heav'ns Wicket seems
To wait them with his Keys, and now at foot
Of Heav'ns ascent they lift thir Feet, when loe
A violent cross wind from either Coast
Blows them transverse ten thousand Leagues awry
Into the devious Air; then might ye see
Cowles, Hoods and Habits with thir wearers tost
And flutterd into Raggs, then Reliques, Beads,
Indulgences, Dispenses, Pardons, Bulls,
The sport of Winds: all these upwhirld aloft
Fly o're the backside of the World farr off
Into a LIMBO large and broad, since calld
The Paradise of Fools, to few unknown
Long after, now unpeopl'd, and untrod;
All this dark Globe the Fiend found as he pass'd,
And long he wanderd, till at last a gleame
Of dawning light turnd thither-ward in haste
His travell'd steps; farr distant hee descries
Ascending by degrees magnificent
Up to the wall of Heaven a Structure high,
At top whereof, but farr more rich appeerd
The work as of a Kingly Palace Gate
With Frontispice of Diamond and Gold
Imbellisht, thick with sparkling orient Gemmes
The Portal shon, inimitable on Earth
By Model, or by shading Pencil drawn.
The Stairs were such as whereon JACOB saw
Angels ascending and descending, bands
Of Guardians bright, when he from ESAU fled
To PADAN-ARAM in the field of LUZ,
Dreaming by night under the open Skie,
And waking cri'd, This is the Gate of Heav'n.
Each Stair mysteriously was meant, nor stood
There alwaies, but drawn up to Heav'n somtimes
Viewless, and underneath a bright Sea flow'd
Of Jasper, or of liquid Pearle, whereon
Who after came from Earth, sayling arriv'd,
Wafted by Angels, or flew o're the Lake
Rapt in a Chariot drawn by fiery Steeds.
The Stairs were then let down, whether to dare
The Fiend by easie ascent, or aggravate
His sad exclusion from the dores of Bliss.
Direct against which op'nd from beneath,
Just o're the blissful seat of Paradise,
A passage down to th' Earth, a passage wide,
Wider by farr then that of after-times
Over Mount SION, and, though that were large,
Over the PROMIS'D LAND to God so dear,
By which, to visit oft those happy Tribes,
On high behests his Angels to and fro
Pass'd frequent, and his eye with choice regard
From PANEAS the fount of JORDANS flood
To BEERSABA, where the HOLY LAND
Borders on AEGYPT and the ARABIAN shoare;
So wide the op'ning seemd, where bounds were set
To darkness, such as bound the Ocean wave.
SATAN from hence now on the lower stair
That scal'd by steps of Gold to Heav'n Gate
Looks down with wonder at the sudden view
Of all this World at once. As when a Scout
Through dark and desart wayes with peril gone
All night; at last by break of chearful dawne
Obtains the brow of some high-climbing Hill,
Which to his eye discovers unaware
The goodly prospect of some forein land
First-seen, or some renownd Metropolis
With glistering Spires and Pinnacles adornd,
Which now the Rising Sun guilds with his beams.
Such wonder seis'd, though after Heaven seen,
The Spirit maligne, but much more envy seis'd
At sight of all this World beheld so faire.
Round he surveys, and well might, where he stood
So high above the circling Canopie
Of Nights extended shade; from Eastern Point
Of LIBRA to the fleecie Starr that bears
ANDROMEDA farr off ATLANTICK Seas
Beyond th' HORIZON; then from Pole to Pole
He views in bredth, and without longer pause
Down right into the Worlds first Region throws
His flight precipitant, and windes with ease
Through the pure marble Air his oblique way
Amongst innumerable Starrs, that shon
Stars distant, but nigh hand seemd other Worlds,
Or other Worlds they seemd, or happy Iles,
Like those HESPERIAN Gardens fam'd of old,
Fortunate Fields, and Groves and flourie Vales,
Thrice happy Iles, but who dwelt happy there
He stayd not to enquire: above them all
The golden Sun in splendor likest Heaven
Allur'd his eye: Thither his course he bends
Through the calm Firmament; but up or downe
By center, or eccentric, hard to tell,
Or Longitude, where the great Luminarie
Alooff the vulgar Constellations thick,
That from his Lordly eye keep distance due,
Dispenses Light from farr; they as they move
Thir Starry dance in numbers that compute
Days, months, and years, towards his all-chearing Lamp
Turn swift their various motions, or are turnd
By his Magnetic beam, that gently warms
The Univers, and to each inward part
With gentle penetration, though unseen,
Shoots invisible vertue even to the deep:
So wondrously was set his Station bright.
There lands the Fiend, a spot like which perhaps
Astronomer in the Sun's lucent Orbe
Through his glaz'd Optic Tube yet never saw.
The place he found beyond expression bright,
Compar'd with aught on Earth, Medal or Stone;
Not all parts like, but all alike informd
With radiant light, as glowing Iron with fire;
If mettal, part seemd Gold, part Silver cleer;
If stone, Carbuncle most or Chrysolite,
Rubie or Topaz, to the Twelve that shon
In AARONS Brest-plate, and a stone besides
Imagind rather oft then elsewhere seen,
That stone, or like to that which here below
Philosophers in vain so long have sought,
In vain, though by thir powerful Art they binde
Volatil HERMES, and call up unbound
In various shapes old PROTEUS from the Sea,
Draind through a Limbec to his Native forme.
What wonder then if fields and regions here
Breathe forth ELIXIR pure, and Rivers run
Potable Gold, when with one vertuous touch
Th' Arch-chimic Sun so farr from us remote
Produces with Terrestrial Humor mixt
Here in the dark so many precious things
Of colour glorious and effect so rare?
Here matter new to gaze the Devil met
Undazl'd, farr and wide his eye commands,
For sight no obstacle found here, nor shade,
But all Sun-shine, as when his Beams at Noon
Culminate from th' AEQUATOR, as they now
Shot upward still direct, whence no way round
Shadow from body opaque can fall, and the Aire,
No where so cleer, sharp'nd his visual ray
To objects distant farr, whereby he soon
Saw within kenn a glorious Angel stand,
The same whom JOHN saw also in the Sun:
His back was turnd, but not his brightness hid;
Of beaming sunnie Raies, a golden tiar
Circl'd his Head, nor less his Locks behind
Illustrious on his Shoulders fledge with wings
Lay waving round; on som great charge imploy'd
Hee seemd, or fixt in cogitation deep.
Glad was the Spirit impure as now in hope
To find who might direct his wandring flight
To Paradise the happie seat of Man,
His journies end and our beginning woe.
But first he casts to change his proper shape,
Which else might work him danger or delay:
And now a stripling Cherube he appeers,
Not of the prime, yet such as in his face
Youth smil'd Celestial, and to every Limb
Sutable grace diffus'd, so well he feignd;
Under a Coronet his flowing haire
In curles on either cheek plaid, wings he wore
Of many a colourd plume sprinkl'd with Gold,
His habit fit for speed succinct, and held
Before his decent steps a Silver wand.
He drew not nigh unheard, the Angel bright,
Ere he drew nigh, his radiant visage turnd,
Admonisht by his eare, and strait was known
Th' Arch-Angel URIEL, one of the seav'n
Who in Gods presence, neerest to his Throne
Stand ready at command, and are his Eyes
That run through all the Heav'ns, or down to th' Earth
Bear his swift errands over moist and dry,
O're Sea and Land: him SATAN thus accostes;
URIEL, for thou of those seav'n Spirits that stand
In sight of God's high Throne, gloriously bright,
The first art wont his great authentic will
Interpreter through highest Heav'n to bring,
Where all his Sons thy Embassie attend;
And here art likeliest by supream decree
Like honour to obtain, and as his Eye
To visit oft this new Creation round;
Unspeakable desire to see, and know
All these his wondrous works, but chiefly Man,
His chief delight and favour, him for whom
All these his works so wondrous he ordaind,
Hath brought me from the Quires of Cherubim
Alone thus wandring. Brightest Seraph tell
In which of all these shining Orbes hath Man
His fixed seat, or fixed seat hath none,
But all these shining Orbes his choice to dwell;
That I may find him, and with secret gaze,
Or open admiration him behold
On whom the great Creator hath bestowd
Worlds, and on whom hath all these graces powrd;
That both in him and all things, as is meet,
The Universal Maker we may praise;
Who justly hath drivn out his Rebell Foes
To deepest Hell, and to repair that loss
Created this new happie Race of Men
To serve him better: wise are all his wayes.
So spake the false dissembler unperceivd;
For neither Man nor Angel can discern
Hypocrisie, the only evil that walks
Invisible, except to God alone,
By his permissive will, through Heav'n and Earth:
And oft though wisdom wake, suspicion sleeps
At wisdoms Gate, and to simplicitie
Resigns her charge, while goodness thinks no ill
Where no ill seems: Which now for once beguil'd
URIEL, though Regent of the Sun, and held
The sharpest sighted Spirit of all in Heav'n;
Who to the fraudulent Impostor foule
In his uprightness answer thus returnd.
Faire Angel, thy desire which tends to know
The works of God, thereby to glorifie
The great Work-Maister, leads to no excess
That reaches blame, but rather merits praise
The more it seems excess, that led thee hither
From thy Empyreal Mansion thus alone,
To witness with thine eyes what some perhaps
Contented with report heare onely in heav'n:
For wonderful indeed are all his works,
Pleasant to know, and worthiest to be all
Had in remembrance alwayes with delight;
But what created mind can comprehend
Thir number, or the wisdom infinite
That brought them forth, but hid thir causes deep.
I saw when at his Word the formless Mass,
This worlds material mould, came to a heap:
Confusion heard his voice, and wilde uproar
Stood rul'd, stood vast infinitude confin'd;
Till at his second bidding darkness fled,
Light shon, and order from disorder sprung:
Swift to thir several Quarters hasted then
The cumbrous Elements, Earth, Flood, Aire, Fire,
And this Ethereal quintessence of Heav'n
Flew upward, spirited with various forms,
That rowld orbicular, and turnd to Starrs
Numberless, as thou seest, and how they move;
Each had his place appointed, each his course,
The rest in circuit walles this Universe.
Look downward on that Globe whose hither side
With light from hence, though but reflected, shines;
That place is Earth the seat of Man, that light
His day, which else as th' other Hemisphere
Night would invade, but there the neighbouring Moon
(So call that opposite fair Starr) her aide
Timely interposes, and her monthly round
Still ending, still renewing, through mid Heav'n;
With borrowd light her countenance triform
Hence fills and empties to enlighten th' Earth,
And in her pale dominion checks the night.
That spot to which I point is PARADISE,
ADAMS abode, those loftie shades his Bowre.
Thy way thou canst not miss, me mine requires.
Thus said, he turnd, and SATAN bowing low,
As to superior Spirits is wont in Heaven,
Where honour due and reverence none neglects,
Took leave, and toward the coast of Earth beneath,
Down from th' Ecliptic, sped with hop'd success,
Throws his steep flight with many an Aerie wheele,
Nor staid, till on NIPHATES top he lights.
THE END OF THE THIRD BOOK.
PARADISE LOST
BOOK IV.
O For that warning voice, which he who saw
Th' APOCALYPS, heard cry in Heaven aloud,
Then when the Dragon, put to second rout,
Came furious down to be reveng'd on men,
WO TO THE INHABITANTS ON EARTH! that now,
While time was, our first Parents had bin warnd
The coming of thir secret foe, and scap'd
Haply so scap'd his mortal snare; for now
SATAN, now first inflam'd with rage, came down,
The Tempter ere th' Accuser of man-kind,
To wreck on innocent frail man his loss
Of that first Battel, and his flight to Hell:
Yet not rejoycing in his speed, though bold,
Far off and fearless, nor with cause to boast,
Begins his dire attempt, which nigh the birth
Now rowling, boiles in his tumultuous brest,
And like a devillish Engine back recoiles
Upon himself; horror and doubt distract
His troubl'd thoughts, and from the bottom stirr
The Hell within him, for within him Hell
He brings, and round about him, nor from Hell
One step no more then from himself can fly
By change of place: Now conscience wakes despair
That slumberd, wakes the bitter memorie
Of what he was, what is, and what must be
Worse; of worse deeds worse sufferings must ensue.
Sometimes towards EDEN which now in his view
Lay pleasant, his grievd look he fixes sad,
Sometimes towards Heav'n and the full-blazing Sun,
Which now sat high in his Meridian Towre:
Then much revolving, thus in sighs began.
O thou that with surpassing Glory crownd,
Look'st from thy sole Dominion like the God
Of this new World; at whose sight all the Starrs
Hide thir diminisht heads; to thee I call,
But with no friendly voice, and add thy name
O Sun, to tell thee how I hate thy beams
That bring to my remembrance from what state
I fell, how glorious once above thy Spheare;
Till Pride and worse Ambition threw me down
Warring in Heav'n against Heav'ns matchless King:
Ah wherefore! he deservd no such return
From me, whom he created what I was
In that bright eminence, and with his good
Upbraided none; nor was his service hard.
What could be less then to afford him praise,
The easiest recompence, and pay him thanks,
How due! yet all his good prov'd ill in me,
And wrought but malice; lifted up so high
I sdeind subjection, and thought one step higher
Would set me highest, and in a moment quit
The debt immense of endless gratitude,
So burthensome, still paying, still to ow;
Forgetful what from him I still receivd,
And understood not that a grateful mind
By owing owes not, but still pays, at once
Indebted and dischargd; what burden then?
O had his powerful Destiny ordaind
Me some inferiour Angel, I had stood
Then happie; no unbounded hope had rais'd
Ambition. Yet why not? som other Power
As great might have aspir'd, and me though mean
Drawn to his part; but other Powers as great
Fell not, but stand unshak'n, from within
Or from without, to all temptations arm'd.
Hadst thou the same free Will and Power to stand?
Thou hadst: whom hast thou then or what to accuse,
But Heav'ns free Love dealt equally to all?
Be then his Love accurst, since love or hate,
To me alike, it deals eternal woe.
Nay curs'd be thou; since against his thy will
Chose freely what it now so justly rues.
Me miserable! which way shall I flie
Infinite wrauth, and infinite despaire?
Which way I flie is Hell; my self am Hell;
And in the lowest deep a lower deep
Still threatning to devour me opens wide,
To which the Hell I suffer seems a Heav'n.
O then at last relent: is there no place
Left for Repentance, none for Pardon left?
None left but by submission; and that word
DISDAIN forbids me, and my dread of shame
Among the spirits beneath, whom I seduc'd
With other promises and other vaunts
Then to submit, boasting I could subdue
Th' Omnipotent. Ay me, they little know
How dearly I abide that boast so vaine,
Under what torments inwardly I groane;
While they adore me on the Throne of Hell,
With Diadem and Scepter high advanc'd
The lower still I fall, onely Supream
In miserie; such joy Ambition findes.
But say I could repent and could obtaine
By Act of Grace my former state; how soon
Would highth recal high thoughts, how soon unsay
What feign'd submission swore: ease would recant
Vows made in pain, as violent and void.
For never can true reconcilement grow
Where wounds of deadly hate have peirc'd so deep:
Which would but lead me to a worse relapse
And heavier fall: so should I purchase deare
Short intermission bought with double smart.
This knows my punisher; therefore as farr
From granting hee, as I from begging peace:
All hope excluded thus, behold in stead
Of us out-cast, exil'd, his new delight,
Mankind created, and for him this World.
So farwel Hope, and with Hope farwel Fear,
Farwel Remorse: all Good to me is lost;
Evil be thou my Good; by thee at least
Divided Empire with Heav'ns King I hold
By thee, and more then half perhaps will reigne;
As Man ere long, and this new World shall know.
Thus while he spake, each passion dimm'd his face
Thrice chang'd with pale, ire, envie and despair,
Which marrd his borrow'd visage, and betraid
Him counterfet, if any eye beheld.
For heav'nly mindes from such distempers foule
Are ever cleer. Whereof hee soon aware,
Each perturbation smooth'd with outward calme,
Artificer of fraud; and was the first
That practisd falshood under saintly shew,
Deep malice to conceale, couch't with revenge:
Yet not anough had practisd to deceive
URIEL once warnd; whose eye pursu'd him down
The way he went, and on th' ASSYRIAN mount
Saw him disfigur'd, more then could befall
Spirit of happie sort: his gestures fierce
He markd and mad demeanour, then alone,
As he suppos'd, all unobserv'd, unseen.
So on he fares, and to the border comes
Of EDEN, where delicious Paradise,
Now nearer, Crowns with her enclosure green,
As with a rural mound the champain head
Of a steep wilderness, whose hairie sides
With thicket overgrown, grottesque and wilde,
Access deni'd; and over head up grew
Insuperable highth of loftiest shade,
Cedar, and Pine, and Firr, and branching Palm,
A Silvan Scene, and as the ranks ascend
Shade above shade, a woodie Theatre
Of stateliest view. Yet higher then thir tops
The verdurous wall of Paradise up sprung:
Which to our general Sire gave prospect large
Into his neather Empire neighbouring round.
And higher then that Wall a circling row
Of goodliest Trees loaden with fairest Fruit,
Blossoms and Fruits at once of golden hue
Appeerd, with gay enameld colours mixt:
On which the Sun more glad impress'd his beams
Then in fair Evening Cloud, or humid Bow,
When God hath showrd the earth; so lovely seemd
That Lantskip: And of pure now purer aire
Meets his approach, and to the heart inspires
Vernal delight and joy, able to drive
All sadness but despair: now gentle gales
Fanning thir odoriferous wings dispense
Native perfumes, and whisper whence they stole
Those balmie spoiles. As when to them who saile
Beyond the CAPE OF HOPE, and now are past
MOZAMBIC, off at Sea North-East windes blow
SABEAN Odours from the spicie shoare
Of ARABIE the blest, with such delay
Well pleas'd they slack thir course, and many a League
Cheard with the grateful smell old Ocean smiles.
So entertaind those odorous sweets the Fiend
Who came thir bane, though with them better pleas'd
Then ASMODEUS with the fishie fume,
That drove him, though enamourd, from the Spouse
Of TOBITS Son, and with a vengeance sent
From MEDIA post to AEGYPT, there fast bound.
Now to th' ascent of that steep savage Hill
SATAN had journied on, pensive and slow;
But further way found none, so thick entwin'd,
As one continu'd brake, the undergrowth
Of shrubs and tangling bushes had perplext
All path of Man or Beast that past that way:
One Gate there onely was, and that look'd East
On th' other side: which when th' arch-fellon saw
Due entrance he disdaind, and in contempt,
At one slight bound high overleap'd all bound
Of Hill or highest Wall, and sheer within
Lights on his feet. As when a prowling Wolfe,
Whom hunger drives to seek new haunt for prey,
Watching where Shepherds pen thir Flocks at eeve
In hurdl'd Cotes amid the field secure,
Leaps o're the fence with ease into the Fould:
Or as a Thief bent to unhoord the cash
Of some rich Burgher, whose substantial dores,
Cross-barrd and bolted fast, fear no assault,
In at the window climbes, or o're the tiles;
So clomb this first grand Thief into Gods Fould:
So since into his Church lewd Hirelings climbe.
Thence up he flew, and on the Tree of Life,
The middle Tree and highest there that grew,
Sat like a Cormorant; yet not true Life
Thereby regaind, but sat devising Death
To them who liv'd; nor on the vertue thought
Of that life-giving Plant, but only us'd
For prospect, what well us'd had bin the pledge
Of immortalitie. So little knows
Any, but God alone, to value right
The good before him, but perverts best things
To worst abuse, or to thir meanest use.
Beneath him with new wonder now he views
To all delight of human sense expos'd
In narrow room Natures whole wealth, yea more,
A Heaven on Earth, for blissful Paradise
Of God the Garden was, by him in the East
Of EDEN planted; EDEN stretchd her Line
From AURAN Eastward to the Royal Towrs
Of great SELEUCIA, built by GRECIAN Kings,
Or where the Sons of EDEN long before
Dwelt in TELASSAR: in this pleasant soile
His farr more pleasant Garden God ordaind;
Out of the fertil ground he caus'd to grow
All Trees of noblest kind for sight, smell, taste;
And all amid them stood the Tree of Life,
High eminent, blooming Ambrosial Fruit
Of vegetable Gold; and next to Life
Our Death the Tree of Knowledge grew fast by,
Knowledge of Good bought dear by knowing ill.
Southward through EDEN went a River large,
Nor chang'd his course, but through the shaggie hill
Pass'd underneath ingulft, for God had thrown
That Mountain as his Garden mould high rais'd
Upon the rapid current, which through veins
Of porous Earth with kindly thirst up drawn,
Rose a fresh Fountain, and with many a rill
Waterd the Garden; thence united fell
Down the steep glade, and met the neather Flood,
Which from his darksom passage now appeers,
And now divided into four main Streams,
Runs divers, wandring many a famous Realme
And Country whereof here needs no account,
But rather to tell how, if Art could tell,
How from that Saphire Fount the crisped Brooks,
Rowling on Orient Pearl and sands of Gold,
With mazie error under pendant shades
Ran Nectar, visiting each plant, and fed
Flours worthy of Paradise which not nice Art
In Beds and curious Knots, but Nature boon
Powrd forth profuse on Hill and Dale and Plaine,
Both where the morning Sun first warmly smote
The open field, and where the unpierc't shade
Imbround the noontide Bowrs: Thus was this place,
A happy rural seat of various view;
Groves whose rich Trees wept odorous Gumms and Balme,
Others whose fruit burnisht with Golden Rinde
Hung amiable, HESPERIAN Fables true,
If true, here onely, and of delicious taste:
Betwixt them Lawns, or level Downs, and Flocks
Grasing the tender herb, were interpos'd,
Or palmie hilloc, or the flourie lap
Of som irriguous Valley spread her store,
Flours of all hue, and without Thorn the Rose:
Another side, umbrageous Grots and Caves
Of coole recess, o're which the mantling Vine
Layes forth her purple Grape, and gently creeps
Luxuriant; mean while murmuring waters fall
Down the slope hills, disperst, or in a Lake,
That to the fringed Bank with Myrtle crownd,
Her chrystall mirror holds, unite thir streams.
The Birds thir quire apply; aires, vernal aires,
Breathing the smell of field and grove, attune
The trembling leaves, while Universal PAN
Knit with the GRACES and the HOURS in dance
Led on th' Eternal Spring. Not that faire field
Of ENNA, where PROSERPIN gathring flours
Her self a fairer Floure by gloomie DIS
Was gatherd, which cost CERES all that pain
To seek her through the world; nor that sweet Grove
Of DAPHNE by ORONTES, and th' inspir'd
CASTALIAN Spring might with this Paradise
Of EDEN strive; nor that NYSEIAN Ile
Girt with the River TRITON, where old CHAM,
Whom Gentiles AMMON call and LIBYAN JOVE,
Hid AMALTHEA and her Florid Son
Young BACCHUS from his Stepdame RHEA'S eye;
Nor where ABASSIN Kings thir issue Guard,
Mount AMARA, though this by som suppos'd
True Paradise under the ETHIOP Line
By NILUS head, enclos'd with shining Rock,
A whole dayes journey high, but wide remote
From this ASSYRIAN Garden, where the Fiend
Saw undelighted all delight, all kind
Of living Creatures new to sight and strange:
Two of far nobler shape erect and tall,
Godlike erect, with native Honour clad
In naked Majestie seemd Lords of all,
And worthie seemd, for in thir looks Divine
The image of thir glorious Maker shon,
Truth, Wisdome, Sanctitude severe and pure,
Severe, but in true filial freedom plac't;
Whence true autoritie in men; though both
Not equal, as thir sex not equal seemd;
For contemplation hee and valour formd,
For softness shee and sweet attractive Grace,
Hee for God only, shee for God in him:
His fair large Front and Eye sublime declar'd
Absolute rule; and Hyacinthin Locks
Round from his parted forelock manly hung
Clustring, but not beneath his shoulders broad:
Shee as a vail down to the slender waste
Her unadorned golden tresses wore
Dissheveld, but in wanton ringlets wav'd
As the Vine curles her tendrils, which impli'd
Subjection, but requir'd with gentle sway,
And by her yeilded, by him best receivd,
Yeilded with coy submission, modest pride,
And sweet reluctant amorous delay.
Nor those mysterious parts were then conceald,
Then was not guiltie shame, dishonest shame
Of natures works, honor dishonorable,
Sin-bred, how have ye troubl'd all mankind
With shews instead, meer shews of seeming pure,
And banisht from mans life his happiest life,
Simplicitie and spotless innocence.
So passd they naked on, nor shund the sight
Of God or Angel, for they thought no ill:
So hand in hand they passd, the lovliest pair
That ever since in loves imbraces met,
ADAM the goodliest man of men since borne
His Sons, the fairest of her Daughters EVE.
Under a tuft of shade that on a green
Stood whispering soft, by a fresh Fountain side
They sat them down, and after no more toil
Of thir sweet Gardning labour then suffic'd
To recommend coole ZEPHYR, and made ease
More easie, wholsom thirst and appetite
More grateful, to thir Supper Fruits they fell,
Nectarine Fruits which the compliant boughes
Yeilded them, side-long as they sat recline
On the soft downie Bank damaskt with flours:
The savourie pulp they chew, and in the rinde
Still as they thirsted scoop the brimming stream;
Nor gentle purpose, nor endearing smiles
Wanted, nor youthful dalliance as beseems
Fair couple, linkt in happie nuptial League,
Alone as they. About them frisking playd
All Beasts of th' Earth, since wilde, and of all chase
In Wood or Wilderness, Forrest or Den;
Sporting the Lion rampd, and in his paw
Dandl'd the Kid; Bears, Tygers, Ounces, Pards
Gambold before them, th' unwieldy Elephant
To make them mirth us'd all his might, & wreathd
His Lithe Proboscis; close the Serpent sly
Insinuating, wove with Gordian twine
His breaded train, and of his fatal guile
Gave proof unheeded; others on the grass
Coucht, and now fild with pasture gazing sat,
Or Bedward ruminating: for the Sun
Declin'd was hasting now with prone carreer
To th' Ocean Iles, and in th' ascending Scale
Of Heav'n the Starrs that usher Evening rose:
When SATAN still in gaze, as first he stood,
Scarce thus at length faild speech recoverd sad.
O Hell! what doe mine eyes with grief behold,
Into our room of bliss thus high advanc't
Creatures of other mould, earth-born perhaps,
Not Spirits, yet to heav'nly Spirits bright
Little inferior; whom my thoughts pursue
With wonder, and could love, so lively shines
In them Divine resemblance, and such grace
The hand that formd them on thir shape hath pourd.
Ah gentle pair, yee little think how nigh
Your change approaches, when all these delights
Will vanish and deliver ye to woe,
More woe, the more your taste is now of joy;
Happie, but for so happie ill secur'd
Long to continue, and this high seat your Heav'n
Ill fenc't for Heav'n to keep out such a foe
As now is enterd; yet no purpos'd foe
To you whom I could pittie thus forlorne
Though I unpittied: League with you I seek,
And mutual amitie so streight, so close,
That I with you must dwell, or you with me
Henceforth; my dwelling haply may not please
Like this fair Paradise, your sense, yet such
Accept your Makers work; he gave it me,
Which I as freely give; Hell shall unfould,
To entertain you two, her widest Gates,
And send forth all her Kings; there will be room,
Not like these narrow limits, to receive
Your numerous ofspring; if no better place,
Thank him who puts me loath to this revenge
On you who wrong me not for him who wrongd.
And should I at your harmless innocence
Melt, as I doe, yet public reason just,
Honour and Empire with revenge enlarg'd,
By conquering this new World, compels me now
To do what else though damnd I should abhorre.
So spake the Fiend, and with necessitie,
The Tyrants plea, excus'd his devilish deeds.
Then from his loftie stand on that high Tree
Down he alights among the sportful Herd
Of those fourfooted kindes, himself now one,
Now other, as thir shape servd best his end
Neerer to view his prey, and unespi'd
To mark what of thir state he more might learn
By word or action markt: about them round
A Lion now he stalkes with fierie glare,
Then as a Tiger, who by chance hath spi'd
In some Purlieu two gentle Fawnes at play,
Strait couches close, then rising changes oft
His couchant watch, as one who chose his ground
Whence rushing he might surest seise them both
Grip't in each paw: when ADAM first of men
To first of women EVE thus moving speech,
Turnd him all eare to heare new utterance flow.
Sole partner and sole part of all these joyes,
Dearer thy self then all; needs must the Power
That made us, and for us this ample World
Be infinitly good, and of his good
As liberal and free as infinite,
That rais'd us from the dust and plac't us here
In all this happiness, who at his hand
Have nothing merited, nor can performe
Aught whereof hee hath need, hee who requires
From us no other service then to keep
This one, this easie charge, of all the Trees
In Paradise that beare delicious fruit
So various, not to taste that onely Tree
Of knowledge, planted by the Tree of Life,
So neer grows Death to Life, what ere Death is,
Som dreadful thing no doubt; for well thou knowst
God hath pronounc't it death to taste that Tree,
The only sign of our obedience left
Among so many signes of power and rule
Conferrd upon us, and Dominion giv'n
Over all other Creatures that possesse
Earth, Aire, and Sea. Then let us not think hard
One easie prohibition, who enjoy
Free leave so large to all things else, and choice
Unlimited of manifold delights:
But let us ever praise him, and extoll
His bountie, following our delightful task
To prune these growing Plants, & tend these Flours,
Which were it toilsom, yet with thee were sweet.
To whom thus Eve repli'd. O thou for whom
And from whom I was formd flesh of thy flesh,
And without whom am to no end, my Guide
And Head, what thou hast said is just and right.
For wee to him indeed all praises owe,
And daily thanks, I chiefly who enjoy
So farr the happier Lot, enjoying thee
Preeminent by so much odds, while thou
Like consort to thy self canst no where find.
That day I oft remember, when from sleep
I first awak't, and found my self repos'd
Under a shade on flours, much wondring where
And what I was, whence thither brought, and how.
Not distant far from thence a murmuring sound
Of waters issu'd from a Cave and spread
Into a liquid Plain, then stood unmov'd
Pure as th' expanse of Heav'n; I thither went
With unexperienc't thought, and laid me downe
On the green bank, to look into the cleer
Smooth Lake, that to me seemd another Skie.
As I bent down to look, just opposite,
A Shape within the watry gleam appeerd
Bending to look on me, I started back,
It started back, but pleasd I soon returnd,
Pleas'd it returnd as soon with answering looks
Of sympathie and love, there I had fixt
Mine eyes till now, and pin'd with vain desire,
Had not a voice thus warnd me, What thou seest,
What there thou seest fair Creature is thy self,
With thee it came and goes: but follow me,
And I will bring thee where no shadow staies
Thy coming, and thy soft imbraces, hee
Whose image thou art, him thou shall enjoy
Inseparablie thine, to him shalt beare
Multitudes like thy self, and thence be call'd
Mother of human Race: what could I doe,
But follow strait, invisibly thus led?
Till I espi'd thee, fair indeed and tall,
Under a Platan, yet methought less faire,
Less winning soft, less amiablie milde,
Then that smooth watry image; back I turnd,
Thou following cryd'st aloud, Return fair EVE,
Whom fli'st thou? whom thou fli'st, of him thou art,
His flesh, his bone; to give thee being I lent
Out of my side to thee, neerest my heart
Substantial Life, to have thee by my side
Henceforth an individual solace dear;
Part of my Soul I seek thee, and thee claim
My other half: with that thy gentle hand
Seisd mine, I yeilded, and from that time see
How beauty is excelld by manly grace
And wisdom, which alone is truly fair.
So spake our general Mother, and with eyes
Of conjugal attraction unreprov'd,
And meek surrender, half imbracing leand
On our first Father, half her swelling Breast
Naked met his under the flowing Gold
Of her loose tresses hid: he in delight
Both of her Beauty and submissive Charms
Smil'd with superior Love, as JUPITER
On JUNO smiles, when he impregns the Clouds
That shed MAY Flowers; and press'd her Matron lip
With kisses pure: aside the Devil turnd
For envie, yet with jealous leer maligne
Ey'd them askance, and to himself thus plaind.
Sight hateful, sight tormenting! thus these two
Imparadis't in one anothers arms
The happier EDEN, shall enjoy thir fill
Of bliss on bliss, while I to Hell am thrust,
Where neither joy nor love, but fierce desire,
Among our other torments not the least,
Still unfulfill'd with pain of longing pines;
Yet let me not forget what I have gain'd
From thir own mouths; all is not theirs it seems:
One fatal Tree there stands of Knowledge call'd,
Forbidden them to taste: Knowledge forbidd'n?
Suspicious, reasonless. Why should thir Lord
Envie them that? can it be sin to know,
Can it be death? and do they onely stand
By Ignorance, is that thir happie state,
The proof of thir obedience and thir faith?
O fair foundation laid whereon to build
Thir ruine! Hence I will excite thir minds
With more desire to know, and to reject
Envious commands, invented with designe
To keep them low whom knowledge might exalt
Equal with Gods; aspiring to be such,
They taste and die: what likelier can ensue?
But first with narrow search I must walk round
This Garden, and no corner leave unspi'd;
A chance but chance may lead where I may meet
Some wandring Spirit of Heav'n, by Fountain side,
Or in thick shade retir'd, from him to draw
What further would be learnt. Live while ye may,
Yet happie pair; enjoy, till I return,
Short pleasures, for long woes are to succeed.
So saying, his proud step he scornful turn'd,
But with sly circumspection, and began
Through wood, through waste, o're hil, o're dale his roam.
Mean while in utmost Longitude, where Heav'n
With Earth and Ocean meets, the setting Sun
Slowly descended, and with right aspect
Against the eastern Gate of Paradise
Leveld his eevning Rayes: it was a Rock
Of Alablaster, pil'd up to the Clouds,
Conspicuous farr, winding with one ascent
Accessible from Earth, one entrance high;
The rest was craggie cliff, that overhung
Still as it rose, impossible to climbe.
Betwixt these rockie Pillars GABRIEL sat
Chief of th' Angelic Guards, awaiting night;
About him exercis'd Heroic Games
Th' unarmed Youth of Heav'n, but nigh at hand
Celestial Armourie, Shields, Helmes, and Speares
Hung high with Diamond flaming, and with Gold.
Thither came URIEL, gliding through the Eeven
On a Sun beam, swift as a shooting Starr
In AUTUMN thwarts the night, when vapors fir'd
Impress the Air, and shews the Mariner
From what point of his Compass to beware
Impetuous winds: he thus began in haste.
GABRIEL, to thee thy cours by Lot hath giv'n
Charge and strict watch that to this happie place
No evil thing approach or enter in;
This day at highth of Noon came to my Spheare
A Spirit, zealous, as he seem'd, to know
More of th' Almighties works, and chiefly Man
Gods latest Image: I describ'd his way
Bent all on speed, and markt his Aerie Gate;
But in the Mount that lies from EDEN North,
Where he first lighted, soon discernd his looks
Alien from Heav'n, with passions foul obscur'd:
Mine eye pursu'd him still, but under shade
Lost sight of him; one of the banisht crew
I fear, hath ventur'd from the deep, to raise
New troubles; him thy care must be to find.
To whom the winged Warriour thus returnd:
URIEL, no wonder if thy perfet sight,
Amid the Suns bright circle where thou sitst,
See farr and wide: in at this Gate none pass
The vigilance here plac't, but such as come
Well known from Heav'n; and since Meridian hour
No Creature thence: if Spirit of other sort,
So minded, have oreleapt these earthie bounds
On purpose, hard thou knowst it to exclude
Spiritual substance with corporeal barr.
But if within the circuit of these walks
In whatsoever shape he lurk, of whom
Thou telst, by morrow dawning I shall know.
So promis'd hee, and URIEL to his charge
Returnd on that bright beam, whose point now raisd
Bore him slope downward to the Sun now fall'n
Beneath th' AZORES; whither the prime Orb,
Incredible how swift, had thither rowl'd
Diurnal, or this less volubil Earth
By shorter flight to th' East, had left him there
Arraying with reflected Purple and Gold
The Clouds that on his Western Throne attend:
Now came still Eevning on, and Twilight gray
Had in her sober Liverie all things clad;
Silence accompanied, for Beast and Bird,
They to thir grassie Couch, these to thir Nests
Were slunk, all but the wakeful Nightingale;
She all night long her amorous descant sung;
Silence was pleas'd: now glow'd the Firmament
With living Saphirs: HESPERUS that led
The starrie Host, rode brightest, till the Moon
Rising in clouded Majestie, at length
Apparent Queen unvaild her peerless light,
And o're the dark her Silver Mantle threw.
When ADAM thus to EVE: Fair Consort, th' hour
Of night, and all things now retir'd to rest
Mind us of like repose, since God hath set
Labour and rest, as day and night to men
Successive, and the timely dew of sleep
Now falling with soft slumbrous weight inclines
Our eye-lids; other Creatures all day long
Rove idle unimploid, and less need rest;
Man hath his daily work of body or mind
Appointed, which declares his Dignitie,
And the regard of Heav'n on all his waies;
While other Animals unactive range,
And of thir doings God takes no account.
Tomorrow ere fresh Morning streak the East
With first approach of light, we must be ris'n,
And at our pleasant labour, to reform
Yon flourie Arbors, yonder Allies green,
Our walks at noon, with branches overgrown,
That mock our scant manuring, and require
More hands then ours to lop thir wanton growth:
Those Blossoms also, and those dropping Gumms,
That lie bestrowne unsightly and unsmooth,
Ask riddance, if we mean to tread with ease;
Mean while, as Nature wills, Night bids us rest.
To whom thus EVE with perfet beauty adornd.
My Author and Disposer, what thou bidst
Unargu'd I obey; so God ordains,
God is thy Law, thou mine: to know no more
Is womans happiest knowledge and her praise.
With thee conversing I forget all time,
All seasons and thir change, all please alike.
Sweet is the breath of morn, her rising sweet,
With charm of earliest Birds; pleasant the Sun
When first on this delightful Land he spreads
His orient Beams, on herb, tree, fruit, and flour,
Glistring with dew; fragrant the fertil earth
After soft showers; and sweet the coming on
Of grateful Eevning milde, then silent Night
With this her solemn Bird and this fair Moon,
And these the Gemms of Heav'n, her starrie train:
But neither breath of Morn when she ascends
With charm of earliest Birds, nor rising Sun
On this delightful land, nor herb, fruit, floure,
Glistring with dew, nor fragrance after showers,
Nor grateful Evening mild, nor silent Night
With this her solemn Bird, nor walk by Moon,
Or glittering Starr-light without thee is sweet.
But wherfore all night long shine these, for whom
This glorious sight, when sleep hath shut all eyes?
To whom our general Ancestor repli'd.
Daughter of God and Man, accomplisht EVE,
Those have thir course to finish, round the Earth,
By morrow Eevning, and from Land to Land
In order, though to Nations yet unborn,
Ministring light prepar'd, they set and rise;
Least total darkness should by Night regaine
Her old possession, and extinguish life
In Nature and all things, which these soft fires
Not only enlighten, but with kindly heate
Of various influence foment and warme,
Temper or nourish, or in part shed down
Thir stellar vertue on all kinds that grow
On Earth, made hereby apter to receive
Perfection from the Suns more potent Ray.
These then, though unbeheld in deep of night,
Shine not in vain, nor think, though men were none,
That heav'n would want spectators, God want praise;
Millions of spiritual Creatures walk the Earth
Unseen, both when we wake, and when we sleep:
All these with ceasless praise his works behold
Both day and night: how often from the steep
Of echoing Hill or Thicket have we heard
Celestial voices to the midnight air,
Sole, or responsive each to others note
Singing thir great Creator: oft in bands
While they keep watch, or nightly rounding walk
With Heav'nly touch of instrumental sounds
In full harmonic number joind, thir songs
Divide the night, and lift our thoughts to Heaven.
Thus talking hand in hand alone they pass'd
On to thir blissful Bower; it was a place
Chos'n by the sovran Planter, when he fram'd
All things to mans delightful use; the roofe
Of thickest covert was inwoven shade
Laurel and Mirtle, and what higher grew
Of firm and fragrant leaf; on either side
ACANTHUS, and each odorous bushie shrub
Fenc'd up the verdant wall; each beauteous flour,
IRIS all hues, Roses, and Gessamin
Rear'd high thir flourisht heads between, and wrought
Mosaic; underfoot the Violet,
Crocus, and Hyacinth with rich inlay
Broiderd the ground, more colour'd then with stone
Of costliest Emblem: other Creature here
Beast, Bird, Insect, or Worm durst enter none;
Such was thir awe of man. In shadier Bower
More sacred and sequesterd, though but feignd,
PAN or SILVANUS never slept, nor Nymph,
Nor FAUNUS haunted. Here in close recess
With Flowers, Garlands, and sweet-smelling Herbs
Espoused EVE deckt first her Nuptial Bed,
And heav'nly Quires the Hymenaean sung,
What day the genial Angel to our Sire
Brought her in naked beauty more adorn'd,
More lovely then PANDORA, whom the Gods
Endowd with all thir gifts, and O too like
In sad event, when to the unwiser Son
Of JAPHET brought by HERMES, she ensnar'd
Mankind with her faire looks, to be aveng'd
On him who had stole JOVES authentic fire.
Thus at thir shadie Lodge arriv'd, both stood,
Both turnd, and under op'n Skie ador'd
The God that made both Skie, Air, Earth & Heav'n
Which they beheld, the Moons resplendent Globe
And starrie Pole: Thou also mad'st the Night,
Maker Omnipotent, and thou the Day,
Which we in our appointed work imployd
Have finisht happie in our mutual help
And mutual love, the Crown of all our bliss
Ordain'd by thee, and this delicious place
For us too large, where thy abundance wants
Partakers, and uncropt falls to the ground.
But thou hast promis'd from us two a Race
To fill the Earth, who shall with us extoll
Thy goodness infinite, both when we wake,
And when we seek, as now, thy gift of sleep.
This said unanimous, and other Rites
Observing none, but adoration pure
Which God likes best, into thir inmost bower
Handed they went; and eas'd the putting off
These troublesom disguises which wee wear,
Strait side by side were laid, nor turnd I weene
ADAM from his fair Spouse, nor EVE the Rites
Mysterious of connubial Love refus'd:
Whatever Hypocrites austerely talk
Of puritie and place and innocence,
Defaming as impure what God declares
Pure, and commands to som, leaves free to all.
Our Maker bids increase, who bids abstain
But our Destroyer, foe to God and Man?
Haile wedded Love, mysterious Law, true source
Of human ofspring, sole proprietie,
In Paradise of all things common else.
By thee adulterous lust was driv'n from men
Among the bestial herds to raunge, by thee
Founded in Reason, Loyal, Just, and Pure,
Relations dear, and all the Charities
Of Father, Son, and Brother first were known.
Farr be it, that I should write thee sin or blame,
Or think thee unbefitting holiest place,
Perpetual Fountain of Domestic sweets,
Whose Bed is undefil'd and chast pronounc't,
Present, or past, as Saints and Patriarchs us'd.
Here Love his golden shafts imploies, here lights
His constant Lamp, and waves his purple wings,
Reigns here and revels; not in the bought smile
Of Harlots, loveless, joyless, unindeard,
Casual fruition, nor in Court Amours
Mixt Dance, or wanton Mask, or Midnight Bal,
Or Serenate, which the starv'd Lover sings
To his proud fair, best quitted with disdain.
These lulld by Nightingales imbraceing slept,
And on thir naked limbs the flourie roof
Showrd Roses, which the Morn repair'd. Sleep on,
Blest pair; and O yet happiest if ye seek
No happier state, and know to know no more.
Now had night measur'd with her shaddowie Cone
Half way up Hill this vast Sublunar Vault,
And from thir Ivorie Port the Cherubim
Forth issuing at th' accustomd hour stood armd
To thir night watches in warlike Parade,
When GABRIEL to his next in power thus spake.
UZZIEL, half these draw off, and coast the South
With strictest watch; these other wheel the North,
Our circuit meets full West. As flame they part
Half wheeling to the Shield, half to the Spear.
From these, two strong and suttle Spirits he calld
That neer him stood, and gave them thus in charge.
ITHURIEL and ZEPHON, with wingd speed
Search through this Garden, leav unsearcht no nook,
But chiefly where those two fair Creatures Lodge,
Now laid perhaps asleep secure of harme.
This Eevning from the Sun's decline arriv'd
Who tells of som infernal Spirit seen
Hitherward bent (who could have thought?) escap'd
The barrs of Hell, on errand bad no doubt:
Such where ye find, seise fast, and hither bring.
So saying, on he led his radiant Files,
Daz'ling the Moon; these to the Bower direct
In search of whom they sought: him there they found
Squat like a Toad, close at the eare of EVE;
Assaying by his Devilish art to reach
The Organs of her Fancie, and with them forge
Illusions as he list, Phantasms and Dreams,
Or if, inspiring venom, he might taint
Th' animal Spirits that from pure blood arise
Like gentle breaths from Rivers pure, thence raise
At least distemperd, discontented thoughts,
Vain hopes, vain aimes, inordinate desires
Blown up with high conceits ingendring pride.
Him thus intent ITHURIEL with his Spear
Touch'd lightly; for no falshood can endure
Touch of Celestial temper, but returns
Of force to its own likeness: up he starts
Discoverd and surpriz'd. As when a spark
Lights on a heap of nitrous Powder, laid
Fit for the Tun som Magazin to store
Against a rumord Warr, the Smuttie graine
With sudden blaze diffus'd, inflames the Aire:
So started up in his own shape the Fiend.
Back stept those two fair Angels half amaz'd
So sudden to behold the grieslie King;
Yet thus, unmovd with fear, accost him soon.
Which of those rebell Spirits adjudg'd to Hell
Com'st thou, escap'd thy prison, and transform'd,
Why satst thou like an enemie in waite
Here watching at the head of these that sleep?
Know ye not then said SATAN, filld with scorn,
Know ye not me? ye knew me once no mate
For you, there sitting where ye durst not soare;
Not to know mee argues your selves unknown,
The lowest of your throng; or if ye know,
Why ask ye, and superfluous begin
Your message, like to end as much in vain?
To whom thus ZEPHON, answering scorn with scorn.
Think not, revolted Spirit, thy shape the same,
Or undiminisht brightness, to be known
As when thou stoodst in Heav'n upright and pure;
That Glorie then, when thou no more wast good,
Departed from thee, and thou resembl'st now
Thy sin and place of doom obscure and foule.
But come, for thou, be sure, shalt give account
To him who sent us, whose charge is to keep
This place inviolable, and these from harm.
So spake the Cherube, and his grave rebuke
Severe in youthful beautie, added grace
Invincible: abasht the Devil stood,
And felt how awful goodness is, and saw
Vertue in her shape how lovly, saw, and pin'd
His loss; but chiefly to find here observd
His lustre visibly impar'd; yet seemd
Undaunted. If I must contend, said he,
Best with the best, the Sender not the sent,
Or all at once; more glorie will be wonn,
Or less be lost. Thy fear, said ZEPHON bold,
Will save us trial what the least can doe
Single against thee wicked, and thence weak.
The Fiend repli'd not, overcome with rage;
But like a proud Steed reind, went hautie on,
Chaumping his iron curb: to strive or flie
He held it vain; awe from above had quelld
His heart, not else dismai'd. Now drew they nigh
The western point, where those half-rounding guards
Just met, & closing stood in squadron joind
Awaiting next command. To whom thir Chief
GABRIEL from the Front thus calld aloud.
O friends, I hear the tread of nimble feet
Hasting this way, and now by glimps discerne
ITHURIEL and ZEPHON through the shade,
And with them comes a third of Regal port,
But faded splendor wan; who by his gate
And fierce demeanour seems the Prince of Hell,
Not likely to part hence without contest;
Stand firm, for in his look defiance lours.
He scarce had ended, when those two approachd
And brief related whom they brought, wher found,
How busied, in what form and posture coucht.
To whom with stern regard thus GABRIEL spake.
Why hast thou, SATAN, broke the bounds prescrib'd
To thy transgressions, and disturbd the charge
Of others, who approve not to transgress
By thy example, but have power and right
To question thy bold entrance on this place;
Imploi'd it seems to violate sleep, and those
Whose dwelling God hath planted here in bliss?
To whom thus SATAN with contemptuous brow.
GABRIEL, thou hadst in Heav'n th' esteem of wise,
And such I held thee; but this question askt
Puts me in doubt. Lives ther who loves his pain?
Who would not, finding way, break loose from Hell,
Though thither doomd? Thou wouldst thy self, no doubt,
And boldly venture to whatever place
Farthest from pain, where thou mightst hope to change
Torment with ease, & soonest recompence
Dole with delight, which in this place I sought;
To thee no reason; who knowst only good,
But evil hast not tri'd: and wilt object
His will who bound us? let him surer barr
His Iron Gates, if he intends our stay
In that dark durance: thus much what was askt.
The rest is true, they found me where they say;
But that implies not violence or harme.
Thus hee in scorn. The warlike Angel mov'd,
Disdainfully half smiling thus repli'd.
O loss of one in Heav'n to judge of wise,
Since SATAN fell, whom follie overthrew,
And now returns him from his prison scap't,
Gravely in doubt whether to hold them wise
Or not, who ask what boldness brought him hither
Unlicenc't from his bounds in Hell prescrib'd;
So wise he judges it to fly from pain
However, and to scape his punishment.
So judge thou still, presumptuous, till the wrauth,
Which thou incurr'st by flying, meet thy flight
Seavenfold, and scourge that wisdom back to Hell,
Which taught thee yet no better, that no pain
Can equal anger infinite provok't.
But wherefore thou alone? wherefore with thee
Came not all Hell broke loose? is pain to them
Less pain, less to be fled, or thou then they
Less hardie to endure? courageous Chief,
The first in flight from pain, had'st thou alleg'd
To thy deserted host this cause of flight,
Thou surely hadst not come sole fugitive.
To which the Fiend thus answerd frowning stern.
Not that I less endure, or shrink from pain,
Insulting Angel, well thou knowst I stood
Thy fiercest, when in Battel to thy aide
The blasting volied Thunder made all speed
And seconded thy else not dreaded Spear.
But still thy words at random, as before,
Argue thy inexperience what behooves
From hard assaies and ill successes past
A faithful Leader, not to hazard all
Through wayes of danger by himself untri'd.
I therefore, I alone first undertook
To wing the desolate Abyss, and spie
This new created World, whereof in Hell
Fame is not silent, here in hope to find
Better abode, and my afflicted Powers
To settle here on Earth, or in mid Aire;
Though for possession put to try once more
What thou and thy gay Legions dare against;
Whose easier business were to serve thir Lord
High up in Heav'n, with songs to hymne his Throne,
And practis'd distances to cringe, not fight.
To whom the warriour Angel soon repli'd.
To say and strait unsay, pretending first
Wise to flie pain, professing next the Spie,
Argues no Leader, but a lyar trac't,
SATAN, and couldst thou faithful add? O name,
O sacred name of faithfulness profan'd!
Faithful to whom? to thy rebellious crew?
Armie of Fiends, fit body to fit head;
Was this your discipline and faith ingag'd,
Your military obedience, to dissolve
Allegeance to th' acknowledg'd Power supream?
And thou sly hypocrite, who now wouldst seem
Patron of liberty, who more then thou
Once fawn'd, and cring'd, and servilly ador'd
Heav'ns awful Monarch? wherefore but in hope
To dispossess him, and thy self to reigne?
But mark what I arreede thee now, avant;
Flie thither whence thou fledst: if from this houre
Within these hallowd limits thou appeer,
Back to th' infernal pit I drag thee chaind,
And Seale thee so, as henceforth not to scorne
The facil gates of hell too slightly barrd.
So threatn'd hee, but SATAN to no threats
Gave heed, but waxing more in rage repli'd.
Then when I am thy captive talk of chaines,
Proud limitarie Cherube, but ere then
Farr heavier load thy self expect to feel
From my prevailing arme, though Heavens King
Ride on thy wings, and thou with thy Compeers,
Us'd to the yoak, draw'st his triumphant wheels
In progress through the rode of Heav'n Star-pav'd.
While thus he spake, th' Angelic Squadron bright
Turnd fierie red, sharpning in mooned hornes
Thir Phalanx, and began to hemm him round
With ported Spears, as thick as when a field
Of CERES ripe for harvest waving bends
Her bearded Grove of ears, which way the wind
Swayes them; the careful Plowman doubting stands
Least on the threshing floore his hopeful sheaves
Prove chaff. On th' other side SATAN allarm'd
Collecting all his might dilated stood,
Like TENERIFF or ATLAS unremov'd:
His stature reacht the Skie, and on his Crest
Sat horror Plum'd; nor wanted in his graspe
What seemd both Spear and Shield: now dreadful deeds
Might have ensu'd, nor onely Paradise
In this commotion, but the Starrie Cope
Of Heav'n perhaps, or all the Elements
At least had gon to rack, disturbd and torne
With violence of this conflict, had not soon
Th' Eternal to prevent such horrid fray
Hung forth in Heav'n his golden Scales, yet seen
Betwixt ASTREA and the SCORPION signe,
Wherein all things created first he weighd,
The pendulous round Earth with ballanc't Aire
In counterpoise, now ponders all events,
Battels and Realms: in these he put two weights
The sequel each of parting and of fight;
The latter quick up flew, and kickt the beam;
Which GABRIEL spying, thus bespake the Fiend.
SATAN, I know thy strength, and thou knowst mine,
Neither our own but giv'n; what follie then
To boast what Arms can doe, since thine no more
Then Heav'n permits, nor mine, though doubld now
To trample thee as mire: for proof look up,
And read thy Lot in yon celestial Sign
Where thou art weigh'd, & shown how light, how weak,
If thou resist. The Fiend lookt up and knew
His mounted scale aloft: nor more; but fled
Murmuring, and with him fled the shades of night.
THE END OF THE FOURTH BOOK.
PARADISE LOST
BOOK V.
Now Morn her rosie steps in th' Eastern Clime
Advancing, sow'd the Earth with Orient Pearle,
When ADAM wak't, so customd, for his sleep
Was Aerie light, from pure digestion bred,
And temperat vapors bland, which th' only sound
Of leaves and fuming rills, AURORA's fan,
Lightly dispers'd, and the shrill Matin Song
Of Birds on every bough; so much the more
His wonder was to find unwak'nd EVE
With Tresses discompos'd, and glowing Cheek,
As through unquiet rest: he on his side
Leaning half-rais'd, with looks of cordial Love
Hung over her enamour'd, and beheld
Beautie, which whether waking or asleep,
Shot forth peculiar Graces; then with voice
Milde, as when ZEPHYRUS on FLORA breathes,
Her hand soft touching, whisperd thus. Awake
My fairest, my espous'd, my latest found,
Heav'ns last best gift, my ever new delight,
Awake, the morning shines, and the fresh field
Calls us, we lose the prime, to mark how spring
Our tended Plants, how blows the Citron Grove,
What drops the Myrrhe, & what the balmie Reed,
How Nature paints her colours, how the Bee
Sits on the Bloom extracting liquid sweet.
Such whispering wak'd her, but with startl'd eye
On ADAM, whom imbracing, thus she spake.
O Sole in whom my thoughts find all repose,
My Glorie, my Perfection, glad I see
Thy face, and Morn return'd, for I this Night,
Such night till this I never pass'd, have dream'd,
If dream'd, not as I oft am wont, of thee,
Works of day pass't, or morrows next designe,
But of offence and trouble, which my mind
Knew never till this irksom night; methought
Close at mine ear one call'd me forth to walk
With gentle voice, I thought it thine; it said,
Why sleepst thou EVE? now is the pleasant time,
The cool, the silent, save where silence yields
To the night-warbling Bird, that now awake
Tunes sweetest his love-labor'd song; now reignes
Full Orb'd the Moon, and with more pleasing light
Shadowie sets off the face of things; in vain,
If none regard; Heav'n wakes with all his eyes,
Whom to behold but thee, Natures desire,
In whose sight all things joy, with ravishment
Attracted by thy beauty still to gaze.
I rose as at thy call, but found thee not;
To find thee I directed then my walk;
And on, methought, alone I pass'd through ways
That brought me on a sudden to the Tree
Of interdicted Knowledge: fair it seem'd,
Much fairer to my Fancie then by day:
And as I wondring lookt, beside it stood
One shap'd & wing'd like one of those from Heav'n
By us oft seen; his dewie locks distill'd
Ambrosia; on that Tree he also gaz'd;
And O fair Plant, said he, with fruit surcharg'd,
Deigns none to ease thy load and taste thy sweet,
Nor God, nor Man; is Knowledge so despis'd?
Or envie, or what reserve forbids to taste?
Forbid who will, none shall from me withhold
Longer thy offerd good, why else set here?
This said he paus'd not, but with ventrous Arme
He pluckt, he tasted; mee damp horror chil'd
At such bold words voucht with a deed so bold:
But he thus overjoy'd, O Fruit Divine,
Sweet of thy self, but much more sweet thus cropt,
Forbidd'n here, it seems, as onely fit
For Gods, yet able to make Gods of Men:
And why not Gods of Men, since good, the more
Communicated, more abundant growes,
The Author not impair'd, but honourd more?
Here, happie Creature, fair Angelic EVE,
Partake thou also; happie though thou art,
Happier thou mayst be, worthier canst not be:
Taste this, and be henceforth among the Gods
Thy self a Goddess, not to Earth confind,
But somtimes in the Air, as wee, somtimes
Ascend to Heav'n, by merit thine, and see
What life the Gods live there, and such live thou.
So saying, he drew nigh, and to me held,
Even to my mouth of that same fruit held part
Which he had pluckt; the pleasant savourie smell
So quick'nd appetite, that I, methought,
Could not but taste. Forthwith up to the Clouds
With him I flew, and underneath beheld
The Earth outstretcht immense, a prospect wide
And various: wondring at my flight and change
To this high exaltation; suddenly
My Guide was gon, and I, me thought, sunk down,
And fell asleep; but O how glad I wak'd
To find this but a dream! Thus EVE her Night
Related, and thus ADAM answerd sad.
Best Image of my self and dearer half,
The trouble of thy thoughts this night in sleep
Affects me equally; nor can I like
This uncouth dream, of evil sprung I fear;
Yet evil whence? in thee can harbour none,
Created pure. But know that in the Soule
Are many lesser Faculties that serve
Reason as chief; among these Fansie next
Her office holds; of all external things,
Which the five watchful Senses represent,
She forms Imaginations, Aerie shapes,
Which Reason joyning or disjoyning, frames
All what we affirm or what deny, and call
Our knowledge or opinion; then retires
Into her private Cell when Nature rests.
Oft in her absence mimic Fansie wakes
To imitate her; but misjoyning shapes,
Wilde work produces oft, and most in dreams,
Ill matching words and deeds long past or late.
Som such resemblances methinks I find
Of our last Eevnings talk, in this thy dream,
But with addition strange; yet be not sad.
Evil into the mind of God or Man
May come and go, so unapprov'd, and leave
No spot or blame behind: Which gives me hope
That what in sleep thou didst abhorr to dream,
Waking thou never wilt consent to do.
Be not disheart'nd then, nor cloud those looks
That wont to be more chearful and serene
Then when fair Morning first smiles on the World,
And let us to our fresh imployments rise
Among the Groves, the Fountains, and the Flours
That open now thir choicest bosom'd smells
Reservd from night, and kept for thee in store.
So cheard he his fair Spouse, and she was cheard,
But silently a gentle tear let fall
From either eye, and wip'd them with her haire;
Two other precious drops that ready stood,
Each in thir chrystal sluce, hee ere they fell
Kiss'd as the gracious signs of sweet remorse
And pious awe, that feard to have offended.
So all was cleard, and to the Field they haste.
But first from under shadie arborous roof,
Soon as they forth were come to open sight
Of day-spring, and the Sun, who scarce up risen
With wheels yet hov'ring o're the Ocean brim,
Shot paralel to the earth his dewie ray,
Discovering in wide Lantskip all the East
Of Paradise and EDENS happie Plains,
Lowly they bow'd adoring, and began
Thir Orisons, each Morning duly paid
In various style, for neither various style
Nor holy rapture wanted they to praise
Thir Maker, in fit strains pronounc't or sung
Unmeditated, such prompt eloquence
Flowd from thir lips, in Prose or numerous Verse,
More tuneable then needed Lute or Harp
To add more sweetness, and they thus began.
These are thy glorious works, Parent of good,
Almightie, thine this universal Frame,
Thus wondrous fair; thy self how wondrous then!
Unspeakable, who sitst above these Heavens
To us invisible or dimly seen
In these thy lowest works, yet these declare
Thy goodness beyond thought, and Power Divine:
Speak yee who best can tell, ye Sons of light,
Angels, for yee behold him, and with songs
And choral symphonies, Day without Night,
Circle his Throne rejoycing, yee in Heav'n,
On Earth joyn all yee Creatures to extoll
Him first, him last, him midst, and without end.
Fairest of Starrs, last in the train of Night,
If better thou belong not to the dawn,
Sure pledge of day, that crownst the smiling Morn
With thy bright Circlet, praise him in thy Spheare
While day arises, that sweet hour of Prime.
Thou Sun, of this great World both Eye and Soule,
Acknowledge him thy Greater, sound his praise
In thy eternal course, both when thou climb'st,
And when high Noon hast gaind, & when thou fallst.
Moon, that now meetst the orient Sun, now fli'st
With the fixt Starrs, fixt in thir Orb that flies,
And yee five other wandring Fires that move
In mystic Dance not without Song, resound
His praise, who out of Darkness call'd up Light.
Aire, and ye Elements the eldest birth
Of Natures Womb, that in quaternion run
Perpetual Circle, multiform; and mix
And nourish all things, let your ceasless change
Varie to our great Maker still new praise.
Ye Mists and Exhalations that now rise
From Hill or steaming Lake, duskie or grey,
Till the Sun paint your fleecie skirts with Gold,
In honour to the Worlds great Author rise,
Whether to deck with Clouds the uncolourd skie,
Or wet the thirstie Earth with falling showers,
Rising or falling still advance his praise.
His praise ye Winds, that from four Quarters blow,
Breath soft or loud; and wave your tops, ye Pines,
With every Plant, in sign of Worship wave.
Fountains and yee, that warble, as ye flow,
Melodious murmurs, warbling tune his praise.
Joyn voices all ye living Souls, ye Birds,
That singing up to Heaven Gate ascend,
Bear on your wings and in your notes his praise;
Yee that in Waters glide, and yee that walk
The Earth, and stately tread, or lowly creep;
Witness if I be silent, Morn or Eeven,
To Hill, or Valley, Fountain, or fresh shade
Made vocal by my Song, and taught his praise.
Hail universal Lord, be bounteous still
To give us onely good; and if the night
Have gathered aught of evil or conceald,
Disperse it, as now light dispels the dark.
So pray'd they innocent, and to thir thoughts
Firm peace recoverd soon and wonted calm.
On to thir mornings rural work they haste
Among sweet dewes and flours; where any row
Of Fruit-trees overwoodie reachd too farr
Thir pamperd boughes, and needed hands to check
Fruitless imbraces: or they led the Vine
To wed her Elm; she spous'd about him twines
Her mariageable arms, and with her brings
Her dowr th' adopted Clusters, to adorn
His barren leaves. Them thus imploid beheld
With pittie Heav'ns high King, and to him call'd
RAPHAEL, the sociable Spirit, that deign'd
To travel with TOBIAS, and secur'd
His marriage with the seaventimes-wedded Maid.
RAPHAEL, said hee, thou hear'st what stir on Earth
SATAN from Hell scap't through the darksom Gulf
Hath raisd in Paradise, and how disturbd
This night the human pair, how he designes
In them at once to ruin all mankind.
Go therefore, half this day as friend with friend
Converse with ADAM, in what Bowre or shade
Thou find'st him from the heat of Noon retir'd,
To respit his day-labour with repast,
Or with repose; and such discourse bring on,
As may advise him of his happie state,
Happiness in his power left free to will,
Left to his own free Will, his Will though free,
Yet mutable; whence warne him to beware
He swerve not too secure: tell him withall
His danger, and from whom, what enemie
Late falln himself from Heav'n, is plotting now
The fall of others from like state of bliss;
By violence, no, for that shall be withstood,
But by deceit and lies; this let him know,
Least wilfully transgressing he pretend
Surprisal, unadmonisht, unforewarnd.
So spake th' Eternal Father, and fulfilld
All Justice: nor delaid the winged Saint
After his charge receivd, but from among
Thousand Celestial Ardors, where he stood
Vaild with his gorgeous wings, up springing light
Flew through the midst of Heav'n; th' angelic Quires
On each hand parting, to his speed gave way
Through all th' Empyreal road; till at the Gate
Of Heav'n arriv'd, the gate self-opend wide
On golden Hinges turning, as by work
Divine the sov'ran Architect had fram'd.
From hence, no cloud, or, to obstruct his sight,
Starr interpos'd, however small he sees,
Not unconform to other shining Globes,
Earth and the Gard'n of God, with Cedars crownd
Above all Hills. As when by night the Glass
Of GALILEO, less assur'd, observes
Imagind Lands and Regions in the Moon:
Or Pilot from amidst the CYCLADES
DELOS or SAMOS first appeering kenns
A cloudy spot. Down thither prone in flight
He speeds, and through the vast Ethereal Skie
Sailes between worlds & worlds, with steddie wing
Now on the polar windes, then with quick Fann
Winnows the buxom Air; till within soare
Of Towring Eagles, to all the Fowles he seems
A PHOENIX, gaz'd by all, as that sole Bird
When to enshrine his reliques in the Sun's
Bright Temple, to AEGYPTIAN THEB'S he flies.
At once on th' Eastern cliff of Paradise
He lights, and to his proper shape returns
A Seraph wingd; six wings he wore, to shade
His lineaments Divine; the pair that clad
Each shoulder broad, came mantling o're his brest
With regal Ornament; the middle pair
Girt like a Starrie Zone his waste, and round
Skirted his loines and thighes with downie Gold
And colours dipt in Heav'n; the third his feet
Shaddowd from either heele with featherd maile
Skie-tinctur'd grain. Like MAIA'S son he stood,
And shook his Plumes, that Heav'nly fragrance filld
The circuit wide. Strait knew him all the bands
Of Angels under watch; and to his state,
And to his message high in honour rise;
For on som message high they guessd him bound.
Thir glittering Tents he passd, and now is come
Into the blissful field, through Groves of Myrrhe,
And flouring Odours, Cassia, Nard, and Balme;
A Wilderness of sweets; for Nature here
Wantond as in her prime, and plaid at will
Her Virgin Fancies, pouring forth more sweet,
Wilde above rule or art; enormous bliss.
Him through the spicie Forrest onward com
ADAM discernd, as in the dore he sat
Of his coole Bowre, while now the mounted Sun
Shot down direct his fervid Raies, to warme
Earths inmost womb, more warmth then ADAM need;
And EVE within, due at her hour prepar'd
For dinner savourie fruits, of taste to please
True appetite, and not disrelish thirst
Of nectarous draughts between, from milkie stream,
Berrie or Grape: to whom thus ADAM call'd.
Haste hither EVE, and worth thy sight behold
Eastward among those Trees, what glorious shape
Comes this way moving; seems another Morn
Ris'n on mid-noon; som great behest from Heav'n
To us perhaps he brings, and will voutsafe
This day to be our Guest. But goe with speed,
And what thy stores contain, bring forth and poure
Abundance, fit to honour and receive
Our Heav'nly stranger; well we may afford
Our givers thir own gifts, and large bestow
From large bestowd, where Nature multiplies
Her fertil growth, and by disburd'ning grows
More fruitful, which instructs us not to spare.
To whom thus EVE. ADAM, earths hallowd mould,
Of God inspir'd, small store will serve, where store,
All seasons, ripe for use hangs on the stalk;
Save what by frugal storing firmness gains
To nourish, and superfluous moist consumes:
But I will haste and from each bough and break,
Each Plant & juciest Gourd will pluck such choice
To entertain our Angel guest, as hee
Beholding shall confess that here on Earth
God hath dispenst his bounties as in Heav'n.
So saying, with dispatchful looks in haste
She turns, on hospitable thoughts intent
What choice to chuse for delicacie best,
What order, so contriv'd as not to mix
Tastes, not well joynd, inelegant, but bring
Taste after taste upheld with kindliest change,
Bestirs her then, and from each tender stalk
Whatever Earth all-bearing Mother yeilds
In INDIA East or West, or middle shoare
In PONTUS or the PUNIC Coast, or where
ALCINOUS reign'd, fruit of all kindes, in coate,
Rough, or smooth rin'd, or bearded husk, or shell
She gathers, Tribute large, and on the board
Heaps with unsparing hand; for drink the Grape
She crushes, inoffensive moust, and meathes
From many a berrie, and from sweet kernels prest
She tempers dulcet creams, nor these to hold
Wants her fit vessels pure, then strews the ground
With Rose and Odours from the shrub unfum'd.
Mean while our Primitive great Sire, to meet
His god-like Guest, walks forth, without more train
Accompani'd then with his own compleat
Perfections, in himself was all his state,
More solemn then the tedious pomp that waits
On Princes, when thir rich Retinue long
Of Horses led, and Grooms besmeard with Gold
Dazles the croud, and sets them all agape.
Neerer his presence ADAM though not awd,
Yet with submiss approach and reverence meek,
As to a superior Nature, bowing low,
Thus said. Native of Heav'n, for other place
None can then Heav'n such glorious shape contain;
Since by descending from the Thrones above,
Those happie places thou hast deignd a while
To want, and honour these, voutsafe with us
Two onely, who yet by sov'ran gift possess
This spacious ground, in yonder shadie Bowre
To rest, and what the Garden choicest bears
To sit and taste, till this meridian heat
Be over, and the Sun more coole decline.
Whom thus the Angelic Vertue answerd milde.
ADAM, I therefore came, nor art thou such
Created, or such place hast here to dwell,
As may not oft invite, though Spirits of Heav'n
To visit thee; lead on then where thy Bowre
Oreshades; for these mid-hours, till Eevning rise
I have at will. So to the Silvan Lodge
They came, that like POMONA'S Arbour smil'd
With flourets deck't and fragrant smells; but EVE
Undeckt, save with her self more lovely fair
Then Wood-Nymph, or the fairest Goddess feign'd
Of three that in Mount IDA naked strove,
Stood to entertain her guest from Heav'n; no vaile
Shee needed, Vertue-proof, no thought infirme
Alterd her cheek. On whom the Angel HAILE
Bestowd, the holy salutation us'd
Long after to blest MARIE, second EVE.
Haile Mother of Mankind, whose fruitful Womb
Shall fill the World more numerous with thy Sons
Then with these various fruits the Trees of God
Have heap'd this Table. Rais'd of grassie terf
Thir Table was, and mossie seats had round,
And on her ample Square from side to side
All AUTUMN pil'd, though SPRING and AUTUMN here
Danc'd hand in hand. A while discourse they hold;
No fear lest Dinner coole; when thus began
Our Authour. Heav'nly stranger, please to taste
These bounties which our Nourisher, from whom
All perfet good unmeasur'd out, descends,
To us for food and for delight hath caus'd
The Earth to yeild; unsavourie food perhaps
To spiritual Natures; only this I know,
That one Celestial Father gives to all.
To whom the Angel. Therefore what he gives
(Whose praise be ever sung) to man in part
Spiritual, may of purest Spirits be found
No ingrateful food: and food alike those pure
Intelligential substances require
As doth your Rational; and both contain
Within them every lower facultie
Of sense, whereby they hear, see, smell, touch, taste,
Tasting concoct, digest, assimilate,
And corporeal to incorporeal turn.
For know, whatever was created, needs
To be sustaind and fed; of Elements
The grosser feeds the purer, earth the sea,
Earth and the Sea feed Air, the Air those Fires
Ethereal, and as lowest first the Moon;
Whence in her visage round those spots, unpurg'd
Vapours not yet into her substance turnd.
Nor doth the Moon no nourishment exhale
From her moist Continent to higher Orbes.
The Sun that light imparts to all, receives
From all his alimental recompence
In humid exhalations, and at Even
Sups with the Ocean: though in Heav'n the Trees
Of life ambrosial frutage bear, and vines
Yeild Nectar, though from off the boughs each Morn
We brush mellifluous Dewes, and find the ground
Cover'd with pearly grain: yet God hath here
Varied his bounty so with new delights,
As may compare with Heaven; and to taste
Think not I shall be nice. So down they sat,
And to thir viands fell, nor seemingly
The Angel, nor in mist, the common gloss
Of Theologians, but with keen dispatch
Of real hunger, and concoctive heate
To transubstantiate; what redounds, transpires
Through Spirits with ease; nor wonder; if by fire
Of sooty coal the Empiric Alchimist
Can turn, or holds it possible to turn
Metals of drossiest Ore to perfet Gold
As from the Mine. Mean while at Table EVE
Ministerd naked, and thir flowing cups
With pleasant liquors crown'd: O innocence
Deserving Paradise! if ever, then,
Then had the Sons of God excuse to have bin
Enamour'd at that sight; but in those hearts
Love unlibidinous reign'd, nor jealousie
Was understood, the injur'd Lovers Hell.
Thus when with meats & drinks they had suffic'd,
Not burd'nd Nature, sudden mind arose
In ADAM, not to let th' occasion pass
Given him by this great Conference to know
Of things above his World, and of thir being
Who dwell in Heav'n, whose excellence he saw
Transcend his own so farr, whose radiant forms
Divine effulgence, whose high Power so far
Exceeded human, and his wary speech
Thus to th' Empyreal Minister he fram'd.
Inhabitant with God, now know I well
Thy favour, in this honour done to man,
Under whose lowly roof thou hast voutsaf't
To enter, and these earthly fruits to taste,
Food not of Angels, yet accepted so,
As that more willingly thou couldst not seem
At Heav'ns high feasts to have fed: yet what compare?
To whom the winged Hierarch repli'd.
O ADAM, one Almightie is, from whom
All things proceed, and up to him return,
If not deprav'd from good, created all
Such to perfection, one first matter all,
Indu'd with various forms, various degrees
Of substance, and in things that live, of life;
But more refin'd, more spiritous, and pure,
As neerer to him plac't or neerer tending
Each in thir several active Sphears assignd,
Till body up to spirit work, in bounds
Proportiond to each kind. So from the root
Springs lighter the green stalk, from thence the leaves
More aerie, last the bright consummate floure
Spirits odorous breathes: flours and thir fruit
Mans nourishment, by gradual scale sublim'd
To vital Spirits aspire, to animal,
To intellectual, give both life and sense,
Fansie and understanding, whence the soule
Reason receives, and reason is her being,
Discursive, or Intuitive; discourse
Is oftest yours, the latter most is ours,
Differing but in degree, of kind the same.
Wonder not then, what God for you saw good
If I refuse not, but convert, as you,
To proper substance; time may come when men
With Angels may participate, and find
No inconvenient Diet, nor too light Fare:
And from these corporal nutriments perhaps
Your bodies may at last turn all to Spirit
Improv'd by tract of time, and wingd ascend
Ethereal, as wee, or may at choice
Here or in Heav'nly Paradises dwell;
If ye be found obedient, and retain
Unalterably firm his love entire
Whose progenie you are. Mean while enjoy
Your fill what happiness this happie state
Can comprehend, incapable of more.
To whom the Patriarch of mankind repli'd.
O favourable spirit, propitious guest,
Well hast thou taught the way that might direct
Our knowledge, and the scale of Nature set
From center to circumference, whereon
In contemplation of created things
By steps we may ascend to God. But say,
What meant that caution joind, IF YE BE FOUND
OBEDIENT? can wee want obedience then
To him, or possibly his love desert
Who formd us from the dust, and plac'd us here
Full to the utmost measure of what bliss
Human desires can seek or apprehend?
To whom the Angel. Son of Heav'n and Earth,
Attend: That thou art happie, owe to God;
That thou continu'st such, owe to thy self,
That is, to thy obedience; therein stand.
This was that caution giv'n thee; be advis'd.
God made thee perfet, not immutable;
And good he made thee, but to persevere
He left it in thy power, ordaind thy will
By nature free, not over-rul'd by Fate
Inextricable, or strict necessity;
Our voluntarie service he requires,
Not our necessitated, such with him
Findes no acceptance, nor can find, for how
Can hearts, not free, be tri'd whether they serve
Willing or no, who will but what they must
By Destinie, and can no other choose?
My self and all th' Angelic Host that stand
In sight of God enthron'd, our happie state
Hold, as you yours, while our obedience holds;
On other surety none; freely we serve.
Because wee freely love, as in our will
To love or not; in this we stand or fall:
And som are fall'n, to disobedience fall'n,
And so from Heav'n to deepest Hell; O fall
From what high state of bliss into what woe!
To whom our great Progenitor. Thy words
Attentive, and with more delighted eare
Divine instructer, I have heard, then when
Cherubic Songs by night from neighbouring Hills
Aereal Music send: nor knew I not
To be both will and deed created free;
Yet that we never shall forget to love
Our maker, and obey him whose command
Single, is yet so just, my constant thoughts
Assur'd me and still assure: though what thou tellst
Hath past in Heav'n, som doubt within me move,
But more desire to hear, if thou consent,
The full relation, which must needs be strange,
Worthy of Sacred silence to be heard;
And we have yet large day, for scarce the Sun
Hath finisht half his journey, and scarce begins
His other half in the great Zone of Heav'n.
Thus ADAM made request, and RAPHAEL
After short pause assenting, thus began.
High matter thou injoinst me, O prime of men,
Sad task and hard, for how shall I relate
To human sense th' invisible exploits
Of warring Spirits; how without remorse
The ruin of so many glorious once
And perfet while they stood; how last unfould
The secrets of another world, perhaps
Not lawful to reveal? yet for thy good
This is dispenc't, and what surmounts the reach
Of human sense, I shall delineate so,
By lik'ning spiritual to corporal forms,
As may express them best, though what if Earth
Be but the shaddow of Heav'n, and things therein
Each to other like, more then on earth is thought?
As yet this world was not, and CHAOS wilde
Reignd where these Heav'ns now rowl, where Earth now rests
Upon her Center pois'd, when on a day
(For Time, though in Eternitie, appli'd
To motion, measures all things durable
By present, past, and future) on such day
As Heav'ns great Year brings forth, th' Empyreal Host
Of Angels by Imperial summons call'd,
Innumerable before th' Almighties Throne
Forthwith from all the ends of Heav'n appeerd
Under thir Hierarchs in orders bright
Ten thousand thousand Ensignes high advanc'd,
Standards, and Gonfalons twixt Van and Reare
Streame in the Aire, and for distinction serve
Of Hierarchies, of Orders, and Degrees;
Or in thir glittering Tissues bear imblaz'd
Holy Memorials, acts of Zeale and Love
Recorded eminent. Thus when in Orbes
Of circuit inexpressible they stood,
Orb within Orb, the Father infinite,
By whom in bliss imbosom'd sat the Son,
Amidst as from a flaming Mount, whoseop
Brightness had made invisible, thus spake.
Hear all ye Angels, Progenie of Light,
Thrones, Dominations, Princedoms, Vertues, Powers,
Hear my Decree, which unrevok't shall stand.
This day I have begot whom I declare
My onely Son, and on this holy Hill
Him have anointed, whom ye now behold
At my right hand; your Head I him appoint;
And by my Self have sworn to him shall bow
All knees in Heav'n, and shall confess him Lord:
Under his great Vice-gerent Reign abide
United as one individual Soule
For ever happie: him who disobeyes
Mee disobeyes, breaks union, and that day
Cast out from God and blessed vision, falls
Into utter darkness, deep ingulft, his place
Ordaind without redemption, without end.
So spake th' Omnipotent, and with his words
All seemd well pleas'd, all seem'd, but were not all.
That day, as other solem dayes, they spent
In song and dance about the sacred Hill,
Mystical dance, which yonder starrie Spheare
Of Planets and of fixt in all her Wheeles
Resembles nearest, mazes intricate,
Eccentric, intervolv'd, yet regular
Then most, when most irregular they seem:
And in thir motions harmonie Divine
So smooths her charming tones, that Gods own ear
Listens delighted. Eevning approachd
(For we have also our Eevning and our Morn,
We ours for change delectable, not need)
Forthwith from dance to sweet repast they turn
Desirous, all in Circles as they stood,
Tables are set, and on a sudden pil'd
With Angels Food, and rubied Nectar flows:
In Pearl, in Diamond, and massie Gold,
Fruit of delicious Vines, the growth of Heav'n.
They eat, they drink, and with refection sweet
Are fill'd, before th' all bounteous King, who showrd
With copious hand, rejoycing in thir joy.
Now when ambrosial Night with Clouds exhal'd
From that high mount of God, whence light & shade
Spring both, the face of brightest Heav'n had changd
To grateful Twilight (for Night comes not there
In darker veile) and roseat Dews dispos'd
All but the unsleeping eyes of God to rest,
Wide over all the Plain, and wider farr
Then all this globous Earth in Plain outspred,
(Such are the Courts of God) Th' Angelic throng
Disperst in Bands and Files thir Camp extend
By living Streams among the Trees of Life,
Pavilions numberless, and sudden reard,
Celestial Tabernacles, where they slept
Fannd with coole Winds, save those who in thir course
Melodious Hymns about the sovran Throne
Alternate all night long: but not so wak'd
SATAN, so call him now, his former name
Is heard no more Heav'n; he of the first,
If not the first Arch-Angel, great in Power,
In favour and praeeminence, yet fraught
With envie against the Son of God, that day
Honourd by his great Father, and proclaimd
MESSIAH King anointed, could not beare
Through pride that sight, and thought himself impaird.
Deep malice thence conceiving & disdain,
Soon as midnight brought on the duskie houre
Friendliest to sleep and silence, he resolv'd
With all his Legions to dislodge, and leave
Unworshipt, unobey'd the Throne supream
Contemptuous, and his next subordinate
Awak'ning, thus to him in secret spake.
Sleepst thou Companion dear, what sleep can close
Thy eye-lids? and remembrest what Decree
Of yesterday, so late hath past the lips
Of Heav'ns Almightie. Thou to me thy thoughts
Wast wont, I mine to thee was wont to impart;
Both waking we were one; how then can now
Thy sleep dissent? new Laws thou seest impos'd;
New Laws from him who reigns, new minds may raise
In us who serve, new Counsels, to debate
What doubtful may ensue, more in this place
To utter is not safe. Assemble thou
Of all those Myriads which we lead the chief;
Tell them that by command, ere yet dim Night
Her shadowie Cloud withdraws, I am to haste,
And all who under me thir Banners wave,
Homeward with flying march where we possess
The Quarters of the North, there to prepare
Fit entertainment to receive our King
The great MESSIAH, and his new commands,
Who speedily through all the Hierarchies
Intends to pass triumphant, and give Laws.
So spake the false Arch-Angel, and infus'd
Bad influence into th' unwarie brest
Of his Associate; hee together calls,
Or several one by one, the Regent Powers,
Under him Regent, tells, as he was taught,
That the most High commanding, now ere Night,
Now ere dim Night had disincumberd Heav'n,
The great Hierarchal Standard was to move;
Tells the suggested cause, and casts between
Ambiguous words and jealousies, to sound
Or taint integritie; but all obey'd
The wonted signal, and superior voice
Of thir great Potentate; for great indeed
His name, and high was his degree in Heav'n;
His count'nance, as the Morning Starr that guides
The starrie flock, allur'd them, and with lyes
Drew after him the third part of Heav'ns Host:
Mean while th' Eternal eye, whose sight discernes
Abstrusest thoughts, from forth his holy Mount
And from within the golden Lamps that burne
Nightly before him, saw without thir light
Rebellion rising, saw in whom, how spred
Among the sons of Morn, what multitudes
Were banded to oppose his high Decree;
And smiling to his onely Son thus said.
Son, thou in whom my glory I behold
In full resplendence, Heir of all my might,
Neerly it now concernes us to be sure
Of our Omnipotence, and with what Arms
We mean to hold what anciently we claim
Of Deitie or Empire, such a foe
Is rising, who intends to erect his Throne
Equal to ours, throughout the spacious North;
Nor so content, hath in his thought to trie
In battel, what our Power is, or our right.
Let us advise, and to this hazard draw
With speed what force is left, and all imploy
In our defence, lest unawares we lose
This our high place, our Sanctuarie, our Hill.
To whom the Son with calm aspect and cleer
Light'ning Divine, ineffable, serene,
Made answer. Mightie Father, thou thy foes
Justly hast in derision, and secure
Laugh'st at thir vain designes and tumults vain,
Matter to mee of Glory, whom thir hate
Illustrates, when they see all Regal Power
Giv'n me to quell thir pride, and in event
Know whether I be dextrous to subdue
Thy Rebels, or be found the worst in Heav'n.
So spake the Son, but SATAN with his Powers
Farr was advanc't on winged speed, an Host
Innumerable as the Starrs of Night,
Or Starrs of Morning, Dew-drops, which the Sun
Impearls on every leaf and every flouer.
Regions they pass'd, the mightie Regencies
Of Seraphim and Potentates and Thrones
In thir triple Degrees, Regions to which
All thy Dominion, ADAM, is no more
Then what this Garden is to all the Earth,
And all the Sea, from one entire globose
Stretcht into Longitude; which having pass'd
At length into the limits of the North
They came, and SATAN to his Royal seat
High on a Hill, far blazing, as a Mount
Rais'd on a Mount, with Pyramids and Towrs
From Diamond Quarries hew'n, & Rocks of Gold,
The Palace of great LUCIFER, (so call
That Structure in the Dialect of men
Interpreted) which not long after, hee
Affecting all equality with God,
In imitation of that Mount whereon
MESSIAH was declar'd in sight of Heav'n,
The Mountain of the Congregation call'd;
For thither he assembl'd all his Train,
Pretending so commanded to consult
About the great reception of thir King,
Thither to come, and with calumnious Art
Of counterfeted truth thus held thir ears.
Thrones, Dominations, Princedomes, Vertues, Powers,
If these magnific Titles yet remain
Not meerly titular, since by Decree
Another now hath to himself ingross't
All Power, and us eclipst under the name
Of King anointed, for whom all this haste
Of midnight march, and hurried meeting here,
This onely to consult how we may best
With what may be devis'd of honours new
Receive him coming to receive from us
Knee-tribute yet unpaid, prostration vile,
Too much to one, but double how endur'd,
To one and to his image now proclaim'd?
But what if better counsels might erect
Our minds and teach us to cast off this Yoke?
Will ye submit your necks, and chuse to bend
The supple knee? ye will not, if I trust
To know ye right, or if ye know your selves
Natives and Sons of Heav'n possest before
By none, and if not equal all, yet free,
Equally free; for Orders and Degrees
Jarr not with liberty, but well consist.
Who can in reason then or right assume
Monarchie over such as live by right
His equals, if in power and splendor less,
In freedome equal? or can introduce
Law and Edict on us, who without law
Erre not, much less for this to be our Lord,
And look for adoration to th' abuse
Of those Imperial Titles which assert
Our being ordain'd to govern, not to serve?
Thus farr his bold discourse without controule
Had audience, when among the Seraphim
ABDIEL, then whom none with more zeale ador'd
The Deitie, and divine commands obei'd,
Stood up, and in a flame of zeale severe
The current of his fury thus oppos'd.
O argument blasphemous, false and proud!
Words which no eare ever to hear in Heav'n
Expected, least of all from thee, ingrate
In place thy self so high above thy Peeres.
Canst thou with impious obloquie condemne
The just Decree of God, pronounc't and sworn,
That to his only Son by right endu'd
With Regal Scepter, every Soule in Heav'n
Shall bend the knee, and in that honour due
Confess him rightful King? unjust thou saist
Flatly unjust, to binde with Laws the free,
And equal over equals to let Reigne,
One over all with unsucceeded power.
Shalt thou give Law to God, shalt thou dispute
With him the points of libertie, who made
Thee what thou art, & formd the Pow'rs of Heav'n
Such as he pleasd, and circumscrib'd thir being?
Yet by experience taught we know how good,
And of our good, and of our dignitie
How provident he is, how farr from thought
To make us less, bent rather to exalt
Our happie state under one Head more neer
United. But to grant it thee unjust,
That equal over equals Monarch Reigne:
Thy self though great & glorious dost thou count,
Or all Angelic Nature joind in one,
Equal to him begotten Son, by whom
As by his Word the mighty Father made
All things, ev'n thee, and all the Spirits of Heav'n
By him created in thir bright degrees,
Crownd them with Glory, & to thir Glory nam'd
Thrones, Dominations, Princedoms, Vertues, Powers
Essential Powers, nor by his Reign obscur'd,
But more illustrious made, since he the Head
One of our number thus reduc't becomes,
His Laws our Laws, all honour to him done
Returns our own. Cease then this impious rage,
And tempt not these; but hast'n to appease
Th' incensed Father, and th' incensed Son,
While Pardon may be found in time besought.
So spake the fervent Angel, but his zeale
None seconded, as out of season judg'd,
Or singular and rash, whereat rejoic'd
Th' Apostat, and more haughty thus repli'd.
That we were formd then saist thou? & the work
Of secondarie hands, by task transferd
From Father to his Son? strange point and new!
Doctrin which we would know whence learnt: who saw
When this creation was? rememberst thou
Thy making, while the Maker gave thee being?
We know no time when we were not as now;
Know none before us, self-begot, self-rais'd
By our own quick'ning power, when fatal course
Had circl'd his full Orbe, the birth mature
Of this our native Heav'n, Ethereal Sons.
Our puissance is our own, our own right hand
Shall teach us highest deeds, by proof to try
Who is our equal: then thou shalt behold
Whether by supplication we intend
Address, and to begirt th' Almighty Throne
Beseeching or besieging. This report,
These tidings carrie to th' anointed King;
And fly, ere evil intercept thy flight.
He said, and as the sound of waters deep
Hoarce murmur echo'd to his words applause
Through the infinite Host, nor less for that
The flaming Seraph fearless, though alone
Encompass'd round with foes, thus answerd bold.
O alienate from God, O spirit accurst,
Forsak'n of all good; I see thy fall
Determind, and thy hapless crew involv'd
In this perfidious fraud, contagion spred
Both of thy crime and punishment: henceforth
No more be troubl'd how to quit the yoke
Of Gods MESSIAH; those indulgent Laws
Will not be now voutsaf't, other Decrees
Against thee are gon forth without recall;
That Golden Scepter which thou didst reject
Is now an Iron Rod to bruise and breake
Thy disobedience. Well thou didst advise,
Yet not for thy advise or threats I fly
These wicked Tents devoted, least the wrauth
Impendent, raging into sudden flame
Distinguish not: for soon expect to feel
His Thunder on thy head, devouring fire.
Then who created thee lamenting learne,
When who can uncreate thee thou shalt know.
So spake the Seraph ABDIEL faithful found,
Among the faithless, faithful only hee;
Among innumerable false, unmov'd,
Unshak'n, unseduc'd, unterrifi'd
His Loyaltie he kept, his Love, his Zeale;
Nor number, nor example with him wrought
To swerve from truth, or change his constant mind
Though single. From amidst them forth he passd,
Long way through hostile scorn, which he susteind
Superior, nor of violence fear'd aught;
And with retorted scorn his back he turn'd
On those proud Towrs to swift destruction doom'd.
THE END OF THE FIFTH BOOK.
PARADISE LOST
BOOK VI.
All night the dreadless Angel unpursu'd
Through Heav'ns wide Champain held his way, till Morn,
Wak't by the circling Hours, with rosie hand
Unbarr'd the gates of Light. There is a Cave
Within the Mount of God, fast by his Throne,
Where light and darkness in perpetual round
Lodge and dislodge by turns, which makes through Heav'n
Grateful vicissitude, like Day and Night;
Light issues forth, and at the other dore
Obsequious darkness enters, till her houre
To veile the Heav'n, though darkness there might well
Seem twilight here; and now went forth the Morn
Such as in highest Heav'n, arrayd in Gold
Empyreal, from before her vanisht Night,
Shot through with orient Beams: when all the Plain
Coverd with thick embatteld Squadrons bright,
Chariots and flaming Armes, and fierie Steeds
Reflecting blaze on blaze, first met his view:
Warr he perceav'd, warr in procinct, and found
Already known what he for news had thought
To have reported: gladly then he mixt
Among those friendly Powers who him receav'd
With joy and acclamations loud, that one
That of so many Myriads fall'n, yet one
Returnd not lost: On to the sacred hill
They led him high applauded, and present
Before the seat supream; from whence a voice
From midst a Golden Cloud thus milde was heard.
Servant of God, well done, well hast thou fought
The better fight, who single hast maintaind
Against revolted multitudes the Cause
Of Truth, in word mightier then they in Armes;
And for the testimonie of Truth hast born
Universal reproach, far worse to beare
Then violence: for this was all thy care
To stand approv'd in sight of God, though Worlds
Judg'd thee perverse: the easier conquest now
Remains thee, aided by this host of friends,
Back on thy foes more glorious to return
Then scornd thou didst depart, and to subdue
By force, who reason for thir Law refuse,
Right reason for thir Law, and for thir King
MESSIAH, who by right of merit Reigns.
Goe MICHAEL of Celestial Armies Prince,
And thou in Military prowess next
GABRIEL, lead forth to Battel these my Sons
Invincible, lead forth my armed Saints
By Thousands and by Millions rang'd for fight;
Equal in number to that Godless crew
Rebellious, them with Fire and hostile Arms
Fearless assault, and to the brow of Heav'n
Pursuing drive them out from God and bliss,
Into thir place of punishment, the Gulf
Of TARTARUS, which ready opens wide
His fiery CHAOS to receave thir fall.
So spake the Sovran voice, and Clouds began
To darken all the Hill, and smoak to rowl
In duskie wreathes, reluctant flames, the signe
Of wrauth awak't: nor with less dread the loud
Ethereal Trumpet from on high gan blow:
At which command the Powers Militant,
That stood for Heav'n, in mighty Quadrate joyn'd
Of Union irresistible, mov'd on
In silence thir bright Legions, to the sound
Of instrumental Harmonie that breath'd
Heroic Ardor to advent'rous deeds
Under thir God-like Leaders, in the Cause
Of God and his MESSIAH. On they move
Indissolubly firm; nor obvious Hill,
Nor streit'ning Vale, nor Wood, nor Stream divides
Thir perfet ranks; for high above the ground
Thir march was, and the passive Air upbore
Thir nimble tread; as when the total kind
Of Birds in orderly array on wing
Came summond over EDEN to receive
Thir names of thee; so over many a tract
Of Heav'n they march'd, and many a Province wide
Tenfold the length of this terrene: at last
Farr in th' Horizon to the North appeer'd
From skirt to skirt a fierie Region, stretcht
In battailous aspect, and neerer view
Bristl'd with upright beams innumerable
Of rigid Spears, and Helmets throng'd, and Shields
Various, with boastful Argument portraid,
The banded Powers of SATAN hasting on
With furious expedition; for they weend
That self same day by fight, or by surprize
To win the Mount of God, and on his Throne
To set the envier of his State, the proud
Aspirer, but thir thoughts prov'd fond and vain
In the mid way: though strange to us it seemd
At first, that Angel should with Angel warr,
And in fierce hosting meet, who wont to meet
So oft in Festivals of joy and love
Unanimous, as sons of one great Sire
Hymning th' Eternal Father: but the shout
Of Battel now began, and rushing sound
Of onset ended soon each milder thought.
High in the midst exalted as a God
Th' Apostat in his Sun-bright Chariot sate
Idol of Majestie Divine, enclos'd
With Flaming Cherubim, and golden Shields;
Then lighted from his gorgeous Throne, for now
'Twixt Host and Host but narrow space was left,
A dreadful interval, and Front to Front
Presented stood in terrible array
Of hideous length: before the cloudie Van,
On the rough edge of battel ere it joyn'd,
SATAN with vast and haughtie strides advanc't,
Came towring, armd in Adamant and Gold;
ABDIEL that sight endur'd not, where he stood
Among the mightiest, bent on highest deeds,
And thus his own undaunted heart explores.
O Heav'n! that such resemblance of the Highest
Should yet remain, where faith and realtie
Remain not; wherfore should not strength & might
There fail where Vertue fails, or weakest prove
Where boldest; though to sight unconquerable?
His puissance, trusting in th' Almightie's aide,
I mean to try, whose Reason I have tri'd
Unsound and false; nor is it aught but just,
That he who in debate of Truth hath won,
Should win in Arms, in both disputes alike
Victor; though brutish that contest and foule,
When Reason hath to deal with force, yet so
Most reason is that Reason overcome.
So pondering, and from his armed Peers
Forth stepping opposite, half way he met
His daring foe, at this prevention more
Incens't, and thus securely him defi'd.
Proud, art thou met? thy hope was to have reacht
The highth of thy aspiring unoppos'd,
The Throne of God unguarded, and his side
Abandond at the terror of thy Power
Or potent tongue; fool, not to think how vain
Against th' Omnipotent to rise in Arms;
Who out of smallest things could without end
Have rais'd incessant Armies to defeat
Thy folly; or with solitarie hand
Reaching beyond all limit, at one blow
Unaided could have finisht thee, and whelmd
Thy Legions under darkness; but thou seest
All are not of thy Train; there be who Faith
Prefer, and Pietie to God, though then
To thee not visible, when I alone
Seemd in thy World erroneous to dissent
From all: my Sect thou seest, now learn too late
How few somtimes may know, when thousands err.
Whom the grand foe with scornful eye askance
Thus answerd. Ill for thee, but in wisht houre
Of my revenge, first sought for thou returnst
From flight, seditious Angel, to receave
Thy merited reward, the first assay
Of this right hand provok't, since first that tongue
Inspir'd with contradiction durst oppose
A third part of the Gods, in Synod met
Thir Deities to assert, who while they feel
Vigour Divine within them, can allow
Omnipotence to none. But well thou comst
Before thy fellows, ambitious to win
From me som Plume, that thy success may show
Destruction to the rest: this pause between
(Unanswerd least thou boast) to let thee know;
At first I thought that Libertie and Heav'n
To heav'nly Soules had bin all one; but now
I see that most through sloth had rather serve,
Ministring Spirits, traind up in Feast and Song;
Such hast thou arm'd, the Minstrelsie of Heav'n,
Servilitie with freedom to contend,
As both thir deeds compar'd this day shall prove.
To whom in brief thus ABDIEL stern repli'd.
Apostat, still thou errst, nor end wilt find
Of erring, from the path of truth remote:
Unjustly thou deprav'st it with the name
Of SERVITUDE to serve whom God ordains,
Or Nature; God and Nature bid the same,
When he who rules is worthiest, and excells
Them whom he governs. This is servitude,
To serve th' unwise, or him who hath rebelld
Against his worthier, as thine now serve thee,
Thy self not free, but to thy self enthrall'd;
Yet leudly dar'st our ministring upbraid.
Reign thou in Hell thy Kingdom, let mee serve
In Heav'n God ever blessed, and his Divine
Behests obey, worthiest to be obey'd,
Yet Chains in Hell, not Realms expect: mean while
From mee returnd, as erst thou saidst, from flight,
This greeting on thy impious Crest receive.
So saying, a noble stroke he lifted high,
Which hung not, but so swift with tempest fell
On the proud Crest of SATAN, that no sight,
Nor motion of swift thought, less could his Shield
Such ruin intercept: ten paces huge
He back recoild; the tenth on bended knee
His massie Spear upstaid; as if on Earth
Winds under ground or waters forcing way
Sidelong, had push't a Mountain from his seat
Half sunk with all his Pines. Amazement seis'd
The Rebel Thrones, but greater rage to see
Thus foil'd thir mightiest, ours joy filld, and shout,
Presage of Victorie and fierce desire
Of Battel: whereat MICHAEL bid sound
Th' Arch-Angel trumpet; through the vast of Heav'n
It sounded, and the faithful Armies rung
HOSANNA to the Highest: nor stood at gaze
The adverse Legions, nor less hideous joyn'd
The horrid shock: now storming furie rose,
And clamour such as heard in Heav'n till now
Was never, Arms on Armour clashing bray'd
Horrible discord, and the madding Wheeles
Of brazen Chariots rag'd; dire was the noise
Of conflict; over head the dismal hiss
Of fiery Darts in flaming volies flew,
And flying vaulted either Host with fire.
Sounder fierie Cope together rush'd
Both Battels maine, with ruinous assault
And inextinguishable rage; all Heav'n
Resounded, and had Earth bin then, all Earth
Had to her Center shook. What wonder? when
Millions of fierce encountring Angels fought
On either side, the least of whom could weild
These Elements, and arm him with the force
Of all thir Regions: how much more of Power
Armie against Armie numberless to raise
Dreadful combustion warring, and disturb,
Though not destroy, thir happie Native seat;
Had not th' Eternal King Omnipotent
From his strong hold of Heav'n high over-rul'd
And limited thir might; though numberd such
As each divided Legion might have seemd
A numerous Host, in strength each armed hand
A Legion; led in fight, yet Leader seemd
Each Warriour single as in Chief, expert
When to advance, or stand, or turn the sway
Of Battel, open when, and when to close
The ridges of grim Warr; no thought of flight,
None of retreat, no unbecoming deed
That argu'd fear; each on himself reli'd,
As onely in his arm the moment lay
Of victorie; deeds of eternal fame
Were don, but infinite: for wide was spred
That Warr and various; somtimes on firm ground
A standing fight, then soaring on main wing
Tormented all the Air; all Air seemd then
Conflicting Fire: long time in eeven scale
The Battel hung; till SATAN, who that day
Prodigious power had shewn, and met in Armes
No equal, raunging through the dire attack
Of fighting Seraphim confus'd, at length
Saw where the Sword of MICHAEL smote, and fell'd
Squadrons at once, with huge two-handed sway
Brandisht aloft the horrid edge came down
Wide wasting; such destruction to withstand
He hasted, and oppos'd the rockie Orb
Of tenfold Adamant, his ample Shield
A vast circumference: At his approach
The great Arch-Angel from his warlike toile
Surceas'd, and glad as hoping here to end
Intestine War in Heav'n, the arch foe subdu'd
Or Captive drag'd in Chains, with hostile frown
And visage all enflam'd first thus began.
Author of evil, unknown till thy revolt,
Unnam'd in Heav'n, now plenteous, as thou seest
These Acts of hateful strife, hateful to all,
Though heaviest by just measure on thy self
And thy adherents: how hast thou disturb'd
Heav'ns blessed peace, and into Nature brought
Miserie, uncreated till the crime
Of thy Rebellion? how hast thou instill'd
Thy malice into thousands, once upright
And faithful, now prov'd false. But think not here
To trouble Holy Rest; Heav'n casts thee out
From all her Confines. Heav'n the seat of bliss
Brooks not the works of violence and Warr.
Hence then, and evil go with thee along
Thy ofspring, to the place of evil, Hell,
Thou and thy wicked crew; there mingle broiles,
Ere this avenging Sword begin thy doome,
Or som more sudden vengeance wing'd from God
Precipitate thee with augmented paine.
So spake the Prince of Angels; to whom thus
The Adversarie. Nor think thou with wind
Of airie threats to aw whom yet with deeds
Thou canst not. Hast thou turnd the least of these
To flight, or if to fall, but that they rise
Unvanquisht, easier to transact with mee
That thou shouldst hope, imperious, & with threats
To chase me hence? erre not that so shall end
The strife which thou call'st evil, but wee style
The strife of Glorie: which we mean to win,
Or turn this Heav'n it self into the Hell
Thou fablest, here however to dwell free,
If not to reign: mean while thy utmost force,
And join him nam'd ALMIGHTIE to thy aid,
I flie not, but have sought thee farr and nigh.
They ended parle, and both addrest for fight
Unspeakable; for who, though with the tongue
Of Angels, can relate, or to what things
Liken on Earth conspicuous, that may lift
Human imagination to such highth
Of Godlike Power: for likest Gods they seemd,
Stood they or mov'd, in stature, motion, arms
Fit to decide the Empire of great Heav'n.
Now wav'd thir fierie Swords, and in the Aire
Made horrid Circles; two broad Suns thir Shields
Blaz'd opposite, while expectation stood
In horror; from each hand with speed retir'd
Where erst was thickest fight, th' Angelic throng,
And left large field, unsafe within the wind
Of such commotion, such as to set forth
Great things by small, If Natures concord broke,
Among the Constellations warr were sprung,
Two Planets rushing from aspect maligne
Of fiercest opposition in mid Skie,
Should combat, and thir jarring Sphears confound.
Together both with next to Almightie Arme,
Uplifted imminent one stroke they aim'd
That might determine, and not need repeate,
As not of power, at once; nor odds appeerd
In might or swift prevention; but the sword
Of MICHAEL from the Armorie of God
Was giv'n him temperd so, that neither keen
Nor solid might resist that edge: it met
The sword of SATAN with steep force to smite
Descending, and in half cut sheere, nor staid,
But with swift wheele reverse, deep entring shar'd
All his right side; then SATAN first knew pain,
And writh'd him to and fro convolv'd; so sore
The griding sword with discontinuous wound
Pass'd through him, but th' Ethereal substance clos'd
Not long divisible, and from the gash
A stream of Nectarous humor issuing flow'd
Sanguin, such as Celestial Spirits may bleed,
And all his Armour staind ere while so bright.
Forthwith on all sides to his aide was run
By Angels many and strong, who interpos'd
Defence, while others bore him on thir Shields
Back to his Chariot; where it stood retir'd
From off the files of warr; there they him laid
Gnashing for anguish and despite and shame
To find himself not matchless, and his pride
Humbl'd by such rebuke, so farr beneath
His confidence to equal God in power.
Yet soon he heal'd; for Spirits that live throughout
Vital in every part, not as frail man
In Entrailes, Heart or Head, Liver or Reines,
Cannot but by annihilating die;
Nor in thir liquid texture mortal wound
Receive, no more then can the fluid Aire:
All Heart they live, all Head, all Eye, all Eare,
All Intellect, all Sense, and as they please,
They Limb themselves, and colour, shape or size
Assume, as likes them best, condense or rare.
Mean while in other parts like deeds deservd
Memorial, where the might of GABRIEL fought,
And with fierce Ensignes pierc'd the deep array
Of MOLOC furious King, who him defi'd,
And at his Chariot wheeles to drag him bound
Threatn'd, nor from the Holie One of Heav'n
Refrein'd his tongue blasphemous; but anon
Down clov'n to the waste, with shatterd Armes
And uncouth paine fled bellowing. On each wing
URIEL and RAPHAEL his vaunting foe,
Though huge, and in a Rock of Diamond Armd,
Vanquish'd ADRAMELEC, and ASMADAI,
Two potent Thrones, that to be less then Gods
Disdain'd, but meaner thoughts learnd in thir flight,
Mangl'd with gastly wounds through Plate and Maile.
Nor stood unmindful ABDIEL to annoy
The Atheist crew, but with redoubl'd blow
ARIEL and ARIOC, and the violence
Of RAMIEL scorcht and blasted overthrew.
I might relate of thousands, and thir names
Eternize here on Earth; but those elect
Angels contented with thir fame in Heav'n
Seek not the praise of men: the other sort
In might though wondrous and in Acts of Warr,
Nor of Renown less eager, yet by doome
Canceld from Heav'n and sacred memorie,
Nameless in dark oblivion let them dwell.
For strength from Truth divided and from Just,
Illaudable, naught merits but dispraise
And ignominie, yet to glorie aspires
Vain glorious, and through infamie seeks fame:
Therfore Eternal silence be thir doome.
And now thir mightiest quelld, the battel swerv'd,
With many an inrode gor'd; deformed rout
Enter'd, and foul disorder; all the ground
With shiverd armour strow'n, and on a heap
Chariot and Charioter lay overturnd
And fierie foaming Steeds; what stood, recoyld
Orewearied, through the faint Satanic Host
Defensive scarse, or with pale fear surpris'd,
Then first with fear surpris'd and sense of paine
Fled ignominious, to such evil brought
By sinne of disobedience, till that hour
Not liable to fear or flight or paine.
Far otherwise th' inviolable Saints
In Cubic Phalanx firm advanc't entire,
Invulnerable, impenitrably arm'd:
Such high advantages thir innocence
Gave them above thir foes, not to have sinnd,
Not to have disobei'd; in fight they stood
Unwearied, unobnoxious to be pain'd
By wound, though from thir place by violence mov'd.
Now Night her course began, and over Heav'n
Inducing darkness, grateful truce impos'd,
And silence on the odious dinn of Warr:
Under her Cloudie covert both retir'd,
Victor and Vanquisht: on the foughten field
MICHAEL and his Angels prevalent
Encamping, plac'd in Guard thir Watches round,
Cherubic waving fires: on th' other part
SATAN with his rebellious disappeerd,
Far in the dark dislodg'd, and void of rest,
His Potentates to Councel call'd by night;
And in the midst thus undismai'd began.
O now in danger tri'd, now known in Armes
Not to be overpowerd, Companions deare,
Found worthy not of Libertie alone,
Too mean pretense, but what we more affect,
Honour, Dominion, Glorie, and renowne,
Who have sustaind one day in doubtful fight,
(And if one day, why not Eternal dayes?)
What Heavens Lord had powerfullest to send
Against us from about his Throne, and judg'd
Sufficient to subdue us to his will,
But proves not so: then fallible, it seems,
Of future we may deem him, though till now
Omniscient thought. True is, less firmly arm'd,
Some disadvantage we endur'd and paine,
Till now not known, but known as soon contemnd,
Since now we find this our Empyreal forme
Incapable of mortal injurie
Imperishable, and though peirc'd with wound,
Soon closing, and by native vigour heal'd.
Of evil then so small as easie think
The remedie; perhaps more valid Armes,
Weapons more violent, when next we meet,
May serve to better us, and worse our foes,
Or equal what between us made the odds,
In Nature none: if other hidden cause
Left them Superiour, while we can preserve
Unhurt our mindes, and understanding sound,
Due search and consultation will disclose.
He sat; and in th' assembly next upstood
NISROC, of Principalities the prime;
As one he stood escap't from cruel fight,
Sore toild, his riv'n Armes to havoc hewn,
And cloudie in aspect thus answering spake.
Deliverer from new Lords, leader to free
Enjoyment of our right as Gods; yet hard
For Gods, and too unequal work we find
Against unequal armes to fight in paine,
Against unpaind, impassive; from which evil
Ruin must needs ensue; for what availes
Valour or strength, though matchless, quelld with pain
Which all subdues, and makes remiss the hands
Of Mightiest. Sense of pleasure we may well
Spare out of life perhaps, and not repine,
But live content, which is the calmest life:
But pain is perfet miserie, the worst
Of evils, and excessive, overturnes
All patience. He who therefore can invent
With what more forcible we may offend
Our yet unwounded Enemies, or arme
Our selves with like defence, to mee deserves
No less then for deliverance what we owe.
Whereto with look compos'd SATAN repli'd.
Not uninvented that, which thou aright
Beleivst so main to our success, I bring;
Which of us who beholds the bright surface
Of this Ethereous mould whereon we stand,
This continent of spacious Heav'n, adornd
With Plant, Fruit, Flour Ambrosial, Gemms & Gold,
Whose Eye so superficially surveyes
These things, as not to mind from whence they grow
Deep under ground, materials dark and crude,
Of spiritous and fierie spume, till toucht
With Heav'ns ray, and temperd they shoot forth
So beauteous, op'ning to the ambient light.
These in thir dark Nativitie the Deep
Shall yeild us, pregnant with infernal flame,
Which into hallow Engins long and round
Thick-rammd, at th' other bore with touch of fire
Dilated and infuriate shall send forth
From far with thundring noise among our foes
Such implements of mischief as shall dash
To pieces, and orewhelm whatever stands
Adverse, that they shall fear we have disarmd
The Thunderer of his only dreaded bolt.
Nor long shall be our labour, yet ere dawne,
Effect shall end our wish. Mean while revive;
Abandon fear; to strength and counsel joind
Think nothing hard, much less to be despaird.
He ended, and his words thir drooping chere
Enlightn'd, and thir languisht hope reviv'd.
Th' invention all admir'd, and each, how hee
To be th' inventer miss'd, so easie it seemd
Once found, which yet unfound most would have thought
Impossible: yet haply of thy Race
In future dayes, if Malice should abound,
Some one intent on mischief, or inspir'd
With dev'lish machination might devise
Like instrument to plague the Sons of men
For sin, on warr and mutual slaughter bent.
Forthwith from Councel to the work they flew,
None arguing stood, innumerable hands
Were ready, in a moment up they turnd
Wide the Celestial soile, and saw beneath
Th' originals of Nature in thir crude
Conception; Sulphurous and Nitrous Foame
They found, they mingl'd, and with suttle Art,
Concocted and adusted they reduc'd
To blackest grain, and into store conveyd:
Part hidd'n veins diggd up (nor hath this Earth
Entrails unlike) of Mineral and Stone,
Whereof to found thir Engins and thir Balls
Of missive ruin; part incentive reed
Provide, pernicious with one touch to fire.
So all ere day spring, under conscious Night
Secret they finish'd, and in order set,
With silent circumspection unespi'd.
Now when fair Morn Orient in Heav'n appeerd
Up rose the Victor Angels, and to Arms
The matin Trumpet Sung: in Arms they stood
Of Golden Panoplie, refulgent Host,
Soon banded; others from the dawning Hills
Lookd round, and Scouts each Coast light-armed scoure,
Each quarter, to descrie the distant foe,
Where lodg'd, or whither fled, or if for fight,
In motion or in alt: him soon they met
Under spred Ensignes moving nigh, in slow
But firm Battalion; back with speediest Sail
ZEPHIEL, of Cherubim the swiftest wing,
Came flying, and in mid Aire aloud thus cri'd.
Arme, Warriours, Arme for fight, the foe at hand,
Whom fled we thought, will save us long pursuit
This day, fear not his flight; so thick a Cloud
He comes, and settl'd in his face I see
Sad resolution and secure: let each
His Adamantine coat gird well, and each
Fit well his Helme, gripe fast his orbed Shield,
Born eevn or high, for this day will pour down,
If I conjecture aught, no drizling showr,
But ratling storm of Arrows barbd with fire.
So warnd he them aware themselves, and soon
In order, quit of all impediment;
Instant without disturb they took Allarm,
And onward move Embattelld; when behold
Not distant far with heavie pace the Foe
Approaching gross and huge; in hollow Cube
Training his devilish Enginrie, impal'd
On every side with shaddowing Squadrons Deep,
To hide the fraud. At interview both stood
A while, but suddenly at head appeerd
SATAN: And thus was heard Commanding loud.
Vangard, to Right and Left the Front unfould;
That all may see who hate us, how we seek
Peace and composure, and with open brest
Stand readie to receive them, if they like
Our overture, and turn not back perverse;
But that I doubt, however witness Heaven,
Heav'n witness thou anon, while we discharge
Freely our part: yee who appointed stand
Do as you have in charge, and briefly touch
What we propound, and loud that all may hear.
So scoffing in ambiguous words, he scarce
Had ended; when to Right and Left the Front
Divided, and to either Flank retir'd.
Which to our eyes discoverd new and strange,
A triple-mounted row of Pillars laid
On Wheels (for like to Pillars most they seem'd
Or hollow'd bodies made of Oak or Firr
With branches lopt, in Wood or Mountain fell'd)
Brass, Iron, Stonie mould, had not thir mouthes
With hideous orifice gap't on us wide,
Portending hollow truce; at each behind
A Seraph stood, and in his hand a Reed
Stood waving tipt with fire; while we suspense,
Collected stood within our thoughts amus'd,
Not long, for sudden all at once thir Reeds
Put forth, and to a narrow vent appli'd
With nicest touch. Immediate in a flame,
But soon obscur'd with smoak, all Heav'n appeerd,
From those deep-throated Engins belcht, whose roar
Emboweld with outragious noise the Air,
And all her entrails tore, disgorging foule
Thir devillish glut, chaind Thunderbolts and Hail
Of Iron Globes, which on the Victor Host
Level'd, with such impetuous furie smote,
That whom they hit, none on thir feet might stand,
Though standing else as Rocks, but down they fell
By thousands, Angel on Arch-Angel rowl'd;
The sooner for thir Arms, unarm'd they might
Have easily as Spirits evaded swift
By quick contraction or remove; but now
Foule dissipation follow'd and forc't rout;
Nor serv'd it to relax thir serried files.
What should they do? if on they rusht, repulse
Repeated, and indecent overthrow
Doubl'd, would render them yet more despis'd,
And to thir foes a laughter; for in view
Stood rankt of Seraphim another row
In posture to displode thir second tire
Of Thunder: back defeated to return
They worse abhorr'd. SATAN beheld thir plight,
And to his Mates thus in derision call'd.
O Friends, why come not on these Victors proud?
Ere while they fierce were coming, and when wee,
To entertain them fair with open Front
And Brest, (what could we more?) propounded terms
Of composition, strait they chang'd thir minds,
Flew off, and into strange vagaries fell,
As they would dance, yet for a dance they seemd
Somwhat extravagant and wilde, perhaps
For joy of offerd peace: but I suppose
If our proposals once again were heard
We should compel them to a quick result.
To whom thus BELIAL in like gamesom mood.
Leader, the terms we sent were terms of weight,
Of hard contents, and full of force urg'd home,
Such as we might perceive amus'd them all,
And stumbl'd many, who receives them right,
Had need from head to foot well understand;
Not understood, this gift they have besides,
They shew us when our foes walk not upright.
So they among themselves in pleasant veine
Stood scoffing, highthn'd in thir thoughts beyond
All doubt of Victorie, eternal might
To match with thir inventions they presum'd
So easie, and of his Thunder made a scorn,
And all his Host derided, while they stood
A while in trouble; but they stood not long,
Rage prompted them at length, & found them arms
Against such hellish mischief fit to oppose.
Forthwith (behold the excellence, the power
Which God hath in his mighty Angels plac'd)
Thir Arms away they threw, and to the Hills
(For Earth hath this variety from Heav'n
Of pleasure situate in Hill and Dale)
Light as the Lightning glimps they ran, they flew,
From thir foundations loosning to and fro
They pluckt the seated Hills with all thir load,
Rocks, Waters, Woods, and by the shaggie tops
Up lifting bore them in thir hands: Amaze,
Be sure, and terrour seis'd the rebel Host,
When coming towards them so dread they saw
The bottom of the Mountains upward turn'd,
Till on those cursed Engins triple-row
They saw them whelmd, and all thir confidence
Under the weight of Mountains buried deep,
Themselves invaded next, and on thir heads
Main Promontories flung, which in the Air
Came shadowing, and opprest whole Legions arm'd,
Thir armor help'd thir harm, crush't in and brus'd
Into thir substance pent, which wrought them pain
Implacable, and many a dolorous groan,
Long strugling underneath, ere they could wind
Out of such prison, though Spirits of purest light,
Purest at first, now gross by sinning grown.
The rest in imitation to like Armes
Betook them, and the neighbouring Hills uptore;
So Hills amid the Air encounterd Hills
Hurl'd to and fro with jaculation dire,
That under ground they fought in dismal shade;
Infernal noise; Warr seem'd a civil Game
To this uproar; horrid confusion heapt
Upon confusion rose: and now all Heav'n
Had gone to wrack, with ruin overspred,
Had not th' Almightie Father where he sits
Shrin'd in his Sanctuarie of Heav'n secure,
Consulting on the sum of things, foreseen
This tumult, and permitted all, advis'd:
That his great purpose he might so fulfill,
To honour his Anointed Son aveng'd
Upon his enemies, and to declare
All power on him transferr'd: whence to his Son
Th' Assessor of his Throne he thus began.
Effulgence of my Glorie, Son belov'd,
Son in whose face invisible is beheld
Visibly, what by Deitie I am,
And in whose hand what by Decree I doe,
Second Omnipotence, two dayes are past,
Two dayes, as we compute the dayes of Heav'n,
Since MICHAEL and his Powers went forth to tame
These disobedient; sore hath been thir fight,
As likeliest was, when two such Foes met arm'd;
For to themselves I left them, and thou knowst,
Equal in their Creation they were form'd,
Save what sin hath impaird, which yet hath wrought
Insensibly, for I suspend thir doom;
Whence in perpetual fight they needs must last
Endless, and no solution will be found:
Warr wearied hath perform'd what Warr can do,
And to disorder'd rage let loose the reines,
With Mountains as with Weapons arm'd, which makes
Wild work in Heav'n, and dangerous to the maine.
Two dayes are therefore past, the third is thine;
For thee I have ordain'd it, and thus farr
Have sufferd, that the Glorie may be thine
Of ending this great Warr, since none but Thou
Can end it. Into thee such Vertue and Grace
Immense I have transfus'd, that all may know
In Heav'n and Hell thy Power above compare,
And this perverse Commotion governd thus,
To manifest thee worthiest to be Heir
Of all things, to be Heir and to be King
By Sacred Unction, thy deserved right.
Go then thou Mightiest in thy Fathers might,
Ascend my Chariot, guide the rapid Wheeles
That shake Heav'ns basis, bring forth all my Warr,
My Bow and Thunder, my Almightie Arms
Gird on, and Sword upon thy puissant Thigh;
Pursue these sons of Darkness, drive them out
From all Heav'ns bounds into the utter Deep:
There let them learn, as likes them, to despise
God and MESSIAH his anointed King.
He said, and on his Son with Rayes direct
Shon full, he all his Father full exprest
Ineffably into his face receiv'd,
And thus the filial Godhead answering spake.
O Father, O Supream of heav'nly Thrones,
First, Highest, Holiest, Best, thou alwayes seekst
To glorifie thy Son, I alwayes thee,
As is most just; this I my Glorie account,
My exaltation, and my whole delight,
That thou in me well pleas'd, declarst thy will
Fulfill'd, which to fulfil is all my bliss.
Scepter and Power, thy giving, I assume,
And gladlier shall resign, when in the end
Thou shalt be All in All, and I in thee
For ever, and in mee all whom thou lov'st:
But whom thou hat'st, I hate, and can put on
Thy terrors, as I put thy mildness on,
Image of thee in all things; and shall soon,
Armd with thy might, rid heav'n of these rebell'd,
To thir prepar'd ill Mansion driven down
To chains of Darkness, and th' undying Worm,
That from thy just obedience could revolt,
Whom to obey is happiness entire.
Then shall thy Saints unmixt, and from th' impure
Farr separate, circling thy holy Mount
Unfained HALLELUIAHS to thee sing,
Hymns of high praise, and I among them chief.
So said, he o're his Scepter bowing, rose
From the right hand of Glorie where he sate,
And the third sacred Morn began to shine
Dawning through Heav'n: forth rush'd with whirlwind sound
The Chariot of Paternal Deitie,
Flashing thick flames, Wheele within Wheele undrawn,
It self instinct with Spirit, but convoyd
By four Cherubic shapes, four Faces each
Had wondrous, as with Starrs thir bodies all
And Wings were set with Eyes, with Eyes the Wheels
Of Beril, and careering Fires between;
Over thir heads a chrystal Firmament,
Whereon a Saphir Throne, inlaid with pure
Amber, and colours of the showrie Arch.
Hee in Celestial Panoplie all armd
Of radiant URIM, work divinely wrought,
Ascended, at his right hand Victorie
Sate Eagle-wing'd, beside him hung his Bow
And Quiver with three-bolted Thunder stor'd,
And from about him fierce Effusion rowld
Of smoak and bickering flame, and sparkles dire;
Attended with ten thousand thousand Saints,
He onward came, farr off his coming shon,
And twentie thousand (I thir number heard)
Chariots of God, half on each hand were seen:
Hee on the wings of Cherub rode sublime
On the Crystallin Skie, in Saphir Thron'd.
Illustrious farr and wide, but by his own
First seen, them unexpected joy surpriz'd,
When the great Ensign of MESSIAH blaz'd
Aloft by Angels born, his Sign in Heav'n:
Under whose Conduct MICHAEL soon reduc'd
His Armie, circumfus'd on either Wing,
Under thir Head imbodied all in one.
Before him Power Divine his way prepar'd;
At his command the uprooted Hills retir'd
Each to his place, they heard his voice and went
Obsequious, Heav'n his wonted face renewd,
And with fresh Flourets Hill and Valley smil'd.
This saw his hapless Foes, but stood obdur'd,
And to rebellious fight rallied thir Powers
Insensate, hope conceiving from despair.
In heav'nly Spirits could such perverseness dwell?
But to convince the proud what Signs availe,
Or Wonders move th' obdurate to relent?
They hard'nd more by what might most reclame,
Grieving to see his Glorie, at the sight
Took envie, and aspiring to his highth,
Stood reimbattell'd fierce, by force or fraud
Weening to prosper, and at length prevaile
Against God and MESSIAH, or to fall
In universal ruin last, and now
To final Battel drew, disdaining flight,
Or faint retreat; when the great Son of God
To all his Host on either hand thus spake.
Stand still in bright array ye Saints, here stand
Ye Angels arm'd, this day from Battel rest;
Faithful hath been your Warfare, and of God
Accepted, fearless in his righteous Cause,
And as ye have receivd, so have ye don
Invincibly; but of this cursed crew
The punishment to other hand belongs,
Vengeance is his, or whose he sole appoints;
Number to this dayes work is not ordain'd
Nor multitude, stand onely and behold
Gods indignation on these Godless pourd
By mee; not you but mee they have despis'd,
Yet envied; against mee is all thir rage,
Because the Father, t' whom in Heav'n supream
Kingdom and Power and Glorie appertains,
Hath honourd me according to his will.
Therefore to mee thir doom he hath assig'n'd;
That they may have thir wish, to trie with mee
In Battel which the stronger proves, they all,
Or I alone against them, since by strength
They measure all, of other excellence
Not emulous, nor care who them excells;
Nor other strife with them do I voutsafe.
So spake the Son, and into terrour chang'd
His count'nance too severe to be beheld
And full of wrauth bent on his Enemies.
At once the Four spred out thir Starrie wings
With dreadful shade contiguous, and the Orbes
Of his fierce Chariot rowld, as with the sound
Of torrent Floods, or of a numerous Host.
Hee on his impious Foes right onward drove,
Gloomie as Night; under his burning Wheeles
The stedfast Empyrean shook throughout,
All but the Throne it self of God. Full soon
Among them he arriv'd; in his right hand
Grasping ten thousand Thunders, which he sent
Before him, such as in thir Soules infix'd
Plagues; they astonisht all resistance lost,
All courage; down thir idle weapons drop'd;
O're Shields and Helmes, and helmed heads he rode
Of Thrones and mighty Seraphim prostrate,
That wish'd the Mountains now might be again
Thrown on them as a shelter from his ire.
Nor less on either side tempestuous fell
His arrows, from the fourfold-visag'd Foure,
Distinct with eyes, and from the living Wheels,
Distinct alike with multitude of eyes,
One Spirit in them rul'd, and every eye
Glar'd lightning, and shot forth pernicious fire
Among th' accurst, that witherd all thir strength,
And of thir wonted vigour left them draind,
Exhausted, spiritless, afflicted, fall'n.
Yet half his strength he put not forth, but check'd
His Thunder in mid Volie, for he meant
Not to destroy, but root them out of Heav'n:
The overthrown he rais'd, and as a Heard
Of Goats or timerous flock together throngd
Drove them before him Thunder-struck, pursu'd
With terrors and with furies to the bounds
And Chrystall wall of Heav'n, which op'ning wide,
Rowld inward, and a spacious Gap disclos'd
Into the wastful Deep; the monstrous sight
Strook them with horror backward, but far worse
Urg'd them behind; headlong themselvs they threw
Down from the verge of Heav'n, Eternal wrauth
Burnt after them to the bottomless pit.
Hell heard th' unsufferable noise, Hell saw
Heav'n ruining from Heav'n and would have fled
Affrighted; but strict Fate had cast too deep
Her dark foundations, and too fast had bound.
Nine dayes they fell; confounded CHAOS roard,
And felt tenfold confusion in thir fall
Through his wilde Anarchie, so huge a rout
Incumberd him with ruin: Hell at last
Yawning receavd them whole, and on them clos'd,
Hell thir fit habitation fraught with fire
Unquenchable, the house of woe and paine.
Disburd'nd Heav'n rejoic'd, and soon repaird
Her mural breach, returning whence it rowld.
Sole Victor from th' expulsion of his Foes
MESSIAH his triumphal Chariot turnd:
To meet him all his Saints, who silent stood
Eye witnesses of his Almightie Acts,
With Jubilie advanc'd; and as they went,
Shaded with branching Palme, each order bright,
Sung Triumph, and him sung Victorious King,
Son, Heire, and Lord, to him Dominion giv'n,
Worthiest to Reign: he celebrated rode
Triumphant through mid Heav'n, into the Courts
And Temple of his mightie Father Thron'd
On high; who into Glorie him receav'd,
Where now he sits at the right hand of bliss.
Thus measuring things in Heav'n by things on Earth
At thy request, and that thou maist beware
By what is past, to thee I have reveal'd
What might have else to human Race bin hid;
The discord which befel, and Warr in Heav'n
Among th' Angelic Powers, and the deep fall
Of those too high aspiring, who rebelld
With SATAN, hee who envies now thy state,
Who now is plotting how he may seduce
Thee also from obedience, that with him
Bereavd of happiness thou maist partake
His punishment, Eternal miserie;
Which would be all his solace and revenge,
As a despite don against the most High,
Thee once to gaine Companion of his woe.
But list'n not to his Temptations, warne
Thy weaker; let it profit thee to have heard
By terrible Example the reward
Of disobedience; firm they might have stood,
Yet fell; remember, and fear to transgress.
THE END OF THE SIXTH BOOK.
PARADISE LOST.
BOOK VII.
Descend from Heav'n URANIA, by that name
If rightly thou art call'd, whose Voice divine
Following, above th' OLYMPIAN Hill I soare,
Above the flight of PEGASEAN wing.
The meaning, not the Name I call: for thou
Nor of the Muses nine, nor on the top
Of old OLYMPUS dwell'st, but Heav'nlie borne,
Before the Hills appeerd, or Fountain flow'd,
Thou with Eternal wisdom didst converse,
Wisdom thy Sister, and with her didst play
In presence of th' Almightie Father, pleas'd
With thy Celestial Song. Up led by thee
Into the Heav'n of Heav'ns I have presum'd,
An Earthlie Guest, and drawn Empyreal Aire,
Thy tempring; with like safetie guided down
Return me to my Native Element:
Least from this flying Steed unrein'd, (as once
BELLEROPHON, though from a lower Clime)
Dismounted, on th' ALEIAN Field I fall
Erroneous, there to wander and forlorne.
Half yet remaines unsung, but narrower bound
Within the visible Diurnal Spheare;
Standing on Earth, not rapt above the Pole,
More safe I Sing with mortal voice, unchang'd
To hoarce or mute, though fall'n on evil dayes,
On evil dayes though fall'n, and evil tongues;
In darkness, and with dangers compast rouud,
And solitude; yet not alone, while thou
Visit'st my slumbers Nightly, or when Morn
Purples the East: still govern thou my Song,
URANIA, and fit audience find, though few.
But drive farr off the barbarous dissonance
Of BACCHUS and his Revellers, the Race
Of that wilde Rout that tore the THRACIAN Bard
In RHODOPE, where Woods and Rocks had Eares
To rapture, till the savage clamor dround
Both Harp and Voice; nor could the Muse defend
Her Son. So fail not thou, who thee implores:
For thou art Heav'nlie, shee an empty dreame.
Say Goddess, what ensu'd when RAPHAEL,
The affable Arch-angel, had forewarn'd
ADAM by dire example to beware
Apostasie, by what befell in Heaven
To those Apostates, least the like befall
In Paradise to ADAM or his Race,
Charg'd not to touch the interdicted Tree,
If they transgress, and slight that sole command,
So easily obeyd amid the choice
Of all tasts else to please thir appetite,
Though wandring. He with his consorted EVE
The storie heard attentive, and was fill'd
With admiration, and deep Muse to heare
Of things so high and strange, things to thir thought
So unimaginable as hate in Heav'n,
And Warr so neer the Peace of God in bliss
With such confusion: but the evil soon
Driv'n back redounded as a flood on those
From whom it sprung, impossible to mix
With Blessedness. Whence ADAM soon repeal'd
The doubts that in his heart arose: and now
Led on, yet sinless, with desire to know
What neerer might concern him, how this World
Of Heav'n and Earth conspicuous first began,
When, and whereof created, for what cause,
What within EDEN or without was done
Before his memorie, as one whose drouth
Yet scarce allay'd still eyes the current streame,
Whose liquid murmur heard new thirst excites,
Proceeded thus to ask his Heav'nly Guest.
Great things, and full of wonder in our eares,
Farr differing from this World, thou hast reveal'd
Divine Interpreter, by favour sent
Down from the Empyrean to forewarne
Us timely of what might else have bin our loss,
Unknown, which human knowledg could not reach:
For which to the infinitly Good we owe
Immortal thanks, and his admonishment
Receave with solemne purpose to observe
Immutably his sovran will, the end
Of what we are. But since thou hast voutsaf't
Gently for our instruction to impart
Things above Earthly thought, which yet concernd
Our knowing, as to highest wisdom seemd,
Deign to descend now lower, and relate
What may no less perhaps availe us known,
How first began this Heav'n which we behold
Distant so high, with moving Fires adornd
Innumerable, and this which yeelds or fills
All space, the ambient Aire wide interfus'd
Imbracing round this florid Earth, what cause
Mov'd the Creator in his holy Rest
Through all Eternitie so late to build
In CHAOS, and the work begun, how soon
Absolv'd, if unforbid thou maist unfould
What wee, not to explore the secrets aske
Of his Eternal Empire, but the more
To magnifie his works, the more we know.
And the great Light of Day yet wants to run
Much of his Race though steep, suspens in Heav'n
Held by thy voice, thy potent voice he heares,
And longer will delay to heare thee tell
His Generation, and the rising Birth
Of Nature from the unapparent Deep:
Or if the Starr of Eevning and the Moon
Haste to thy audience, Night with her will bring
Silence, and Sleep listning to thee will watch,
Or we can bid his absence, till thy Song
End, and dismiss thee ere the Morning shine.
Thus ADAM his illustrous Guest besought:
And thus the Godlike Angel answerd milde.
This also thy request with caution askt
Obtaine: though to recount Almightie works
What words or tongue of Seraph can suffice,
Or heart of man suffice to comprehend?
Yet what thou canst attain, which best may serve
To glorifie the Maker, and inferr
Thee also happier, shall not be withheld
Thy hearing, such Commission from above
I have receav'd, to answer thy desire
Of knowledge within bounds; beyond abstain
To ask, nor let thine own inventions hope
Things not reveal'd, which th' invisible King,
Onely Omniscient, hath supprest in Night,
To none communicable in Earth or Heaven:
Anough is left besides to search and know.
But Knowledge is as food, and needs no less
Her Temperance over Appetite, to know
In measure what the mind may well contain,
Oppresses else with Surfet, and soon turns
Wisdom to Folly, as Nourishment to Winde.
Know then, that after LUCIFER from Heav'n
(So call him, brighter once amidst the Host
Of Angels, then that Starr the Starrs among)
Fell with his flaming Legions through the Deep
Into his place, and the great Son returnd
Victorious with his Saints, th' Omnipotent
Eternal Father from his Throne beheld
Thir multitude, and to his Son thus spake.
At least our envious Foe hath fail'd, who thought
All like himself rebellious, by whose aid
This inaccessible high strength, the seat
Of Deitie supream, us dispossest,
He trusted to have seis'd, and into fraud
Drew many, whom thir place knows here no more;
Yet farr the greater part have kept, I see,
Thir station, Heav'n yet populous retaines
Number sufficient to possess her Realmes
Though wide, and this high Temple to frequent
With Ministeries due and solemn Rites:
But least his heart exalt him in the harme
Already done, to have dispeopl'd Heav'n,
My damage fondly deem'd, I can repaire
That detriment, if such it be to lose
Self-lost, and in a moment will create
Another World, out of one man a Race
Of men innumerable, there to dwell,
Not here, till by degrees of merit rais'd
They open to themselves at length the way
Up hither, under long obedience tri'd,
And Earth be chang'd to Heavn, & Heav'n to Earth,
One Kingdom, Joy and Union without end.
Mean while inhabit laxe, ye Powers of Heav'n,
And thou my Word, begotten Son, by thee
This I perform, speak thou, and be it don:
My overshadowing Spirit and might with thee
I send along, ride forth, and bid the Deep
Within appointed bounds be Heav'n and Earth,
Boundless the Deep, because I am who fill
Infinitude, nor vacuous the space.
Though I uncircumscrib'd my self retire,
And put not forth my goodness, which is free
To act or not, Necessitie and Chance
Approach not mee, and what I will is Fate.
So spake th' Almightie, and to what he spake
His Word, the Filial Godhead, gave effect.
Immediate are the Acts of God, more swift
Then time or motion, but to human ears
Cannot without process of speech be told,
So told as earthly notion can receave.
Great triumph and rejoycing was in Heav'n
When such was heard declar'd the Almightie's will;
Glorie they sung to the most High, good will
To future men, and in thir dwellings peace:
Glorie to him whose just avenging ire
Had driven out th' ungodly from his sight
And th' habitations of the just; to him
Glorie and praise, whose wisdom had ordain'd
Good out of evil to create, in stead
Of Spirits maligne a better Race to bring
Into thir vacant room, and thence diffuse
His good to Worlds and Ages infinite.
So sang the Hierarchies: Mean while the Son
On his great Expedition now appeer'd,
Girt with Omnipotence, with Radiance crown'd
Of Majestie Divine, Sapience and Love
Immense, and all his Father in him shon.
About his Chariot numberless were pour'd
Cherub and Seraph, Potentates and Thrones,
And Vertues, winged Spirits, and Chariots wing'd,
From the Armoury of God, where stand of old
Myriads between two brazen Mountains lodg'd
Against a solemn day, harnest at hand,
Celestial Equipage; and now came forth
Spontaneous, for within them Spirit livd,
Attendant on thir Lord: Heav'n op'nd wide
Her ever during Gates, Harmonious sound
On golden Hinges moving, to let forth
The King of Glorie in his powerful Word
And Spirit coming to create new Worlds.
On heav'nly ground they stood, and from the shore
They view'd the vast immeasurable Abyss
Outrageous as a Sea, dark, wasteful, wilde,
Up from the bottom turn'd by furious windes
And surging waves, as Mountains to assault
Heav'ns highth, and with the Center mix the Pole.
Silence, ye troubl'd waves, and thou Deep, peace,
Said then th' Omnific Word, your discord end:
Nor staid, but on the Wings of Cherubim
Uplifted, in Paternal Glorie rode
Farr into CHAOS, and the World unborn;
For CHAOS heard his voice: him all his Traine
Follow'd in bright procession to behold
Creation, and the wonders of his might.
Then staid the fervid Wheeles, and in his hand
He took the golden Compasses, prepar'd
In Gods Eternal store, to circumscribe
This Universe, and all created things:
One foot he center'd, and the other turn'd
Round through the vast profunditie obscure,
And said, thus farr extend, thus farr thy bounds,
This be thy just Circumference, O World.
Thus God the Heav'n created, thus the Earth,
Matter unform'd and void: Darkness profound
Cover'd th' Abyss: but on the watrie calme
His brooding wings the Spirit of God outspred,
And vital vertue infus'd, and vital warmth
Throughout the fluid Mass, but downward purg'd
The black tartareous cold infernal dregs
Adverse to life: then founded, then conglob'd
Like things to like, the rest to several place
Disparted, and between spun out the Air,
And Earth self-ballanc't on her Center hung.
Let ther be Light, said God, and forthwith Light
Ethereal, first of things, quintessence pure
Sprung from the Deep, and from her Native East
To journie through the airie gloom began,
Sphear'd in a radiant Cloud, for yet the Sun
Was not; shee in a cloudie Tabernacle
Sojourn'd the while. God saw the Light was good;
And light from darkness by the Hemisphere
Divided: Light the Day, and Darkness Night
He nam'd. Thus was the first Day Eev'n and Morn:
Nor past uncelebrated, nor unsung
By the Celestial Quires, when Orient Light
Exhaling first from Darkness they beheld;
Birth-day of Heav'n and Earth; with joy and shout
The hollow Universal Orb they fill'd,
And touch't thir Golden Harps, & hymning prais'd
God and his works, Creatour him they sung,
Both when first Eevning was, and when first Morn.
Again, God said, let ther be Firmament
Amid the Waters, and let it divide
The Waters from the Waters: and God made
The Firmament, expanse of liquid, pure,
Transparent, Elemental Air, diffus'd
In circuit to the uttermost convex
Of this great Round: partition firm and sure,
The Waters underneath from those above
Dividing: for as Earth, so hee the World
Built on circumfluous Waters calme, in wide
Crystallin Ocean, and the loud misrule
Of CHAOS farr remov'd, least fierce extreames
Contiguous might distemper the whole frame:
And Heav'n he nam'd the Firmament: So Eev'n
And Morning CHORUS sung the second Day.
The Earth was form'd, but in the Womb as yet
Of Waters, Embryon immature involv'd,
Appeer'd not: over all the face of Earth
Main Ocean flow'd, not idle, but with warme
Prolific humour soft'ning all her Globe,
Fermented the great Mother to conceave,
Satiate with genial moisture, when God said
Be gather'd now ye Waters under Heav'n
Into one place, and let dry Land appeer.
Immediately the Mountains huge appeer
Emergent, and thir broad bare backs upheave
Into the Clouds, thir tops ascend the Skie:
So high as heav'd the tumid Hills, so low
Down sunk a hollow bottom broad and deep,
Capacious bed of Waters: thither they
Hasted with glad precipitance, uprowld
As drops on dust conglobing from the drie;
Part rise in crystal Wall, or ridge direct,
For haste; such flight the great command impress'd
On the swift flouds: as Armies at the call
Of Trumpet (for of Armies thou hast heard)
Troop to thir Standard, so the watrie throng,
Wave rowling after Wave, where way they found,
If steep, with torrent rapture, if through Plaine,
Soft-ebbing; nor withstood them Rock or Hill,
But they, or under ground, or circuit wide
With Serpent errour wandring, found thir way,
And on the washie Oose deep Channels wore;
Easie, e're God had bid the ground be drie,
All but within those banks, where Rivers now
Stream, and perpetual draw thir humid traine.
The dry Land, Earth, and the great receptacle
Of congregated Waters he call'd Seas:
And saw that it was good, and said, Let th' Earth
Put forth the verdant Grass, Herb yeilding Seed,
And Fruit Tree yeilding Fruit after her kind;
Whose Seed is in her self upon the Earth.
He scarce had said, when the bare Earth, till then
Desert and bare, unsightly, unadorn'd,
Brought forth the tender Grass, whose verdure clad
Her Universal Face with pleasant green,
Then Herbs of every leaf, that sudden flour'd
Op'ning thir various colours, and made gay
Her bosom smelling sweet: and these scarce blown,
Forth flourish't thick the clustring Vine, forth crept
The smelling Gourd, up stood the cornie Reed
Embattell'd in her field: add the humble Shrub,
And Bush with frizl'd hair implicit: last
Rose as in Dance the stately Trees, and spred
Thir branches hung with copious Fruit; or gemm'd
Thir Blossoms: with high Woods the Hills were crownd,
With tufts the vallies & each fountain side,
With borders long the Rivers. That Earth now
Seemd like to Heav'n, a seat where Gods might dwell,
Or wander with delight, and love to haunt
Her sacred shades: though God had yet not rain'd
Upon the Earth, and man to till the ground
None was, but from the Earth a dewie Mist
Went up and waterd all the ground, and each
Plant of the field, which e're it was in the Earth
God made, and every Herb, before it grew
On the green stemm; God saw that it was good:
So Eev'n and Morn recorded the Third Day.
Again th' Almightie spake: Let there be Lights
High in th' expanse of Heaven to divide
The Day from Night; and let them be for Signes,
For Seasons, and for Dayes, and circling Years,
And let them be for Lights as I ordaine
Thir Office in the Firmament of Heav'n
To give Light on the Earth; and it was so.
And God made two great Lights, great for thir use
To Man, the greater to have rule by Day,
The less by Night alterne: and made the Starrs,
And set them in the Firmament of Heav'n
To illuminate the Earth, and rule the Day
In thir vicissitude, and rule the Night,
And Light from Darkness to divide. God saw,
Surveying his great Work, that it was good:
For of Celestial Bodies first the Sun
A mightie Spheare he fram'd, unlightsom first,
Though of Ethereal Mould: then form'd the Moon
Globose, and everie magnitude of Starrs,
And sowd with Starrs the Heav'n thick as a field:
Of Light by farr the greater part he took,
Transplanted from her cloudie Shrine, and plac'd
In the Suns Orb, made porous to receive
And drink the liquid Light, firm to retaine
Her gather'd beams, great Palace now of Light.
Hither as to thir Fountain other Starrs
Repairing, in thir gold'n Urns draw Light,
And hence the Morning Planet guilds his horns;
By tincture or reflection they augment
Thir small peculiar, though from human sight
So farr remote, with diminution seen.
First in his East the glorious Lamp was seen,
Regent of Day, and all th' Horizon round
Invested with bright Rayes, jocond to run
His Longitude through Heav'ns high rode: the gray
Dawn, and the PLEIADES before him danc'd
Shedding sweet influence: less bright the Moon,
But opposite in leveld West was set
His mirror, with full face borrowing her Light
From him, for other light she needed none
In that aspect, and still that distance keepes
Till night, then in the East her turn she shines,
Revolvd on Heav'ns great Axle, and her Reign
With thousand lesser Lights dividual holds,
With thousand thousand Starres, that then appeer'd
Spangling the Hemisphere: then first adornd
With thir bright Luminaries that Set and Rose,
Glad Eevning & glad Morn crownd the fourth day.
And God said, let the Waters generate
Reptil with Spawn abundant, living Soule:
And let Fowle flie above the Earth, with wings
Displayd on the op'n Firmament of Heav'n.
And God created the great Whales, and each
Soul living, each that crept, which plenteously
The waters generated by thir kindes,
And every Bird of wing after his kinde;
And saw that it was good, and bless'd them, saying,
Be fruitful, multiply, and in the Seas
And Lakes and running Streams the waters fill;
And let the Fowle be multiply'd on the Earth.
Forthwith the Sounds and Seas, each Creek & Bay
With Frie innumerable swarme, and Shoales
Of Fish that with thir Finns and shining Scales
Glide under the green Wave, in Sculles that oft
Bank the mid Sea: part single or with mate
Graze the Sea weed thir pasture, & through Groves
Of Coral stray, or sporting with quick glance
Show to the Sun thir wav'd coats dropt with Gold,
Or in thir Pearlie shells at ease, attend
Moist nutriment, or under Rocks thir food
In jointed Armour watch: on smooth the Seale,
And bended Dolphins play: part huge of bulk
Wallowing unweildie, enormous in thir Gate
Tempest the Ocean: there Leviathan
Hugest of living Creatures, on the Deep
Stretcht like a Promontorie sleeps or swimmes,
And seems a moving Land, and at his Gilles
Draws in, and at his Trunck spouts out a Sea.
Mean while the tepid Caves, and Fens and shoares
Thir Brood as numerous hatch, from the Egg that soon
Bursting with kindly rupture forth disclos'd
Thir callow young, but featherd soon and fledge
They summ'd thir Penns, and soaring th' air sublime
With clang despis'd the ground, under a cloud
In prospect; there the Eagle and the Stork
On Cliffs and Cedar tops thir Eyries build:
Part loosly wing the Region, part more wise
In common, rang'd in figure wedge thir way,
Intelligent of seasons, and set forth
Thir Aierie Caravan high over Sea's
Flying, and over Lands with mutual wing
Easing thir flight; so stears the prudent Crane
Her annual Voiage, born on Windes; the Aire
Floats, as they pass, fann'd with unnumber'd plumes:
From Branch to Branch the smaller Birds with song
Solac'd the Woods, and spred thir painted wings
Till Ev'n, nor then the solemn Nightingal
Ceas'd warbling, but all night tun'd her soft layes:
Others on Silver Lakes and Rivers Bath'd
Thir downie Brest; the Swan with Arched neck
Between her white wings mantling proudly, Rowes
Her state with Oarie feet: yet oft they quit
The Dank, and rising on stiff Pennons, towre
The mid Aereal Skie: Others on ground
Walk'd firm; the crested Cock whose clarion sounds
The silent hours, and th' other whose gay Traine
Adorns him, colour'd with the Florid hue
Of Rainbows and Starrie Eyes. The Waters thus
With Fish replenisht, and the Aire with Fowle,
Ev'ning and Morn solemniz'd the Fift day.
The Sixt, and of Creation last arose
With Eevning Harps and Mattin, when God said,
Let th' Earth bring forth Fowle living in her kinde,
Cattel and Creeping things, and Beast of the Earth,
Each in their kinde. The Earth obey'd, and strait
Op'ning her fertil Woomb teem'd at a Birth
Innumerous living Creatures, perfet formes,
Limb'd and full grown: out of the ground up-rose
As from his Laire the wilde Beast where he wonns
In Forrest wilde, in Thicket, Brake, or Den;
Among the Trees in Pairs they rose, they walk'd:
The Cattel in the Fields and Meddowes green:
Those rare and solitarie, these in flocks
Pasturing at once, and in broad Herds upsprung:
The grassie Clods now Calv'd, now half appeer'd
The Tawnie Lion, pawing to get free
His hinder parts, then springs as broke from Bonds,
And Rampant shakes his Brinded main; the Ounce,
The Libbard, and the Tyger, as the Moale
Rising, the crumbl'd Earth above them threw
In Hillocks; the swift Stag from under ground
Bore up his branching head: scarse from his mould
BEHEMOTH biggest born of Earth upheav'd
His vastness: Fleec't the Flocks and bleating rose,
As Plants: ambiguous between Sea and Land
The River Horse and scalie Crocodile.
At once came forth whatever creeps the ground,
Insect or Worme; those wav'd thir limber fans
For wings, and smallest Lineaments exact
In all the Liveries dect of Summers pride
With spots of Gold and Purple, azure and green:
These as a line thir long dimension drew,
Streaking the ground with sinuous trace; not all
Minims of Nature; some of Serpent kinde
Wondrous in length and corpulence involv'd
Thir Snakie foulds, and added wings. First crept
The Parsimonious Emmet, provident
Of future, in small room large heart enclos'd,
Pattern of just equalitie perhaps
Hereafter, join'd in her popular Tribes
Of Commonaltie: swarming next appeer'd
The Femal Bee that feeds her Husband Drone
Deliciously, and builds her waxen Cells
With Honey stor'd: the rest are numberless,
And thou thir Natures know'st, and gav'st them Names,
Needlest to thee repeaed; nor unknown
The Serpent suttl'st Beast of all the field,
Of huge extent somtimes, with brazen Eyes
And hairie Main terrific, though to thee
Not noxious, but obedient at thy call.
Now Heav'n in all her Glorie shon, and rowld
Her motions, as the great first-Movers hand
First wheeld thir course; Earth in her rich attire
Consummate lovly smil'd; Aire, Water, Earth,
By Fowl, Fish, Beast, was flown, was swum, was walkt
Frequent; and of the Sixt day yet remain'd;
There wanted yet the Master work, the end
Of all yet don; a Creature who not prone
And Brute as other Creatures, but endu'd
With Sanctitie of Reason, might erect
His Stature, and upright with Front serene
Govern the rest, self-knowing, and from thence
Magnanimous to correspond with Heav'n,
But grateful to acknowledge whence his good
Descends, thither with heart and voice and eyes
Directed in Devotion, to adore
And worship God Supream, who made him chief
Of all his works: therefore the Omnipotent
Eternal Father (For where is not hee
Present) thus to his Son audibly spake.
Let us make now Man in our image, Man
In our similitude, and let them rule
Over the Fish and Fowle of Sea and Aire,
Beast of the Field, and over all the Earth,
And every creeping thing that creeps the ground.
This said, he formd thee, ADAM, thee O Man
Dust of the ground, and in thy nostrils breath'd
The breath of Life; in his own Image hee
Created thee, in the Image of God
Express, and thou becam'st a living Soul.
Male he created thee, but thy consort
Femal for Race; then bless'd Mankinde, and said,
Be fruitful, multiplie, and fill the Earth,
Subdue it, and throughout Dominion hold
Over Fish of the Sea, and Fowle of the Aire,
And every living thing that moves on the Earth.
Wherever thus created, for no place
Is yet distinct by name, thence, as thou know'st
He brought thee into this delicious Grove,
This Garden, planted with the Trees of God,
Delectable both to behold and taste;
And freely all thir pleasant fruit for food
Gave thee, all sorts are here that all th' Earth yeelds,
Varietie without end; but of the Tree
Which tasted works knowledge of Good and Evil,
Thou mai'st not; in the day thou eat'st, thou di'st;
Death is the penaltie impos'd, beware,
And govern well thy appetite, least sin
Surprise thee, and her black attendant Death.
Here finish'd hee, and all that he had made
View'd, and behold all was entirely good;
So Ev'n and Morn accomplish'd the Sixt day:
Yet not till the Creator from his work
Desisting, though unwearied, up returnd
Up to the Heav'n of Heav'ns his high abode,
Thence to behold this new created World
Th' addition of his Empire, how it shew'd
In prospect from his Throne, how good, how faire,
Answering his great Idea. Up he rode
Followd with acclamation and the sound
Symphonious of ten thousand Harpes that tun'd
Angelic harmonies: the Earth, the Aire
Resounded, (thou remember'st, for thou heardst)
The Heav'ns and all the Constellations rung,
The Planets in thir stations list'ning stood,
While the bright Pomp ascended jubilant.
Open, ye everlasting Gates, they sung,
Open, ye Heav'ns, your living dores; let in
The great Creator from his work returnd
Magnificent, his Six days work, a World;
Open, and henceforth oft; for God will deigne
To visit oft the dwellings of just Men
Delighted, and with frequent intercourse
Thither will send his winged Messengers
On errands of supernal Grace. So sung
The glorious Train ascending: He through Heav'n,
That open'd wide her blazing Portals, led
To Gods Eternal house direct the way,
A broad and ample rode, whose dust is Gold
And pavement Starrs, as Starrs to thee appeer,
Seen in the Galaxie, that Milkie way
Which nightly as a circling Zone thou seest
Pouderd with Starrs. And now on Earth the Seaventh
Eev'ning arose in EDEN, for the Sun
Was set, and twilight from the East came on,
Forerunning Night; when at the holy mount
Of Heav'ns high-seated top, th' Impereal Throne
Of Godhead, fixt for ever firm and sure,
The Filial Power arriv'd, and sate him down
With his great Father (for he also went
Invisible, yet staid (such priviledge
Hath Omnipresence) and the work ordain'd,
Author and end of all things, and from work
Now resting, bless'd and hallowd the Seav'nth day,
As resting on that day from all his work,
But not in silence holy kept; the Harp
Had work and rested not, the solemn Pipe,
And Dulcimer, all Organs of sweet stop,
All sounds on Fret by String or Golden Wire
Temper'd soft Tunings, intermixt with Voice
Choral or Unison: of incense Clouds
Fuming from Golden Censers hid the Mount.
Creation and the Six dayes acts they sung,
Great are thy works, JEHOVAH, infinite
Thy power; what thought can measure thee or tongue
Relate thee; greater now in thy return
Then from the Giant Angels; thee that day
Thy Thunders magnifi'd; but to create
Is greater then created to destroy.
Who can impair thee, mighty King, or bound
Thy Empire? easily the proud attempt
Of Spirits apostat and thir Counsels vaine
Thou hast repeld, while impiously they thought
Thee to diminish, and from thee withdraw
The number of thy worshippers. Who seekes
To lessen thee, against his purpose serves
To manifest the more thy might: his evil
Thou usest, and from thence creat'st more good.
Witness this new-made World, another Heav'n
From Heaven Gate not farr, founded in view
On the cleer HYALINE, the Glassie Sea;
Of amplitude almost immense, with Starr's
Numerous, and every Starr perhaps a World
Of destind habitation; but thou know'st
Thir seasons: among these the seat of men,
Earth with her nether Ocean circumfus'd,
Thir pleasant dwelling place. Thrice happie men,
And sons of men, whom God hath thus advanc't,
Created in his Image, there to dwell
And worship him, and in reward to rule
Over his Works, on Earth, in Sea, or Air,
And multiply a Race of Worshippers
Holy and just: thrice happie if they know
Thir happiness, and persevere upright.
So sung they, and the Empyrean rung,
With HALLELUIAHS: Thus was Sabbath kept.
And thy request think now fulfill'd, that ask'd
How first this World and face of things began,
And what before thy memorie was don
From the beginning, that posteritie
Informd by thee might know; if else thou seekst
Aught, not surpassing human measure, say.
To whom thus ADAM gratefully repli'd.
What thanks sufficient, or what recompence
Equal have I to render thee, Divine
Hystorian, who thus largely hast allayd
The thirst I had of knowledge, and voutsaf't
This friendly condescention to relate
Things else by me unsearchable, now heard
VVith wonder, but delight, and, as is due,
With glorie attributed to the high
Creator; some thing yet of doubt remaines,
VVhich onely thy solution can resolve.
VVhen I behold this goodly Frame, this VVorld
Of Heav'n and Earth consisting, and compute,
Thir magnitudes, this Earth a spot, a graine,
An Atom, with the Firmament compar'd
And all her numberd Starrs, that seem to rowle
Spaces incomprehensible (for such
Thir distance argues and thir swift return
Diurnal) meerly to officiate light
Round this opacous Earth, this punctual spot,
One day and night; in all thir vast survey
Useless besides, reasoning I oft admire,
How Nature wise and frugal could commit
Such disproportions, with superfluous hand
So many nobler Bodies to create,
Greater so manifold to this one use,
For aught appeers, and on thir Orbs impose
Such restless revolution day by day
Repeated, while the sedentarie Earth,
That better might with farr less compass move,
Serv'd by more noble then her self, attaines
Her end without least motion, and receaves,
As Tribute such a sumless journey brought
Of incorporeal speed, her warmth and light;
Speed, to describe whose swiftness Number failes.
So spake our Sire, and by his count'nance seemd
Entring on studious thoughts abstruse, which EVE
Perceaving where she sat retir'd in sight,
With lowliness Majestic from her seat,
And Grace that won who saw to wish her stay,
Rose, and went forth among her Fruits and Flours,
To visit how they prosper'd, bud and bloom,
Her Nurserie; they at her coming sprung
And toucht by her fair tendance gladlier grew.
Yet went she not, as not with such discourse
Delighted, or not capable her eare
Of what was high: such pleasure she reserv'd,
ADAM relating, she sole Auditress;
Her Husband the Relater she preferr'd
Before the Angel, and of him to ask
Chose rather; hee, she knew would intermix
Grateful digressions, and solve high dispute
With conjugal Caresses, from his Lip
Not Words alone pleas'd her. O when meet now
Such pairs, in Love and mutual Honour joyn'd?
With Goddess-like demeanour forth she went;
Not unattended, for on her as Queen
A pomp of winning Graces waited still,
And from about her shot Darts of desire
Into all Eyes to wish her still in sight.
And RAPHAEL now to ADAM's doubt propos'd
Benevolent and facil thus repli'd.
To ask or search I blame thee not, for Heav'n
Is as the Book of God before thee set,
Wherein to read his wondrous Works, and learne
His Seasons, Hours, or Days, or Months, or Yeares:
This to attain, whether Heav'n move or Earth,
Imports not, if thou reck'n right, the rest
From Man or Angel the great Architect
Did wisely to conceal, and not divulge
His secrets to be scann'd by them who ought
Rather admire; or if they list to try
Conjecture, he his Fabric of the Heav'ns
Hath left to thir disputes, perhaps to move
His laughter at thir quaint Opinions wide
Hereafter, when they come to model Heav'n
And calculate the Starrs, how they will weild
The mightie frame, how build, unbuild, contrive
To save appeerances, how gird the Sphear
With Centric and Eccentric scribl'd o're,
Cycle and Epicycle, Orb in Orb:
Alreadie by thy reasoning this I guess,
Who art to lead thy ofspring, and supposest
That Bodies bright and greater should not serve
The less not bright, nor Heav'n such journies run,
Earth sitting still, when she alone receaves
The benefit: consider first, that Great
Or Bright inferrs not Excellence: the Earth
Though, in comparison of Heav'n, so small,
Nor glistering, may of solid good containe
More plenty then the Sun that barren shines,
Whose vertue on it self workes no effect,
But in the fruitful Earth; there first receavd
His beams, unactive else, thir vigor find.
Yet not to Earth are those bright Luminaries
Officious, but to thee Earths habitant.
And for the Heav'ns wide Circuit, let it speak
The Makers high magnificence, who built
So spacious, and his Line stretcht out so farr;
That Man may know he dwells not in his own;
An Edifice too large for him to fill,
Lodg'd in a small partition, and the rest
Ordain'd for uses to his Lord best known.
The swiftness of those Circles attribute,
Though numberless, to his Omnipotence,
That to corporeal substances could adde
Speed almost Spiritual; mee thou thinkst not slow,
Who since the Morning hour set out from Heav'n
Where God resides, and ere mid-day arriv'd
In EDEN, distance inexpressible
By Numbers that have name. But this I urge,
Admitting Motion in the Heav'ns, to shew
Invalid that which thee to doubt it mov'd;
Not that I so affirm, though so it seem
To thee who hast thy dwelling here on Earth.
God to remove his wayes from human sense,
Plac'd Heav'n from Earth so farr, that earthly sight,
If it presume, might erre in things too high,
And no advantage gaine. What if the Sun
Be Center to the World, and other Starrs
By his attractive vertue and thir own
Incited, dance about him various rounds?
Thir wandring course now high, now low, then hid,
Progressive, retrograde, or standing still,
In six thou seest, and what if sev'nth to these
The Planet Earth, so stedfast though she seem,
Insensibly three different Motions move?
Which else to several Sphears thou must ascribe,
Mov'd contrarie with thwart obliquities,
Or save the Sun his labour, and that swift
Nocturnal and Diurnal rhomb suppos'd,
Invisible else above all Starrs, the Wheele
Of Day and Night; which needs not thy beleefe,
If Earth industrious of her self fetch Day
Travelling East, and with her part averse
From the Suns beam meet Night, her other part
Still luminous by his ray. What if that light
Sent from her through the wide transpicuous aire,
To the terrestrial Moon be as a Starr
Enlightning her by Day, as she by Night
This Earth? reciprocal, if Land be there,
Feilds and Inhabitants: Her spots thou seest
As Clouds, and Clouds may rain, and Rain produce
Fruits in her soft'nd Soile, for some to eate
Allotted there; and other Suns perhaps
With thir attendant Moons thou wilt descrie
Communicating Male and Femal Light,
Which two great Sexes animate the World,
Stor'd in each Orb perhaps with some that live.
For such vast room in Nature unpossest
By living Soule, desert and desolate,
Onely to shine, yet scarce to contribute
Each Orb a glimps of Light, conveyd so farr
Down to this habitable, which returnes
Light back to them, is obvious to dispute.
But whether thus these things, or whether not,
Whether the Sun predominant in Heav'n
Rise on the Earth, or Earth rise on the Sun,
Hee from the East his flaming rode begin,
Or Shee from West her silent course advance
With inoffensive pace that spinning sleeps
On her soft Axle, while she paces Eev'n,
And bears thee soft with the smooth Air along,
Sollicit not thy thoughts with matters hid,
Leave them to God above, him serve and feare;
Of other Creatures, as him pleases best,
Wherever plac't, let him dispose: joy thou
In what he gives to thee, this Paradise
And thy faire EVE; Heav'n is for thee too high
To know what passes there; be lowlie wise:
Think onely what concernes thee and thy being;
Dream not of other Worlds, what Creatures there
Live, in what state, condition or degree,
Contented that thus farr hath been reveal'd
Not of Earth onely but of highest Heav'n.
To whom thus ADAM cleerd of doubt, repli'd.
How fully hast thou satisfi'd mee, pure
Intelligence of Heav'n, Angel serene,
And freed from intricacies, taught to live,
The easiest way, nor with perplexing thoughts
To interrupt the sweet of Life, from which
God hath bid dwell farr off all anxious cares,
And not molest us, unless we our selves
Seek them with wandring thoughts, and notions vaine.
But apt the Mind or Fancie is to roave
Uncheckt, and of her roaving is no end;
Till warn'd, or by experience taught, she learne,
That not to know at large of things remote
From use, obscure and suttle, but to know
That which before us lies in daily life,
Is the prime Wisdom, what is more, is fume,
Or emptiness, or fond impertinence,
And renders us in things that most concerne
Unpractis'd, unprepar'd, and still to seek.
Therefore from this high pitch let us descend
A lower flight, and speak of things at hand
Useful, whence haply mention may arise
Of somthing not unseasonable to ask
By sufferance, and thy wonted favour deign'd.
Thee I have heard relating what was don
Ere my remembrance: now hear mee relate
My Storie, which perhaps thou hast not heard;
And Day is yet not spent; till then thou seest
How suttly to detaine thee I devise,
Inviting thee to hear while I relate,
Fond, were it not in hope of thy reply:
For while I sit with thee, I seem in Heav'n,
And sweeter thy discourse is to my eare
Then Fruits of Palm-tree pleasantest to thirst
And hunger both, from labour, at the houre
Of sweet repast; they satiate, and soon fill,
Though pleasant, but thy words with Grace Divine
Imbu'd, bring to thir sweetness no satietie.
To whom thus RAPHAEL answer'd heav'nly meek.
Nor are thy lips ungraceful, Sire of men,
Nor tongue ineloquent; for God on thee
Abundantly his gifts hath also pour'd,
Inward and outward both, his image faire:
Speaking or mute all comliness and grace
Attends thee, and each word, each motion formes.
Nor less think wee in Heav'n of thee on Earth
Then of our fellow servant, and inquire
Gladly into the wayes of God with Man:
For God we see hath honour'd thee, and set
On Man his equal Love: say therefore on;
For I that Day was absent, as befell,
Bound on a voyage uncouth and obscure,
Farr on excursion toward the Gates of Hell;
Squar'd in full Legion (such command we had)
To see that none thence issu'd forth a spie,
Or enemie, while God was in his work,
Least hee incenst at such eruption bold,
Destruction with Creation might have mixt.
Not that they durst without his leave attempt,
But us he sends upon his high behests
For state, as Sovran King, and to enure
Our prompt obedience. Fast we found, fast shut
The dismal Gates, and barricado'd strong;
But long ere our approaching heard within
Noise, other then the sound of Dance or Song,
Torment, and lowd lament, and furious rage.
Glad we return'd up to the coasts of Light
Ere Sabbath Eev'ning: so we had in charge.
But thy relation now; for I attend,
Pleas'd with thy words no less then thou with mine.
So spake the Godlike Power, and thus our Sire.
For Man to tell how human Life began
Is hard; for who himself beginning knew?
Desire with thee still longer to converse
Induc'd me. As new wak't from soundest sleep
Soft on the flourie herb I found me laid
In Balmie Sweat, which with his Beames the Sun
Soon dri'd, and on the reaking moisture fed.
Strait toward Heav'n my wondring Eyes I turnd,
And gaz'd a while the ample Skie, till rais'd
By quick instinctive motion up I sprung,
As thitherward endevoring, and upright
Stood on my feet; about me round I saw
Hill, Dale, and shadie Woods, and sunnie Plaines,
And liquid Lapse of murmuring Streams; by these,
Creatures that livd, and movd, and walk'd, or flew,
Birds on the branches warbling; all things smil'd,
With fragrance and with joy my heart oreflow'd.
My self I then perus'd, and Limb by Limb
Survey'd, and sometimes went, and sometimes ran
With supple joints, as lively vigour led:
But who I was, or where, or from what cause,
Knew not; to speak I tri'd, and forthwith spake,
My Tongue obey'd and readily could name
What e're I saw. Thou Sun, said I, faire Light,
And thou enlight'nd Earth, so fresh and gay,
Ye Hills and Dales, ye Rivers, Woods, and Plaines,
And ye that live and move, fair Creatures, tell,
Tell, if ye saw, how came I thus, how here?
Not of my self; by some great Maker then,
In goodness and in power praeeminent;
Tell me, how may I know him, how adore,
From whom I have that thus I move and live,
And feel that I am happier then I know.
While thus I call'd, and stray'd I knew not whither,
From where I first drew Aire, and first beheld
This happie Light, when answer none return'd,
On a green shadie Bank profuse of Flours
Pensive I sate me down; there gentle sleep
First found me, and with soft oppression seis'd
My droused sense, untroubl'd, though I thought
I then was passing to my former state
Insensible, and forthwith to dissolve:
When suddenly stood at my Head a dream,
Whose inward apparition gently mov'd
My Fancy to believe I yet had being,
And livd: One came, methought, of shape Divine,
And said, thy Mansion wants thee, ADAM, rise,
First Man, of Men innumerable ordain'd
First Father, call'd by thee I come thy Guide
To the Garden of bliss, thy seat prepar'd.
So saying, by the hand he took me rais'd,
And over Fields and Waters, as in Aire
Smooth sliding without step, last led me up
A woodie Mountain; whose high top was plaine,
A Circuit wide, enclos'd, with goodliest Trees
Planted, with Walks, and Bowers, that what I saw
Of Earth before scarse pleasant seemd. Each Tree
Load'n with fairest Fruit, that hung to the Eye
Tempting, stirr'd in me sudden appetite
To pluck and eate; whereat I wak'd, and found
Before mine Eyes all real, as the dream
Had lively shadowd: Here had new begun
My wandring, had not hee who was my Guide
Up hither, from among the Trees appeer'd,
Presence Divine. Rejoycing, but with aw
In adoration at his feet I fell
Submiss: he rear'd me, & Whom thou soughtst I am,
Said mildely, Author of all this thou seest
Above, or round about thee or beneath.
This Paradise I give thee, count it thine
To Till and keep, and of the Fruit to eate:
Of every Tree that in the Garden growes
Eate freely with glad heart; fear here no dearth:
But of the Tree whose operation brings
Knowledg of good and ill, which I have set
The Pledge of thy Obedience and thy Faith,
Amid the Garden by the Tree of Life,
Remember what I warne thee, shun to taste,
And shun the bitter consequence: for know,
The day thou eat'st thereof, my sole command
Transgrest, inevitably thou shalt dye;
From that day mortal, and this happie State
Shalt loose, expell'd from hence into a World
Of woe and sorrow. Sternly he pronounc'd
The rigid interdiction, which resounds
Yet dreadful in mine eare, though in my choice
Not to incur; but soon his cleer aspect
Return'd and gratious purpose thus renew'd.
Not onely these fair bounds, but all the Earth
To thee and to thy Race I give; as Lords
Possess it, and all things that therein live,
Or live in Sea, or Aire, Beast, Fish, and Fowle.
In signe whereof each Bird and Beast behold
After thir kindes; I bring them to receave
From thee thir Names, and pay thee fealtie
With low subjection; understand the same
Of Fish within thir watry residence,
Not hither summond, since they cannot change
Thir Element to draw the thinner Aire.
As thus he spake, each Bird and Beast behold
Approaching two and two, These cowring low
With blandishment, each Bird stoop'd on his wing.
I nam'd them, as they pass'd, and understood
Thir Nature, with such knowledg God endu'd
My sudden apprehension: but in these
I found not what me thought I wanted still;
And to the Heav'nly vision thus presum'd.
O by what Name, for thou above all these,
Above mankinde, or aught then mankinde higher,
Surpassest farr my naming, how may I
Adore thee, Author of this Universe,
And all this good to man, for whose well being
So amply, and with hands so liberal
Thou hast provided all things: but with mee
I see not who partakes. In solitude
What happiness, who can enjoy alone,
Or all enjoying, what contentment find?
Thus I presumptuous; and the vision bright,
As with a smile more bright'nd, thus repli'd.
What call'st thou solitude, is not the Earth
With various living creatures, and the Aire
Replenisht, and all these at thy command
To come and play before thee, know'st thou not
Thir language and thir wayes, they also know,
And reason not contemptibly; with these
Find pastime, and beare rule; thy Realm is large.
So spake the Universal Lord, and seem'd
So ordering. I with leave of speech implor'd,
And humble deprecation thus repli'd.
Let not my words offend thee, Heav'nly Power,
My Maker, be propitious while I speak.
Hast thou not made me here thy substitute,
And these inferiour farr beneath me set?
Among unequals what societie
Can sort, what harmonie or true delight?
Which must be mutual, in proportion due
Giv'n and receiv'd; but in disparitie
The one intense, the other still remiss
Cannot well suite with either, but soon prove
Tedious alike: Of fellowship I speak
Such as I seek, fit to participate
All rational delight, wherein the brute
Cannot be human consort; they rejoyce
Each with thir kinde, Lion with Lioness;
So fitly them in pairs thou hast combin'd;
Much less can Bird with Beast, or Fish with Fowle
So well converse, nor with the Ox the Ape;
Wors then can Man with Beast, and least of all.
Whereto th' Almighty answer'd, not displeas'd.
A nice and suttle happiness I see
Thou to thy self proposest, in the choice
Of thy Associates, ADAM, and wilt taste
No pleasure, though in pleasure, solitarie.
What thinkst thou then of mee, and this my State,
Seem I to thee sufficiently possest
Of happiness, or not? who am alone
From all Eternitie, for none I know
Second to mee or like, equal much less.
How have I then with whom to hold converse
Save with the Creatures which I made, and those
To me inferiour, infinite descents
Beneath what other Creatures are to thee?
He ceas'd, I lowly answer'd. To attaine
The highth and depth of thy Eternal wayes
All human thoughts come short, Supream of things;
Thou in thy self art perfet, and in thee
Is no deficience found; not so is Man,
But in degree, the cause of his desire
By conversation with his like to help,
Or solace his defects. No need that thou
Shouldst propagat, already infinite;
And through all numbers absolute, though One;
But Man by number is to manifest
His single imperfection, and beget
Like of his like, his Image multipli'd,
In unitie defective, which requires
Collateral love, and deerest amitie.
Thou in thy secresie although alone,
Best with thy self accompanied, seek'st not
Social communication, yet so pleas'd,
Canst raise thy Creature to what highth thou wilt
Of Union or Communion, deifi'd;
I by conversing cannot these erect
From prone, nor in thir wayes complacence find.
Thus I embold'nd spake, and freedom us'd
Permissive, and acceptance found, which gain'd
This answer from the gratious voice Divine.
Thus farr to try thee, ADAM, I was pleas'd,
And finde thee knowing not of Beasts alone,
Which thou hast rightly nam'd, but of thy self,
Expressing well the spirit within thee free,
My Image, not imparted to the Brute,
Whose fellowship therefore unmeet for thee
Good reason was thou freely shouldst dislike,
And be so minded still; I, ere thou spak'st,
Knew it not good for Man to be alone,
And no such companie as then thou saw'st
Intended thee, for trial onely brought,
To see how thou could'st judge of fit and meet:
What next I bring shall please thee, be assur'd,
Thy likeness, thy fit help, thy other self,
Thy wish, exactly to thy hearts desire.
Hee ended, or I heard no more, for now
My earthly by his Heav'nly overpowerd,
Which it had long stood under, streind to the highth
In that celestial Colloquie sublime,
As with an object that excels the sense,
Dazl'd and spent, sunk down, and sought repair
Of sleep, which instantly fell on me, call'd
By Nature as in aide, and clos'd mine eyes.
Mine eyes he clos'd, but op'n left the Cell
Of Fancie my internal sight, by which
Abstract as in a transe methought I saw,
Though sleeping, where I lay, and saw the shape
Still glorious before whom awake I stood;
Who stooping op'nd my left side, and took
From thence a Rib, with cordial spirits warme,
And Life-blood streaming fresh; wide was the wound,
But suddenly with flesh fill'd up & heal'd:
The Rib he formd and fashond with his hands;
Under his forming hands a Creature grew,
Manlike, but different sex, so lovly faire,
That what seemd fair in all the World, seemd now
Mean, or in her summd up, in her containd
And in her looks, which from that time infus'd
Sweetness into my heart, unfelt before,
And into all things from her Aire inspir'd
The spirit of love and amorous delight.
She disappeerd, and left me dark, I wak'd
To find her, or for ever to deplore
Her loss, and other pleasures all abjure:
When out of hope, behold her, not farr off,
Such as I saw her in my dream, adornd
With what all Earth or Heaven could bestow
To make her amiable: On she came,
Led by her Heav'nly Maker, though unseen,
And guided by his voice, nor uninformd
Of nuptial Sanctitie and marriage Rites:
Grace was in all her steps, Heav'n in her Eye,
In every gesture dignitie and love.
I overjoyd could not forbear aloud.
This turn hath made amends; thou hast fulfill'd
Thy words, Creator bounteous and benigne,
Giver of all things faire, but fairest this
Of all thy gifts, nor enviest. I now see
Bone of my Bone, Flesh of my Flesh, my Self
Before me; Woman is her Name, of Man
Extracted; for this cause he shall forgoe
Father and Mother, and to his Wife adhere;
And they shall be one Flesh, one Heart, one Soule.
She heard me thus, and though divinely brought,
Yet Innocence and Virgin Modestie,
Her vertue and the conscience of her worth,
That would be woo'd, and not unsought be won,
Not obvious, not obtrusive, but retir'd,
The more desirable, or to say all,
Nature her self, though pure of sinful thought,
Wrought in her so, that seeing me, she turn'd;
I follow'd her, she what was Honour knew,
And with obsequious Majestie approv'd
My pleaded reason. To the Nuptial Bowre
I led her blushing like the Morn: all Heav'n,
And happie Constellations on that houre
Shed thir selectest influence; the Earth
Gave sign of gratulation, and each Hill;
Joyous the Birds; fresh Gales and gentle Aires
Whisper'd it to the Woods, and from thir wings
Flung Rose, flung Odours from the spicie Shrub,
Disporting, till the amorous Bird of Night
Sung Spousal, and bid haste the Eevning Starr
On his Hill top, to light the bridal Lamp.
Thus I have told thee all my State, and brought
My Storie to the sum of earthly bliss
Which I enjoy, and must confess to find
In all things else delight indeed, but such
As us'd or not, works in the mind no change,
Nor vehement desire, these delicacies
I mean of Taste, Sight, Smell, Herbs, Fruits, & Flours,
Walks, and the melodie of Birds; but here
Farr otherwise, transported I behold,
Transported touch; here passion first I felt,
Commotion strange, in all enjoyments else
Superiour and unmov'd, here onely weake
Against the charm of Beauties powerful glance.
Or Nature faild in mee, and left some part
Not proof enough such Object to sustain,
Or from my side subducting, took perhaps
More then enough; at least on her bestow'd
Too much of Ornament, in outward shew
Elaborate, of inward less exact.
For well I understand in the prime end
Of Nature her th' inferiour, in the mind
And inward Faculties, which most excell,
In outward also her resembling less
His Image who made both, and less expressing
The character of that Dominion giv'n
O're other Creatures; yet when I approach
Her loveliness, so absolute she seems
And in her self compleat, so well to know
Her own, that what she wills to do or say,
Seems wisest, vertuousest, discreetest, best;
All higher knowledge in her presence falls
Degraded, Wisdom in discourse with her
Looses discount'nanc't, and like folly shewes;
Authoritie and Reason on her waite,
As one intended first, not after made
Occasionally; and to consummate all,
Greatness of mind and nobleness thir seat
Build in her loveliest, and create an awe
About her, as a guard Angelic plac't.
To whom the Angel with contracted brow.
Accuse not Nature, she hath don her part;
Do thou but thine, and be not diffident
Of Wisdom, she deserts thee not, if thou
Dismiss not her, when most thou needst her nigh,
By attributing overmuch to things
Less excellent, as thou thy self perceav'st.
For what admir'st thou, what transports thee so,
An outside? fair no doubt, and worthy well
Thy cherishing, thy honouring, and thy love,
Not thy subjection: weigh with her thy self;
Then value: Oft times nothing profits more
Then self-esteem, grounded on just and right
Well manag'd; of that skill the more thou know'st,
The more she will acknowledge thee her Head,
And to realities yeild all her shows;
Made so adorn for thy delight the more,
So awful, that with honour thou maist love
Thy mate, who sees when thou art seen least wise.
But if the sense of touch whereby mankind
Is propagated seem such dear delight
Beyond all other, think the same voutsaf't
To Cattel and each Beast; which would not be
To them made common & divulg'd, if aught
Therein enjoy'd were worthy to subdue
The Soule of Man, or passion in him move.
What higher in her societie thou findst
Attractive, human, rational, love still;
In loving thou dost well, in passion not,
Wherein true Love consists not; love refines
The thoughts, and heart enlarges, hath his seat
In Reason, and is judicious, is the scale
By which to heav'nly Love thou maist ascend,
Not sunk in carnal pleasure, for which cause
Among the Beasts no Mate for thee was found.
To whom thus half abash't ADAM repli'd.
Neither her out-side formd so fair, nor aught
In procreation common to all kindes
(Though higher of the genial Bed by far,
And with mysterious reverence I deem)
So much delights me, as those graceful acts,
Those thousand decencies that daily flow
From all her words and actions, mixt with Love
And sweet compliance, which declare unfeign'd
Union of Mind, or in us both one Soule;
Harmonie to behold in wedded pair
More grateful then harmonious sound to the eare.
Yet these subject not; I to thee disclose
What inward thence I feel, not therefore foild,
Who meet with various objects, from the sense
Variously representing; yet still free
Approve the best, and follow what I approve.
To love thou blam'st me not, for love thou saist
Leads up to Heav'n, is both the way and guide;
Bear with me then, if lawful what I ask;
Love not the heav'nly Spirits, and how thir Love
Express they, by looks onely, or do they mix
Irradiance, virtual or immediate touch?
To whom the Angel with a smile that glow'd
Celestial rosie red, Loves proper hue,
Answer'd. Let it suffice thee that thou know'st
Us happie, and without Love no happiness.
Whatever pure thou in the body enjoy'st
(And pure thou wert created) we enjoy
In eminence, and obstacle find none
Of membrane, joynt, or limb, exclusive barrs:
Easier then Air with Air, if Spirits embrace,
Total they mix, Union of Pure with Pure
Desiring; nor restrain'd conveyance need
As Flesh to mix with Flesh, or Soul with Soul.
But I can now no more; the parting Sun
Beyond the Earths green Cape and verdant Isles
HESPEREAN sets, my Signal to depart.
Be strong, live happie, and love, but first of all
Him whom to love is to obey, and keep
His great command; take heed least Passion sway
Thy Judgement to do aught, which else free Will
Would not admit; thine and of all thy Sons
The weal or woe in thee is plac't; beware.
I in thy persevering shall rejoyce,
And all the Blest: stand fast; to stand or fall
Free in thine own Arbitrement it lies.
Perfet within, no outward aid require;
And all temptation to transgress repel.
So saying, he arose; whom ADAM thus
Follow'd with benediction. Since to part,
Go heavenly Guest, Ethereal Messenger,
Sent from whose sovran goodness I adore.
Gentle to me and affable hath been
Thy condescension, and shall be honour'd ever
With grateful Memorie: thou to mankind
Be good and friendly still, and oft return.
So parted they, the Angel up to Heav'n
From the thick shade, and ADAM to his Bowre.
THE END OF THE SEVENTH BOOK.
PARADISE LOST
BOOK VIII.
No more of talk where God or Angel Guest
With Man, as with his Friend, familiar us'd
To sit indulgent, and with him partake
Rural repast, permitting him the while
Venial discourse unblam'd: I now must change
Those Notes to Tragic; foul distrust, and breach
Disloyal on the part of Man, revolt
And disobedience: On the part of Heav'n
Now alienated, distance and distaste,
Anger and just rebuke, and judgement giv'n,
That brought into this World a world of woe,
Sinne and her shadow Death, and Miserie
Deaths Harbinger: Sad task, yet argument
Not less but more Heroic then the wrauth
Of stern ACHILLES on his Foe pursu'd
Thrice Fugitive about TROY Wall; or rage
Of TURNUS for LAVINIA disespous'd,
Or NEPTUN'S ire or JUNO'S, that so long
Perplex'd the GREEK and CYTHEREA'S Son;
If answerable style I can obtaine
Of my Celestial Patroness, who deignes
Her nightly visitation unimplor'd,
And dictates to me slumbring, or inspires
Easie my unpremeditated Verse:
Since first this subject for Heroic Song
Pleas'd me long choosing, and beginning late;
Not sedulous by Nature to indite
Warrs, hitherto the onely Argument
Heroic deem'd, chief maistrie to dissect
With long and tedious havoc fabl'd Knights
In Battels feign'd; the better fortitude
Of Patience and Heroic Martyrdom
Unsung; or to describe Races and Games,
Or tilting Furniture, emblazon'd Shields,
Impreses quaint, Caparisons and Steeds;
Bases and tinsel Trappings, gorgious Knights
At Joust and Torneament; then marshal'd Feast
Serv'd up in Hall with Sewers, and Seneshals;
The skill of Artifice or Office mean,
Not that which justly gives Heroic name
To Person or to Poem. Mee of these
Nor skilld nor studious, higher Argument
Remaines, sufficient of it self to raise
That name, unless an age too late, or cold
Climat, or Years damp my intended wing
Deprest, and much they may, if all be mine,
Not Hers who brings it nightly to my Ear.
The Sun was sunk, and after him the Starr
Of HESPERUS, whose Office is to bring
Twilight upon the Earth, short Arbiter
Twixt Day and Night, and now from end to end
Nights Hemisphere had veild the Horizon round:
When SATAN who late fled before the threats
Of GABRIEL out of EDEN, now improv'd
In meditated fraud and malice, bent
On mans destruction, maugre what might hap
Of heavier on himself, fearless return'd.
By Night he fled, and at Midnight return'd
From compassing the Earth, cautious of day,
Since URIEL Regent of the Sun descri'd
His entrance, and forewarnd the Cherubim
That kept thir watch; thence full of anguish driv'n,
The space of seven continu'd Nights he rode
With darkness, thrice the Equinoctial Line
He circl'd, four times cross'd the Carr of Night
From Pole to Pole, traversing each Colure;
On the eighth return'd, and on the Coast averse
From entrance or Cherubic Watch, by stealth
Found unsuspected way. There was a place,
Now not, though Sin, not Time, first wraught the change,
Where TIGRIS at the foot of Paradise
Into a Gulf shot under ground, till part
Rose up a Fountain by the Tree of Life;
In with the River sunk, and with it rose
Satan involv'd in rising Mist, then sought
Where to lie hid; Sea he had searcht and Land
From EDEN over PONTUS, and the Poole
MAEOTIS, up beyond the River OB;
Downward as farr Antartic; and in length
West from ORANTES to the Ocean barr'd
At DARIEN, thence to the Land where flowes
GANGES and INDUS: thus the Orb he roam'd
With narrow search; and with inspection deep
Consider'd every Creature, which of all
Most opportune might serve his Wiles, and found
The Serpent suttlest Beast of all the Field.
Him after long debate, irresolute
Of thoughts revolv'd, his final sentence chose
Fit Vessel, fittest Imp of fraud, in whom
To enter, and his dark suggestions hide
From sharpest sight: for in the wilie Snake,
Whatever sleights none would suspicious mark,
As from his wit and native suttletie
Proceeding, which in other Beasts observ'd
Doubt might beget of Diabolic pow'r
Active within beyond the sense of brute.
Thus he resolv'd, but first from inward griefe
His bursting passion into plaints thus pour'd:
O Earth, how like to Heav'n, if not preferrd
More justly, Seat worthier of Gods, as built
With second thoughts, reforming what was old!
For what God after better worse would build?
Terrestrial Heav'n, danc't round by other Heav'ns
That shine, yet bear thir bright officious Lamps,
Light above Light, for thee alone, as seems,
In thee concentring all thir precious beams
Of sacred influence: As God in Heav'n
Is Center, yet extends to all, so thou
Centring receav'st from all those Orbs; in thee,
Not in themselves, all thir known vertue appeers
Productive in Herb, Plant, and nobler birth
Of Creatures animate with gradual life
Of Growth, Sense, Reason, all summ'd up in Man.
With what delight could I have walkt thee round
If I could joy in aught, sweet interchange
Of Hill and Vallie, Rivers, Woods and Plaines,
Now Land, now Sea, & Shores with Forrest crownd,
Rocks, Dens, and Caves; but I in none of these
Find place or refuge; and the more I see
Pleasures about me, so much more I feel
Torment within me, as from the hateful siege
Of contraries; all good to me becomes
Bane, and in Heav'n much worse would be my state.
But neither here seek I, no nor in Heav'n
To dwell, unless by maistring Heav'ns Supreame;
Nor hope to be my self less miserable
By what I seek, but others to make such
As I though thereby worse to me redound:
For onely in destroying I finde ease
To my relentless thoughts; and him destroyd,
Or won to what may work his utter loss,
For whom all this was made, all this will soon
Follow, as to him linkt in weal or woe,
In wo then; that destruction wide may range:
To mee shall be the glorie sole among
The infernal Powers, in one day to have marr'd
What he ALMIGHTIE styl'd, six Nights and Days
Continu'd making, and who knows how long
Before had bin contriving, though perhaps
Not longer then since I in one Night freed
From servitude inglorious welnigh half
Th' Angelic Name, and thinner left the throng
Of his adorers: hee to be aveng'd,
And to repaire his numbers thus impair'd,
Whether such vertue spent of old now faild
More Angels to Create, if they at least
Are his Created or to spite us more,
Determin'd to advance into our room
A Creature form'd of Earth, and him endow,
Exalted from so base original,
With Heav'nly spoils, our spoils: What he decreed
He effected; Man he made, and for him built
Magnificent this World, and Earth his seat,
Him Lord pronounc'd, and, O indignitie!
Subjected to his service Angel wings,
And flaming Ministers to watch and tend
Thir earthlie Charge: Of these the vigilance
I dread, and to elude, thus wrapt in mist
Of midnight vapor glide obscure, and prie
In every Bush and Brake, where hap may finde
The Serpent sleeping, in whose mazie foulds
To hide me, and the dark intent I bring.
O foul descent! that I who erst contended
With Gods to sit the highest, am now constraind
Into a Beast, and mixt with bestial slime,
This essence to incarnate and imbrute,
That to the hight of Deitie aspir'd;
But what will not Ambition and Revenge
Descend to? who aspires must down as low
As high he soard, obnoxious first or last
To basest things. Revenge, at first though sweet,
Bitter ere long back on it self recoiles;
Let it; I reck not, so it light well aim'd,
Since higher I fall short, on him who next
Provokes my envie, this new Favorite
Of Heav'n, this Man of Clay, Son of despite,
Whom us the more to spite his Maker rais'd
From dust: spite then with spite is best repaid.
So saying, through each Thicket Danck or Drie,
Like a black mist low creeping, he held on
His midnight search, where soonest he might finde
The Serpent: him fast sleeping soon he found
In Labyrinth of many a round self-rowl'd,
His head the midst, well stor'd with suttle wiles:
Not yet in horrid Shade or dismal Den,
Not nocent yet, but on the grassie Herbe
Fearless unfeard he slept: in at his Mouth
The Devil enterd, and his brutal sense,
In heart or head, possessing soon inspir'd
With act intelligential; but his sleep
Disturbd not, waiting close th' approach of Morn.
Now whenas sacred Light began to dawne
In EDEN on the humid Flours, that breathd
Thir morning Incense, when all things that breath,
From th' Earths great Altar send up silent praise
To the Creator, and his Nostrils fill
With gratefull Smell, forth came the human pair
And joynd thir vocal Worship to the Quire
Of Creatures wanting voice, that done, partake
The season, prime for sweetest Sents and Aires:
Then commune how that day they best may ply
Thir growing work: for much thir work outgrew
The hands dispatch of two Gardning so wide.
And EVE first to her Husband thus began.
ADAM, well may we labour still to dress
This Garden, still to tend Plant, Herb and Flour.
Our pleasant task enjoyn'd, but till more hands
Aid us, the work under our labour grows,
Luxurious by restraint; what we by day
Lop overgrown, or prune, or prop, or bind,
One night or two with wanton growth derides
Tending to wilde. Thou therefore now advise
Or hear what to my mind first thoughts present,
Let us divide our labours, thou where choice
Leads thee, or where most needs, whether to wind
The Woodbine round this Arbour, or direct
The clasping Ivie where to climb, while I
In yonder Spring of Roses intermixt
With Myrtle, find what to redress till Noon:
For while so near each other thus all day
Our task we choose, what wonder if no near
Looks intervene and smiles, or object new
Casual discourse draw on, which intermits
Our dayes work brought to little, though begun
Early, and th' hour of Supper comes unearn'd.
To whom mild answer ADAM thus return'd.
Sole EVE, Associate sole, to me beyond
Compare above all living Creatures deare,
Well hast thou motion'd, wel thy thoughts imployd
How we might best fulfill the work which here
God hath assign'd us, nor of me shalt pass
Unprais'd: for nothing lovelier can be found
In woman, then to studie houshold good,
And good workes in her Husband to promote.
Yet not so strictly hath our Lord impos'd
Labour, as to debarr us when we need
Refreshment, whether food, or talk between,
Food of the mind, or this sweet intercourse
Of looks and smiles, for smiles from Reason flow,
To brute deni'd, and are of Love the food,
Love not the lowest end of human life.
For not to irksom toile, but to delight
He made us, and delight to Reason joyn'd.
These paths and Bowers doubt not but our joynt
Will keep from Wilderness with ease, as wide
As we need walk, till younger hands ere long
Assist us: But if much converse perhaps
Thee satiate, to short absence I could yeild.
For solitude somtimes is best societie,
And short retirement urges sweet returne.
But other doubt possesses me, least harm
Befall thee sever'd from me; for thou knowst
What hath bin warn'd us, what malicious Foe
Envying our happiness, and of his own
Despairing, seeks to work us woe and shame
By sly assault; and somwhere nigh at hand
Watches, no doubt, with greedy hope to find
His wish and best advantage, us asunder,
Hopeless to circumvent us joynd, where each
To other speedie aide might lend at need;
Whether his first design be to withdraw
Our fealtie from God, or to disturb
Conjugal Love, then which perhaps no bliss
Enjoy'd by us excites his envie more;
Or this, or worse, leave not the faithful side
That gave thee being, stil shades thee and protects.
The Wife, where danger or dishonour lurks,
Safest and seemliest by her Husband staies,
Who guards her, or with her the worst endures.
To whom the Virgin Majestie of EVE,
As one who loves, and some unkindness meets,
With sweet austeer composure thus reply'd.
Ofspring of Heav'n and Earth, and all Earths Lord,
That such an enemie we have, who seeks
Our ruin, both by thee informd I learne,
And from the parting Angel over-heard
As in a shadie nook I stood behind,
Just then returnd at shut of Evening Flours.
But that thou shouldst my firmness therefore doubt
To God or thee, because we have a foe
May tempt it, I expected not to hear.
His violence thou fearst not, being such,
As wee, not capable of death or paine,
Can either not receave, or can repell.
His fraud is then thy fear, which plain inferrs
Thy equal fear that my firm Faith and Love
Can by his fraud be shak'n or seduc't;
Thoughts, which how found they harbour in thy Brest,
ADAM, misthought of her to thee so dear?
To whom with healing words ADAM reply'd.
Daughter of God and Man, immortal EVE,
For such thou art, from sin and blame entire:
Not diffident of thee do I dissuade
Thy absence from my sight, but to avoid
Th' attempt it self, intended by our Foe.
For hee who tempts, though in vain, at least asperses
The tempted with dishonour foul, suppos'd
Not incorruptible of Faith, not prooff
Against temptation: thou thy self with scorne
And anger wouldst resent the offer'd wrong,
Though ineffectual found: misdeem not then,
If such affront I labour to avert
From thee alone, which on us both at once
The Enemie, though bold, will hardly dare,
Or daring, first on mee th' assault shall light.
Nor thou his malice and false guile contemn;
Suttle he needs must be, who could seduce
Angels, nor think superfluous others aid.
I from the influence of thy looks receave
Access in every Vertue, in thy sight
More wise, more watchful, stronger, if need were
Of outward strength; while shame, thou looking on,
Shame to be overcome or over-reacht
Would utmost vigor raise, and rais'd unite.
Why shouldst not thou like sense within thee feel
When I am present, and thy trial choose
With me, best witness of thy Vertue tri'd.
So spake domestick ADAM in his care
And Matrimonial Love, but EVE, who thought
Less attributed to her Faith sincere,
Thus her reply with accent sweet renewd.
If this be our condition, thus to dwell
In narrow circuit strait'nd by a Foe,
Suttle or violent, we not endu'd
Single with like defence, wherever met,
How are we happie, still in fear of harm?
But harm precedes not sin: onely our Foe
Tempting affronts us with his foul esteem
Of our integritie: his foul esteeme
Sticks no dishonor on our Front, but turns
Foul on himself; then wherfore shund or feard
By us? who rather double honour gaine
From his surmise prov'd false, finde peace within,
Favour from Heav'n, our witness from th' event.
And what is Faith, Love, Vertue unassaid
Alone, without exterior help sustaind?
Let us not then suspect our happie State
Left so imperfet by the Maker wise,
As not secure to single or combin'd.
Fraile is our happiness, if this be so,
And EDEN were no EDEN thus expos'd.
To whom thus ADAM fervently repli'd.
O Woman, best are all things as the will
Of God ordaind them, his creating hand
Nothing imperfet or deficient left
Of all that he Created, much less Man,
Or ought that might his happie State secure,
Secure from outward force; within himself
The danger lies, yet lies within his power:
Against his will he can receave no harme.
But God left free the Will, for what obeyes
Reason, is free, and Reason he made right,
But bid her well beware, and still erect,
Least by some faire appeering good surpris'd
She dictate false, and missinforme the Will
To do what God expresly hath forbid.
Not then mistrust, but tender love enjoynes,
That I should mind thee oft, and mind thou me.
Firm we subsist, yet possible to swerve,
Since Reason not impossibly may meet
Some specious object by the Foe subornd,
And fall into deception unaware,
Not keeping strictest watch, as she was warnd.
Seek not temptation then, which to avoide
Were better, and most likelie if from mee
Thou sever not; Trial will come unsought.
Wouldst thou approve thy constancie, approve
First thy obedience; th' other who can know,
Not seeing thee attempted, who attest?
But if thou think, trial unsought may finde
Us both securer then thus warnd thou seemst,
Go; for thy stay, not free, absents thee more;
Go in thy native innocence, relie
On what thou hast of vertue, summon all,
For God towards thee hath done his part, do thine.
So spake the Patriarch of Mankinde, but EVE
Persisted, yet submiss, though last, repli'd.
With thy permission then, and thus forewarnd
Chiefly by what thy own last reasoning words
Touchd onely, that our trial, when least sought,
May finde us both perhaps farr less prepar'd,
The willinger I goe, nor much expect
A Foe so proud will first the weaker seek;
So bent, the more shall shame him his repulse.
Thus saying, from her Husbands hand her hand
Soft she withdrew, and like a Wood-Nymph light
OREAD or DRYAD, or of DELIA's Traine,
Betook her to the Groves, but DELIA's self
In gate surpass'd and Goddess-like deport,
Though not as shee with Bow and Quiver armd,
But with such Gardning Tools as Are yet rude,
Guiltless of fire had formd, or Angels brought,
To PALES, or POMONA, thus adornd,
Likest she seemd, POMONA when she fled
VERTUMNUS, or to CERES in her Prime,
Yet Virgin of PROSERPINA from JOVE.
Her long with ardent look his EYE pursu'd
Delighted, but desiring more her stay.
Oft he to her his charge of quick returne,
Repeated, shee to him as oft engag'd
To be returnd by Noon amid the Bowre,
And all things in best order to invite
Noontide repast, or Afternoons repose.
O much deceav'd, much failing, hapless EVE,
Of thy presum'd return! event perverse!
Thou never from that houre in Paradise
Foundst either sweet repast, or found repose;
Such ambush hid among sweet Flours and Shades
Waited with hellish rancor imminent
To intercept thy way, or send thee back
Despoild of Innocence, of Faith, of Bliss.
For now, and since first break of dawne the Fiend,
Meer Serpent in appearance, forth was come,
And on his Quest, where likeliest he might finde
The onely two of Mankinde, but in them
The whole included Race, his purposd prey.
In Bowre and Field he sought, where any tuft
Of Grove or Garden-Plot more pleasant lay,
Thir tendance or Plantation for delight,
By Fountain or by shadie Rivulet
He sought them both, but wish'd his hap might find
EVE separate, he wish'd, but not with hope
Of what so seldom chanc'd, when to his wish,
Beyond his hope, EVE separate he spies,
Veild in a Cloud of Fragrance, where she stood,
Half spi'd, so thick the Roses bushing round
About her glowd, oft stooping to support
Each Flour of slender stalk, whose head though gay
Carnation, Purple, Azure, or spect with Gold,
Hung drooping unsustaind, them she upstaies
Gently with Mirtle band, mindless the while,
Her self, though fairest unsupported Flour,
From her best prop so farr, and storn so nigh.
Neererhe drew, and many a walk travers'd
Of stateliest Covert, Cedar, Pine, or Palme,
Then voluble and bold, now hid, now seen
Among thick-wov'n Arborets and Flours
Imborderd on each Bank, the hand of EVE:
Spot more delicious then those Gardens feign'd
Or of reviv'd ADONIS, or renownd
ALCINOUS, host of old LAERTES Son,
Or that, not Mystic, where the Sapient King
Held dalliance with his faire EGYPTIAN Spouse.
Much hee the Place admir'd, the Person more.
As one who long in populous City pent,
Where Houses thick and Sewers annoy the Aire,
Forth issuing on a Summers Morn, to breathe
Among the pleasant Villages and Farmes
Adjoynd, from each thing met conceaves delight,
The smell of Grain, or tedded Grass, or Kine,
Or Dairie, each rural sight, each rural sound;
If chance with Nymphlike step fair Virgin pass,
What pleasing seemd, for her now pleases more,
She most, and in her look summs all Delight.
Such Pleasure took the Serpent to behold
This Flourie Plat, the sweet recess of EVE
Thus earlie, thus alone; her Heav'nly forme
Angelic, but more soft, and Feminine,
Her graceful Innocence, her every Aire
Of gesture or lest action overawd
His Malice, and with rapine sweet bereav'd
His fierceness of the fierce intent it brought:
That space the Evil one abstracted stood
From his own evil, and for the time remaind
Stupidly good, of enmitie disarm'd,
Of guile, of hate, of envie, of revenge;
But the hot Hell that alwayes in him burnes,
Though in mid Heav'n, soon ended his delight,
And tortures him now more, the more he sees
Of pleasure not for him ordain'd: then soon
Fierce hate he recollects, and all his thoughts
Of mischief, gratulating, thus excites.
Thoughts, whither have he led me, with what sweet
Compulsion thus transported to forget
What hither brought us, hate, not love, nor hope
Of Paradise for Hell, hope here to taste
Of pleasure, but all pleasure to destroy,
Save what is in destroying, other joy
To me is lost. Then let me not let pass
Occasion which now smiles, behold alone
The Woman, opportune to all attempts,
Her Husband, for I view far round, not nigh,
Whose higher intellectual more I shun,
And strength, of courage hautie, and of limb
Heroic built, though of terrestrial mould,
Foe not informidable, exempt from wound,
I not; so much hath Hell debas'd, and paine
Infeebl'd me, to what I was in Heav'n.
Shee fair, divinely fair, fit Love for Gods,
Not terrible, though terrour be in Love
And beautie, not approacht by stronger hate,
Hate stronger, under shew of Love well feign'd,
The way which to her ruin now I tend.
So spake the Enemie of Mankind, enclos'd
In Serpent, Inmate bad, and toward EVE
Address'd his way, not with indented wave,
Prone on the ground, as since, but on his reare,
Circular base of rising foulds, that tour'd
Fould above fould a surging Maze, his Head
Crested aloft, and Carbuncle his Eyes;
With burnisht Neck of verdant Gold, erect
Amidst his circling Spires, that on the grass
Floted redundant: pleasing was his shape,
And lovely, never since of Serpent kind
Lovelier, not those that in ILLYRIA chang'd
HERMIONE and CADMUS, or the God
In EPIDAURUS; nor to which transformd
AMMONIAN JOVE, or CAPITOLINE was seen,
Hee with OLYMPIAS, this with her who bore
SCIPIO the highth of ROME. With tract oblique
At first, as one who sought access, but feard
To interrupt, side-long he works his way.
As when a Ship by skilful Stearsman wrought
Nigh Rivers mouth or Foreland, where the Wind
Veres oft, as oft so steers, and shifts her Saile;
So varied hee, and of his tortuous Traine
Curld many a wanton wreath in sight of EVE,
To lure her Eye; shee busied heard the sound
Of rusling Leaves, but minded not, as us'd
To such disport before her through the Field,
From every Beast, more duteous at her call,
Then at CIRCEAN call the Herd disguis'd.
Hee boulder now, uncall'd before her stood;
But as in gaze admiring: Oft he bowd
His turret Crest, and sleek enamel'd Neck,
Fawning, and lick'd the ground whereon she trod.
His gentle dumb expression turnd at length
The Eye of EVE to mark his play; he glad
Of her attention gaind, with Serpent Tongue
Organic, or impulse of vocal Air,
His fraudulent temptation thus began.
Wonder not, sovran Mistress, if perhaps
Thou canst, who art sole Wonder, much less arm
Thy looks, the Heav'n of mildness, with disdain,
Displeas'd that I approach thee thus, and gaze
Insatiate, I thus single; nor have feard
Thy awful brow, more awful thus retir'd.
Fairest resemblance of thy Maker faire,
Thee all living things gaze on, all things thine
By gift, and thy Celestial Beautie adore
With ravishment beheld, there best beheld
Where universally admir'd; but here
In this enclosure wild, these Beasts among,
Beholders rude, and shallow to discerne
Half what in thee is fair, one man except,
Who sees thee? (and what is one?) who shouldst be seen
A Goddess among Gods, ador'd and serv'd
By Angels numberless, thy daily Train.
So gloz'd the Tempter, and his Proem tun'd;
Into the Heart of EVE his words made way,
Though at the voice much marveling; at length
Not unamaz'd she thus in answer spake.
What may this mean? Language of Man pronounc't
By Tongue of Brute, and human sense exprest?
The first at lest of these I thought deni'd
To Beasts, whom God on their Creation-Day
Created mute to all articulat sound;
The latter I demurre, for in thir looks
Much reason, and in thir actions oft appeers.
Thee, Serpent, suttlest beast of all the field
I knew, but not with human voice endu'd;
Redouble then this miracle, and say,
How cam'st thou speakable of mute, and how
To me so friendly grown above the rest
Of brutal kind, that daily are in sight?
Say, for such wonder claims attention due.
To whom the guileful Tempter thus reply'd.
Empress of this fair World, resplendent EVE,
Easie to mee it is to tell thee all
What thou commandst, and right thou shouldst be obeyd:
I was at first as other Beasts that graze
The trodden Herb, of abject thoughts and low,
As was my food, nor aught but food discern'd
Or Sex, and apprehended nothing high:
Till on a day roaving the field, I chanc'd
A goodly Tree farr distant to behold
Loaden with fruit of fairest colours mixt,
Ruddie and Gold: I nearer drew to gaze;
When from the boughes a savorie odour blow'n,
Grateful to appetite, more pleas'd my sense
Then smell of sweetest Fenel, or the Teats
Of Ewe or Goat dropping with Milk at Eevn,
Unsuckt of Lamb or Kid, that tend thir play.
To satisfie the sharp desire I had
Of tasting those fair Apples, I resolv'd
Not to deferr; hunger and thirst at once,
Powerful perswaders, quick'nd at the scent
Of that alluring fruit, urg'd me so keene.
About the Mossie Trunk I wound me soon,
For high from ground the branches would require
Thy utmost reach or ADAMS: Round the Tree
All other Beasts that saw, with like desire
Longing and envying stood, but could not reach.
Amid the Tree now got, where plentie hung
Tempting so nigh, to pluck and eat my fill
I spar'd not, for such pleasure till that hour
At Feed or Fountain never had I found.
Sated at length, ere long I might perceave
Strange alteration in me, to degree
Of Reason in my inward Powers, and Speech
Wanted not long, though to this shape retaind.
Thenceforth to Speculations high or deep
I turnd my thoughts, and with capacious mind
Considerd all things visible in Heav'n,
Or Earth, or Middle, all things fair and good;
But all that fair and good in thy Divine
Semblance, and in thy Beauties heav'nly Ray
United I beheld; no Fair to thine
Equivalent or second, which compel'd
Mee thus, though importune perhaps, to come
And gaze, and worship thee of right declar'd
Sovran of Creatures, universal Dame.
So talk'd the spirited sly Snake; and EVE
Yet more amaz'd unwarie thus reply'd.
Serpent, thy overpraising leaves in doubt
The vertue of that Fruit, in thee first prov'd:
But say, where grows the Tree, from hence how far?
For many are the Trees of God that grow
In Paradise, and various, yet unknown
To us, in such abundance lies our choice,
As leaves a greater store of Fruit untoucht,
Still hanging incorruptible, till men
Grow up to thir provision, and more hands
Help to disburden Nature of her Bearth.
To whom the wilie Adder, blithe and glad.
Empress, the way is readie, and not long,
Beyond a row of Myrtles, on a Flat,
Fast by a Fountain, one small Thicket past
Of blowing Myrrh and Balme; if thou accept
My conduct, I can bring thee thither soon.
Lead then, said EVE. Hee leading swiftly rowld
In tangles, and make intricate seem strait,
To mischief swift. Hope elevates, and joy
Bright'ns his Crest, as when a wandring Fire
Compact of unctuous vapor, which the Night
Condenses, and the cold invirons round,
Kindl'd through agitation to a Flame,
Which oft, they say, some evil Spirit attends,
Hovering and blazing with delusive Light,
Misleads th' amaz'd Night-wanderer from his way
To Boggs and Mires, & oft through Pond or Poole,
There swallow'd up and lost, from succour farr.
So glister'd the dire Snake and into fraud
Led EVE our credulous Mother, to the Tree
Of prohibition, root of all our woe;
Which when she saw, thus to her guide she spake.
Serpent, we might have spar'd our coming hither,
Fruitless to me, though Fruit be here to excess,
The credit of whose vertue rest with thee,
Wondrous indeed, if cause of such effects.
But of this Tree we may not taste nor touch;
God so commanded, and left that Command
Sole Daughter of his voice; the rest, we live
Law to our selves, our Reason is our Law.
To whom the Tempter guilefully repli'd.
Indeed? hath God then said that of the Fruit
Of all these Garden Trees ye shall not eate,
Yet Lords declar'd of all in Earth or Aire?
To whom thus EVE yet sinless. Of the Fruit
Of each Tree in the Garden we may eate,
But of the Fruit of this fair Tree amidst
The Garden, God hath said, Ye shall not eate
Thereof, nor shall ye touch it, least ye die.
She scarse had said, though brief, when now more bold
The Tempter, but with shew of Zeale and Love
To Man, and indignation at his wrong,
New part puts on, and as to passion mov'd,
Fluctuats disturbd, yet comely, and in act
Rais'd, as of som great matter to begin.
As when of old som Orator renound
In ATHENS or free ROME, where Eloquence
Flourishd, since mute, to som great cause addrest,
Stood in himself collected, while each part,
Motion, each act won audience ere the tongue,
Somtimes in highth began, as no delay
Of Preface brooking through his Zeal of Right.
So standing, moving, or to highth upgrown
The Tempter all impassiond thus began.
O Sacred, Wise, and Wisdom-giving Plant,
Mother of Science, Now I feel thy Power
Within me cleere, not onely to discerne
Things in thir Causes, but to trace the wayes
Of highest Agents, deemd however wise.
Queen of this Universe, doe not believe
Those rigid threats of Death; ye shall not Die:
How should ye? by the Fruit? it gives you Life
To Knowledge? By the Threatner, look on mee,
Mee who have touch'd and tasted, yet both live,
And life more perfet have attaind then Fate
Meant mee, by ventring higher then my Lot.
Shall that be shut to Man, which to the Beast
Is open? or will God incense his ire
For such a pretty Trespass, and not praise
Rather your dauntless vertue, whom the pain
Of Death denounc't, whatever thing Death be,
Deterrd not from atchieving what might leade
To happier life, knowledge of Good and Evil;
Of good, how just? of evil, if what is evil
Be real, why not known, since easier shunnd?
God therefore cannot hurt ye, and be just;
Not just, not God; not feard then, nor obeid:
Your feare it self of Death removes the feare.
Why then was this forbid? Why but to awe,
Why but to keep ye low and ignorant,
His worshippers; he knows that in the day
Ye Eate thereof, your Eyes that seem so cleere,
Yet are but dim, shall perfetly be then
Op'nd and cleerd, and ye shall be as Gods,
Knowing both Good and Evil as they know.
That ye should be as Gods, since I as Man,
Internal Man, is but proportion meet,
I of brute human, yee of human Gods.
So ye shalt die perhaps, by putting off
Human, to put on Gods, death to be wisht,
Though threat'nd, which no worse then this can bring
And what are Gods that Man may not become
As they, participating God-like food?
The Gods are first, and that advantage use
On our belief, that all from them proceeds,
I question it, for this fair Earth I see,
Warm'd by the Sun, producing every kind,
Them nothing: If they all things, who enclos'd
Knowledge of Good and Evil in this Tree,
That whoso eats thereof, forthwith attains
Wisdom without their leave? and wherein lies
Th' offence, that Man should thus attain to know?
What can your knowledge hurt him, or this Tree
Impart against his will if all be his?
Or is it envie, and can envie dwell
In heav'nly brests? these, these and many more
Causes import your need of this fair Fruit.
Goddess humane, reach then, and freely taste.
He ended, and his words replete with guile
Into her heart too easie entrance won:
Fixt on the Fruit she gaz'd, which to behold
Might tempt alone, and in her ears the sound
Yet rung of his perswasive words, impregn'd
With Reason, to her seeming, and with Truth;
Meanwhile the hour of Noon drew on, and wak'd
An eager appetite, rais'd by the smell
So savorie of that Fruit, which with desire,
Inclinable now grown to touch or taste,
Sollicited her longing eye; yet first
Pausing a while, thus to her self she mus'd.
Great are thy Vertues, doubtless, best of Fruits,
Though kept from Man, & worthy to be admir'd,
Whose taste, too long forborn, at first assay
Gave elocution to the mute, and taught
The Tongue not made for Speech to speak thy praise:
Thy praise hee also who forbids thy use,
Conceales not from us, naming thee the Tree
Of Knowledge, knowledge both of good and evil;
Forbids us then to taste, but his forbidding
Commends thee more, while it inferrs the good
By thee communicated, and our want:
For good unknown, sure is not had, or had
And yet unknown, is as not had at all.
In plain then, what forbids he but to know,
Forbids us good, forbids us to be wise?
Such prohibitions binde not. But if Death
Bind us with after-bands, what profits then
Our inward freedom? In the day we eate
Of this fair Fruit, our doom is, we shall die.
How dies the Serpent? hee hath eat'n and lives,
And knows, and speaks, and reasons, and discernes,
Irrational till then. For us alone
Was death invented? or to us deni'd
This intellectual food, for beasts reserv'd?
For Beasts it seems: yet that one Beast which first
Hath tasted, envies not, but brings with joy
The good befall'n him, Author unsuspect,
Friendly to man, farr from deceit or guile.
What fear I then, rather what know to feare
Under this ignorance of Good and Evil,
Of God or Death, of Law or Penaltie?
Here grows the Cure of all, this Fruit Divine,
Fair to the Eye, inviting to the Taste,
Of vertue to make wise: what hinders then
To reach, and feed at once both Bodie and Mind?
So saying, her rash hand in evil hour
Forth reaching to the Fruit, she pluck'd, she eat:
Earth felt the wound, and Nature from her seat
Sighing through all her Works gave signs of woe,
That all was lost. Back to the Thicket slunk
The guiltie Serpent, and well might, for EVE
Intent now wholly on her taste, naught else
Regarded, such delight till then, as seemd,
In Fruit she never tasted, whether true
Or fansied so, through expectation high
Of knowledg, nor was God-head from her thought.
Greedily she ingorg'd without restraint,
And knew not eating Death: Satiate at length,
And hight'nd as with Wine, jocond and boon,
Thus to her self she pleasingly began.
O Sovran, vertuous, precious of all Trees
In Paradise, of operation blest
To Sapience, hitherto obscur'd, infam'd,
And thy fair Fruit let hang, as to no end
Created; but henceforth my early care,
Not without Song, each Morning, and due praise
Shall tend thee, and the fertil burden ease
Of thy full branches offer'd free to all;
Till dieted by thee I grow mature
In knowledge, as the Gods who all things know;
Though others envie what they cannot give;
For had the gift bin theirs, it had not here
Thus grown. Experience, next to thee I owe,
Best guide; not following thee, I had remaind
In ignorance, thou op'nst Wisdoms way,
And giv'st access, though secret she retire.
And I perhaps am secret; Heav'n is high,
High and remote to see from thence distinct
Each thing on Earth; and other care perhaps
May have diverted from continual watch
Our great Forbidder, safe with all his Spies
About him. But to ADAM in what sort
Shall I appeer? shall I to him make known
As yet my change, and give him to partake
Full happiness with mee, or rather not,
But keep the odds of Knowledge in my power
Without Copartner? so to add what wants
In Femal Sex, the more to draw his Love,
And render me more equal, and perhaps
A thing not undesireable, somtime
Superior; for inferior who is free?
This may be well: but what if God have seen,
And Death ensue? then I shall be no more,
And ADAM wedded to another EVE,
Shall live with her enjoying, I extinct;
A death to think. Confirm'd then I resolve,
ADAM shall share with me in bliss or woe:
So dear I love him, that with him all deaths
I could endure; without him live no life.
So saying, from the Tree her step she turnd,
But first low Reverence don, as to the power
That dwelt within, whose presence had infus'd
Into the plant sciential sap, deriv'd
From Nectar, drink of Gods. ADAM the while
Waiting desirous her return, had wove
Of choicest Flours a Garland to adorne
Her Tresses, and her rural labours crown
As Reapers oft are wont thir Harvest Queen.
Great joy he promis'd to his thoughts, and new
Solace in her return, so long delay'd;
Yet oft his heart, divine of somthing ill,
Misgave him; hee the faultring measure felt;
And forth to meet her went, the way she took
That Morn when first they parted; by the Tree
Of Knowledge he must pass, there he her met,
Scarse from the Tree returning; in her hand
A bough of fairest fruit that downie smil'd,
New gatherd, and ambrosial smell diffus'd.
To him she hasted, in her face excuse
Came Prologue, and Apologie to prompt,
Which with bland words at will she thus addrest.
Hast thou not wonderd, ADAM, at my stay?
Thee I have misst, and thought it long, depriv'd
Thy presence, agonie of love till now
Not felt, nor shall be twice, for never more
Mean I to trie, what rash untri'd I sought,
The paine of absence from thy sight. But strange
Hath bin the cause, and wonderful to heare:
This Tree is not as we are told, a Tree
Of danger tasted, nor to evil unknown
Op'ning the way, but of Divine effect
To open Eyes, and make them Gods who taste;
And hath bin tasted such; the Serpent wise,
Or not restraind as wee, or not obeying,
Hath eat'n of the fruit, and is become,
Not dead, as we are threatn'd, but thenceforth
Endu'd with human voice and human sense,
Reasoning to admiration, and with mee
Perswasively hath so prevaild, that I
Have also tasted, and have also found
Th' effects to correspond, opener mine Eyes,
Dimm erst, dilated Spirits, ampler Heart,
And growing up to Godhead; which for thee
Chiefly I sought, without thee can despise.
For bliss, as thou hast part, to me is bliss,
Tedious, unshar'd with thee, and odious soon.
Thou therefore also taste, that equal Lot
May joyne us, equal Joy, as equal Love;
Least thou not tasting, different degree
Disjoyne us, and I then too late renounce
Deitie for thee, when Fate will not permit.
Thus EVE with Countnance blithe her storie told;
But in her Cheek distemper flushing glowd.
On th' other side, ADAM, soon as he heard
The fatal Trespass don by EVE, amaz'd,
Astonied stood and Blank, while horror chill
Ran through his veins, and all his joynts relax'd;
From his slack hand the Garland wreath'd for EVE
Down drop'd, and all the faded Roses shed:
Speechless he stood and pale, till thus at length
First to himself he inward silence broke.
O fairest of Creation, last and best
Of all Gods Works, Creature in whom excell'd
Whatever can to fight or thought be found,
Holy, divine, good, amiable, or sweet!
How art thou lost, how on a sudden lost,
Defac't, deflourd, and now to Death devote?
Rather how hast thou yeelded to transgress
The strict forbiddance, how to violate
The sacred Fruit forbidd'n! som cursed fraud
Of Enemie hath beguil'd thee, yet unknown,
And mee with thee hath ruind, for with thee
Certain my resolution is to Die;
How can I live without thee, how forgoe
Thy sweet Converse and Love so dearly joyn'd,
To live again in these wilde Woods forlorn?
Should God create another EVE, and I
Another Rib afford, yet loss of thee
Would never from my heart; no no, I feel
The Link of Nature draw me: Flesh of Flesh,
Bone of my Bone thou art, and from thy State
Mine never shall be parted, bliss or woe.
So having said, as one from sad dismay
Recomforted, and after thoughts disturbd
Submitting to what seemd remediless,
Thus in calme mood his Words to EVE he turnd.
Bold deed thou hast presum'd, adventrous EVE,
And peril great provok't, who thus hast dar'd
Had it bin onely coveting to Eye
That sacred Fruit, sacred to abstinence,
Much more to taste it under banne to touch.
But past who can recall, or don undoe?
Not God omnipotent, for Fate, yet so
Perhaps thou shalt not Die, perhaps the Fact
Is not so hainous now, foretasted Fruit,
Profan'd first by the Serpent, by him first
Made common and unhallowd: ere one tastes;
Nor yet on him found deadly; he yet lives,
Lives, as thou saidst, and gaines to live as Man
Higher degree of Life, inducement strong
To us, as likely tasting to attaine
Proportional ascent, which cannot be
But to be Gods, or Angels Demi-gods.
Nor can I think that God, Creator wise,
Though threatning, will in earnest so destroy
Us his prime Creatures, dignifi'd so high,
Set over all his Works, which in our Fall,
For us created, needs with us must faile,
Dependent made; so God shall uncreate,
Be frustrate, do, undo, and labour loose,
Not well conceav'd of God, who though his Power
Creation could repeate, yet would be loath
Us to abolish, least the Adversary
Triumph and say; Fickle their State whom God
Most Favors, who can please him long? Mee first
He ruind, now Mankind; whom will he next?
Matter of scorne, not to be given the Foe.
However I with thee have fixt my Lot,
Certain to undergoe like doom, if Death
Consort with thee, Death is to mee as Life;
So forcible within my heart I feel
The Bond of Nature draw me to my owne,
My own in thee, for what thou art is mine;
Our State cannot be severd, we are one,
One Flesh; to loose thee were to loose my self.
So ADAM, and thus EVE to him repli'd.
O glorious trial of exceeding Love,
Illustrious evidence, example high!
Ingaging me to emulate, but short
Of thy perfection, how shall I attaine,
ADAM, from whose deare side I boast me sprung,
And gladly of our Union heare thee speak,
One Heart, one Soul in both; whereof good prooff
This day affords, declaring thee resolvd,
Rather then Death or aught then Death more dread
Shall separate us, linkt in Love so deare,
To undergoe with mee one Guilt, one Crime,
If any be, of tasting this fair Fruit,
Whose vertue, for of good still good proceeds,
Direct, or by occasion hath presented
This happie trial of thy Love, which else
So eminently never had bin known.
Were it I thought Death menac't would ensue
This my attempt, I would sustain alone
The worst, and not perswade thee, rather die
Deserted, then oblige thee with a fact
Pernicious to thy Peace, chiefly assur'd
Remarkably so late of thy so true,
So faithful Love unequald; but I feel
Farr otherwise th' event, not Death, but Life
Augmented, op'nd Eyes, new Hopes, new Joyes,
Taste so Divine, that what of sweet before
Hath toucht my sense, flat seems to this, and harsh.
On my experience, ADAM, freely taste,
And fear of Death deliver to the Windes.
So saying, she embrac'd him, and for joy
Tenderly wept, much won that he his Love
Had so enobl'd, as of choice to incurr
Divine displeasure for her sake, or Death.
In recompence (for such compliance bad
Such recompence best merits) from the bough
She gave him of that fair enticing Fruit
With liberal hand: he scrupl'd not to eat
Against his better knowledge, not deceav'd,
But fondly overcome with Femal charm.
Earth trembl'd from her entrails, as again
In pangs, and Nature gave a second groan,
Skie lowr'd, and muttering Thunder, som sad drops
Wept at compleating of the mortal Sin
Original; while ADAM took no thought,
Eating his fill, nor EVE to iterate
Her former trespass fear'd, the more to soothe
Him with her lov'd societie, that now
As with new Wine intoxicated both
They swim in mirth, and fansie that they feel
Divinitie within them breeding wings
Wherewith to scorn the Earth: but that false Fruit
Farr other operation first displaid,
Carnal desire enflaming, hee on EVE
Began to cast lascivious Eyes, she him
As wantonly repaid; in Lust they burne:
Till ADAM thus 'gan EVE to dalliance move.
EVE, now I see thou art exact of taste,
And elegant, of Sapience no small part,
Since to each meaning savour we apply,
And Palate call judicious; I the praise
Yeild thee, so well this day thou hast purvey'd.
Much pleasure we have lost, while we abstain'd
From this delightful Fruit, nor known till now
True relish, tasting; if such pleasure be
In things to us forbidden, it might be wish'd,
For this one Tree had bin forbidden ten.
But come, so well refresh't, now let us play,
As meet is, after such delicious Fare;
For never did thy Beautie since the day
I saw thee first and wedded thee, adorn'd
With all perfections, so enflame my sense
With ardor to enjoy thee, fairer now
Then ever, bountie of this vertuous Tree.
So said he, and forbore not glance or toy
Of amorous intent, well understood
Of EVE, whose Eye darted contagious Fire.
Her hand he seis'd, and to a shadie bank,
Thick overhead with verdant roof imbowr'd
He led her nothing loath; Flours were the Couch,
Pansies, and Violets, and Asphodel,
And Hyacinth, Earths freshest softest lap.
There they thir fill of Love and Loves disport
Took largely, of thir mutual guilt the Seale,
The solace of thir sin, till dewie sleep
Oppress'd them, wearied with thir amorous play.
Soon as the force of that fallacious Fruit,
That with exhilerating vapour bland
About thir spirits had plaid, and inmost powers
Made erre, was now exhal'd, and grosser sleep
Bred of unkindly fumes, with conscious dreams
Encumberd, now had left them, up they rose
As from unrest, and each the other viewing,
Soon found thir Eyes how op'nd, and thir minds
How dark'nd; innocence, that as a veile
Had shadow'd them from knowing ill, was gon,
Just confidence, and native righteousness,
And honour from about them, naked left
To guiltie shame hee cover'd, but his Robe
Uncover'd more. So rose the DANITE strong
HERCULEAN SAMSON from the Harlot-lap
Of PHILISTEAN DALILAH, and wak'd
Shorn of his strength, They destitute and bare
Of all thir vertue: silent, and in face
Confounded long they sate, as struck'n mute,
Till ADAM, though not less then EVE abasht,
At length gave utterance to these words constraind.
O EVE, in evil hour thou didst give care
To that false Worm, of whomsoever taught
To counterfet Mans voice, true in our Fall,
False in our promis'd Rising; since our Eyes
Op'nd we find indeed, and find we know
Both Good and Evil, Good lost and Evil got,
Bad Fruit of Knowledge, if this be to know,
Which leaves us naked thus, of Honour void,
Of Innocence, of Faith, of Puritie,
Our wonted Ornaments now soild and staind,
And in our Faces evident the signes
Of foul concupiscence; whence evil store;
Even shame, the last of evils; of the first
Be sure then. How shall I behold the face
Henceforth of God or Angel, earst with joy
And rapture so oft beheld? those heav'nly shapes
Will dazle now this earthly, with thir blaze
Insufferably bright. O might I here
In solitude live savage, in some glad
Obscur'd, where highest Woods impenetrable
To Starr or Sun-light, spread thir umbrage broad,
And brown as Evening: Cover me ye Pines,
Ye Cedars, with innumerable boughs
Hide me, where I may never see them more.
But let us now, as in bad plight, devise
What best may for the present serve to hide
The Parts of each from other, that seem most
To shame obnoxious, and unseemliest seen,
Some Tree whose broad smooth Leaves together sowd,
And girded on our loyns, may cover round
Those middle parts, that this new commer, Shame,
There sit not, and reproach us as unclean.
So counsel'd hee, and both together went
Into the thickest Wood, there soon they chose
The Figtree, not that kind for Fruit renown'd,
But such as at this day to INDIANS known
In MALABAR or DECAN spreds her Armes
Braunching so broad and long, that in the ground
The bended Twigs take root, and Daughters grow
About the Mother Tree, a Pillard shade
High overarch't, and echoing Walks between;
There oft the INDIAN Herdsman shunning heate
Shelters in coole, and tends his pasturing Herds
At Loopholes cut through thickest shade: Those Leaves
They gatherd, broad as AMAZONIAN Targe,
And with what skill they had, together sowd,
To gird thir waste, vain Covering if to hide
Thir guilt and dreaded shame; O how unlike
To that first naked Glorie. Such of late
COLUMBUS found th' AMERICAN to girt
With featherd Cincture, naked else and wilde
Among the Trees on Iles and woodie Shores.
Thus fenc't, and as they thought, thir shame in part
Coverd, but not at rest or ease of Mind,
They sate them down to weep, nor onely Teares
Raind at thir Eyes, but high Winds worse within
Began to rise, high Passions, Anger, Hate,
Mistrust, Suspicion, Discord, and shook sore
Thir inward State of Mind, calme Region once
And full of Peace, now tost and turbulent:
For Understanding rul'd not, and the Will
Heard not her lore, both in subjection now
To sensual Appetite, who from beneathe
Usurping over sovran Reason claimd
Superior sway: From thus distemperd brest,
ADAM, estrang'd in look and alterd stile,
Speech intermitted thus to EVE renewd.
Would thou hadst heark'nd to my words, & stai'd
With me, as I besought thee, when that strange
Desire of wandring this unhappie Morn,
I know not whence possessd thee; we had then
Remaind still happie, not as now, despoild
Of all our good, sham'd, naked, miserable.
Let none henceforth seek needless cause to approve
The Faith they owe; when earnestly they seek
Such proof, conclude, they then begin to faile.
To whom soon mov'd with touch of blame thus EVE.
What words have past thy Lips, ADAM severe,
Imput'st thou that to my default, or will
Of wandering, as thou call'st it, which who knows
But might as ill have happ'nd thou being by,
Or to thy self perhaps: hadst thou bin there,
Or bere th' attempt, thou couldst not have discernd
Fraud in the Serpent, speaking as he spake;
No ground of enmitie between us known,
Why hee should mean me ill, or seek to harme.
Was I to have never parted from thy side?
As good have grown there still a liveless Rib.
Being as I am, why didst not thou the Head
Command me absolutely not to go,
Going into such danger as thou saidst?
Too facil then thou didst not much gainsay,
Nay, didst permit, approve, and fair dismiss.
Hadst thou bin firm and fixt in thy dissent,
Neither had I transgress'd, nor thou with mee.
To whom then first incenst ADAM repli'd.
Is this the Love, is the recompence
Of mine to thee, ingrateful EVE, exprest
Immutable when thou wert lost, not I,
Who might have liv'd and joyd immortal bliss,
Yet willingly chose rather Death with thee:
And am I now upbraided, as the cause
Of thy transgressing? not enough severe,
It seems, in thy restraint: what could I more?
I warn'd thee, I admonish'd thee, foretold
The danger, and the lurking Enemie
That lay in wait; beyond this had bin force,
And force upon free Will hath here no place.
But confidence then bore thee on, secure
Either to meet no danger, or to finde
Matter of glorious trial; and perhaps
I also err'd in overmuch admiring
What seemd in thee so perfet, that I thought
No evil durst attempt thee, but I rue
That errour now, which is become my crime,
And thou th' accuser. Thus it shall befall
Him who to worth in Women overtrusting
Lets her Will rule; restraint she will not brook,
And left to her self, if evil thence ensue,
Shee first his weak indulgence will accuse.
Thus they in mutual accusation spent
The fruitless hours, but neither self-condemning
And of thir vain contest appeer'd no end.
THE END OF THE EIGHTH BOOK.
PARADISE LOST
BOOK IX.
Meanwhile the hainous and despightfull act
Of SATAN done in Paradise, and how
Hee in the Serpent had perverted EVE,
Her Husband shee, to taste the fatall fruit,
Was known in Heav'n; for what can scape the Eye
Of God All-seeing, or deceave his Heart
Omniscient, who in all things wise and just,
Hinder'd not SATAN to attempt the minde
Of Man, with strength entire, and free Will arm'd,
Complete to have discover'd and repulst
Whatever wiles of Foe or seeming Friend.
For still they knew, and ought to have still remember'd
The high Injunction not to taste that Fruit,
Whoever tempted; which they not obeying,
Incurr'd, what could they less, the penaltie,
And manifold in sin, deserv'd to fall.
Up into Heav'n from Paradise in hast
Th' Angelic Guards ascended, mute and sad
For Man, for of his state by this they knew,
Much wondring how the suttle Fiend had stoln
Entrance unseen. Soon as th' unwelcome news
From Earth arriv'd at Heaven Gate, displeas'd
All were who heard, dim sadness did not spare
That time Celestial visages, yet mixt
With pitie, violated not thir bliss.
About the new-arriv'd, in multitudes
Th' ethereal People ran, to hear and know
How all befell: they towards the Throne Supream
Accountable made haste to make appear
With righteous plea, thir utmost vigilance,
And easily approv'd; when the most High
Eternal Father from his secret Cloud,
Amidst in Thunder utter'd thus his voice.
Assembl'd Angels, and ye Powers return'd
From unsuccessful charge, be not dismaid,
Nor troubl'd at these tidings from the Earth,
Which your sincerest care could not prevent,
Foretold so lately what would come to pass,
When first this Tempter cross'd the Gulf from Hell.
I told ye then he should prevail and speed
On his bad Errand, Man should be seduc't
And flatter'd out of all, believing lies
Against his Maker; no Decree of mine
Concurring to necessitate his Fall,
Or touch with lightest moment of impulse
His free Will, to her own inclining left
In eevn scale. But fall'n he is, and now
What rests, but that the mortal Sentence pass
On his transgression, Death denounc't that day,
Which he presumes already vain and void,
Because not yet inflicted, as he fear'd,
By some immediate stroak; but soon shall find
Forbearance no acquittance ere day end.
Justice shall not return as bountie scorn'd.
But whom send I to judge them? whom but thee
Vicegerent Son, to thee I have transferr'd
All Judgement, whether in Heav'n, or Earth; or Hell.
Easie it may be seen that I intend
Mercie collegue with Justice, sending thee
Mans Friend, his Mediator, his design'd
Both Ransom and Redeemer voluntarie,
And destin'd Man himself to judge Man fall'n.
So spake the Father, and unfoulding bright
Toward the right hand his Glorie, on the Son
Blaz'd forth unclouded Deitie; he full
Resplendent all his Father manifest
Express'd, and thus divinely answer'd milde.
Father Eternal, thine is to decree,
Mine both in Heav'n and Earth to do thy will
Supream, that thou in mee thy Son belov'd
Mayst ever rest well pleas'd. I go to judge
On Earth these thy transgressors, but thou knowst,
Whoever judg'd, the worst on mee must light,
When time shall be, for so I undertook
Before thee; and not repenting, this obtaine
Of right, that I may mitigate thir doom
On me deriv'd, yet I shall temper so
Justice with Mercie, as may illustrate most
Them fully satisfied, and thee appease.
Attendance none shall need, nor Train, where none
Are to behold the Judgement, but the judg'd,
Those two; the third best absent is condemn'd,
Convict by flight, and Rebel to all Law
Conviction to the Serpent none belongs.
Thus saying, from his radiant Seat he rose
Of high collateral glorie: him Thrones and Powers,
Princedoms, and Dominations ministrant
Accompanied to Heaven Gate, from whence
EDEN and all the Coast in prospect lay.
Down he descended strait; the speed of Gods
Time counts not, though with swiftest minutes wing'd.
Now was the Sun in Western cadence low
From Noon, and gentle Aires due at thir hour
To fan the Earth now wak'd, and usher in
The Eevning coole when he from wrauth more coole
Came the mild Judge and Intercessor both
To sentence Man: the voice of God they heard
Now walking in the Garden, by soft windes
Brought to thir Ears, while day declin'd, they heard
And from his presence hid themselves among
The thickest Trees, both Man and Wife, till God
Approaching, thus to ADAM call'd aloud.
Where art thou ADAM, wont with joy to meet
My coming seen far off? I miss thee here,
Not pleas'd, thus entertaind with solitude,
Where obvious dutie erewhile appear'd unsaught:
Or come I less conspicuous, or what change
Absents thee, or what chance detains? Come forth.
He came, and with him EVE, more loth, though first
To offend, discount'nanc't both, and discompos'd;
Love was not in thir looks, either to God
Or to each other, but apparent guilt,
And shame, and perturbation, and despaire,
Anger, and obstinacie, and hate, and guile.
Whence ADAM faultring long, thus answer'd brief.
I heard thee in the Garden, and of thy voice
Affraid, being naked, hid my self. To whom
The gracious Judge without revile repli'd.
My voice thou oft hast heard, and hast not fear'd,
But still rejoyc't, how is it now become
So dreadful to thee? that thou art naked, who
Hath told thee? hast thou eaten of the Tree
Whereof I gave thee charge thou shouldst not eat?
To whom thus ADAM sore beset repli'd.
O Heav'n! in evil strait this day I stand
Before my Judge, either to undergoe
My self the total Crime, or to accuse
My other self, the partner of my life;
Whose failing, while her Faith to me remaines,
I should conceal, and not expose to blame
By my complaint; but strict necessitie
Subdues me, and calamitous constraint,
Least on my head both sin and punishment,
However insupportable, be all
Devolv'd; though should I hold my peace, yet thou
Wouldst easily detect what I conceale.
This Woman whom thou mad'st to be my help,
And gav'st me as thy perfet gift, so good,
So fit, so acceptable, so Divine,
That from her hand I could suspect no ill,
And what she did, whatever in it self,
Her doing seem'd to justifie the deed;
Shee gave me of the Tree, and I did eate.
To whom the sovran Presence thus repli'd.
Was shee thy God, that her thou didst obey
Before his voice, or was shee made thy guide,
Superior, or but equal, that to her
Thou did'st resigne thy Manhood, and the Place
Wherein God set thee above her made of thee,
And for thee, whose perfection farr excell'd
Hers in all real dignitie: Adornd
She was indeed, and lovely to attract
Thy Love, not thy Subjection, and her Gifts
Were such as under Government well seem'd,
Unseemly to beare rule, which was thy part
And person, had'st thou known thy self aright.
So having said, he thus to EVE in few:
Say Woman, what is this which thou hast done?
To whom sad EVE with shame nigh overwhelm'd,
Confessing soon, yet not before her Judge
Bold or loquacious, thus abasht repli'd.
The Serpent me beguil'd and I did eate.
Which when the Lord God heard, without delay
To Judgement he proceeded on th' accus'd
Serpent though brute, unable to transferre
The Guilt on him who made him instrument
Of mischief, and polluted from the end
Of his Creation; justly then accurst,
As vitiated in Nature: more to know
Concern'd not Man (since he no further knew)
Nor alter'd his offence; yet God at last
To Satan first in sin his doom apply'd,
Though in mysterious terms, judg'd as then best:
And on the Serpent thus his curse let fall.
Because thou hast done this, thou art accurst
Above all Cattel, each Beast of the Field;
Upon thy Belly groveling thou shalt goe,
And dust shalt eat all the days of thy Life.
Between Thee and the Woman I will put
Enmitie, and between thine and her Seed;
Her Seed shall bruise thy head, thou bruise his heel.
So spake this Oracle, then verifi'd
When JESUS son of MARY second EVE,
Saw Satan fall like Lightning down from Heav'n,
Prince of the Aire; then rising from his Grave
Spoild Principalities and Powers, triumpht
In open shew, and with ascention bright
Captivity led captive through the Aire,
The Realme it self of Satan long usurpt,
Whom he shall tread at last under our feet;
Eevn hee who now foretold his fatal bruise,
And to the Woman thus his Sentence turn'd.
Thy sorrow I will greatly multiplie
By thy Conception; Children thou shalt bring
In sorrow forth, and to thy Husbands will
Thine shall submit, hee over thee shall rule.
On ADAM last thus judgement he pronounc'd.
Because thou hast heark'nd to the voice of thy Wife,
And eaten of the Tree concerning which
I charg'd thee, saying: Thou shalt not eate thereof,
Curs'd is the ground for thy sake, thou in sorrow
Shalt eate thereof all the days of thy Life;
Thornes also and Thistles it shall bring thee forth
Unbid, and thou shalt eate th' Herb of th' Field,
In the sweat of thy Face shalt thou eate Bread,
Till thou return unto the ground, for thou
Out of the ground wast taken, know thy Birth,
For dust thou art, and shalt to dust returne.
So judg'd he Man, both Judge and Saviour sent,
And th' instant stroke of Death denounc't that day
Remov'd farr off; then pittying how they stood
Before him naked to the aire, that now
Must suffer change, disdain'd not to begin
Thenceforth the forme of servant to assume,
As when he wash'd his servants feet, so now
As Father of his Familie he clad
Thir nakedness with Skins of Beasts, or slain,
Or as the Snake with youthful Coate repaid;
And thought not much to cloath his Enemies:
Nor hee thir outward onely with the Skins
Of Beasts, but inward nakedness, much more
Opprobrious, with his Robe of righteousness,
Araying cover'd from his Fathers sight.
To him with swift ascent he up returnd,
Into his blissful bosom reassum'd
In glory as of old, to him appeas'd
All, though all-knowing, what had past with Man
Recounted, mixing intercession sweet.
Meanwhile ere thus was sin'd and judg'd on Earth,
Within the Gates of Hell sate Sin and Death,
In counterview within the Gates, that now
Stood open wide, belching outrageous flame
Farr into CHAOS, since the Fiend pass'd through,
Sin opening, who thus now to Death began.
O Son, why sit we here each other viewing
Idlely, while Satan our great Author thrives
In other Worlds, and happier Seat provides
For us his ofspring deare? It cannot be
But that success attends him; if mishap,
Ere this he had return'd, with fury driv'n
By his Avenger, since no place like this
Can fit his punishment, or their revenge.
Methinks I feel new strength within me rise,
Wings growing, and Dominion giv'n me large
Beyond this Deep; whatever drawes me on,
Or sympathie, or som connatural force
Powerful at greatest distance to unite
With secret amity things of like kinde
By secretest conveyance. Thou my Shade
Inseparable must with mee along:
For Death from Sin no power can separate.
But least the difficultie of passing back
Stay his returne perhaps over this Gulfe
Impassable, impervious, let us try
Adventrous work, yet to thy power and mine
Not unagreeable, to found a path
Over this Maine from Hell to that new World
Where Satan now prevailes, a Monument
Of merit high to all th' infernal Host,
Easing thir passage hence, for intercourse,
Or transmigration, as thir lot shall lead.
Nor can I miss the way, so strongly drawn
By this new felt attraction and instinct.
Whom thus the meager Shadow answerd soon.
Goe whither Fate and inclination strong
Leads thee, I shall not lag behinde, nor erre
The way, thou leading, such a sent I draw
Of carnage, prey innumerable, and taste
The savour of Death from all things there that live:
Nor shall I to the work thou enterprisest
Be wanting, but afford thee equal aid.
So saying, with delight he snuff'd the smell
Of mortal change on Earth. As when a flock
Of ravenous Fowl, though many a League remote,
Against the day of Battel, to a Field,
Where Armies lie encampt, come flying, lur'd
With sent of living Carcasses design'd
For death, the following day, in bloodie fight.
So sented the grim Feature, and upturn'd
His Nostril wide into the murkie Air,
Sagacious of his Quarrey from so farr.
Then Both from out Hell Gates into the waste
Wide Anarchie of CHAOS damp and dark
Flew divers, & with Power (thir Power was great)
Hovering upon the Waters; what they met
Solid or slimie, as in raging Sea
Tost up and down, together crowded drove
From each side shoaling towards the mouth of Hell.
As when two Polar Winds blowing adverse
Upon the CRONIAN Sea, together drive
Mountains of Ice, that stop th' imagin'd way
Beyond PETSORA Eastward, to the rich
CATHAIAN Coast. The aggregated Soyle
Death with his Mace petrific, cold and dry,
As with a Trident smote, and fix't as firm
As DELOS floating once; the rest his look
Bound with GORGONIAN rigor not to move,
And with ASPHALTIC slime; broad as the Gate,
Deep to the Roots of Hell the gather'd beach
They fasten'd, and the Mole immense wraught on
Over the foaming deep high Archt, a Bridge
Of length prodigious joyning to the Wall
Immoveable of this now fenceless world
Forfeit to Death; from hence a passage broad,
Smooth, easie, inoffensive down to Hell.
So, if great things to small may be compar'd,
XERXES, the Libertie of GREECE to yoke,
From SUSA his MEMNONIAN Palace high
Came to the Sea, and over HELLESPONT
Bridging his way, EUROPE with ASIA joyn'd,
And scourg'd with many a stroak th' indignant waves.
Now had they brought the work by wondrous Art
Pontifical, a ridge of pendent Rock
Over the vext Abyss, following the track
Of SATAN, to the selfsame place where hee
First lighted from his Wing, and landed safe
From out of CHAOS to the outside bare
Of this round World: with Pinns of Adamant
And Chains they made all fast, too fast they made
And durable; and now in little space
The Confines met of Empyrean Heav'n
And of this World, and on the left hand Hell
With long reach interpos'd; three sev'ral wayes
In sight, to each of these three places led.
And now thir way to Earth they had descri'd,
To Paradise first tending, when behold
SATAN in likeness of an Angel bright
Betwixt the CENTAURE and the SCORPION stearing
His ZENITH, while the Sun in ARIES rose:
Disguis'd he came, but those his Children dear
Thir Parent soon discern'd, though in disguise.
Hee, after EVE seduc't, unminded slunk
Into the Wood fast by, and changing shape
To observe the sequel, saw his guileful act
By EVE, though all unweeting, seconded
Upon her Husband, saw thir shame that sought
Vain covertures; but when he saw descend
The Son of God to judge them, terrifi'd
Hee fled, not hoping to escape, but shun
The present, fearing guiltie what his wrauth
Might suddenly inflict; that past, return'd
By Night, and listning where the hapless Paire
Sate in thir sad discourse, and various plaint,
Thence gatherd his own doom, which understood
Not instant, but of future time. With joy
And tidings fraught, to Hell he now return'd,
And at the brink of CHAOS, neer the foot
Of this new wondrous Pontifice, unhop't
Met who to meet him came, his Ofspring dear.
Great joy was at thir meeting, and at sight
Of that stupendious Bridge his joy encreas'd.
Long hee admiring stood, till Sin, his faire
Inchanting Daughter, thus the silence broke.
O Parent, these are thy magnific deeds,
Thy Trophies, which thou view'st as not thine own,
Thou art thir Author and prime Architect:
For I no sooner in my Heart divin'd,
My Heart, which by a secret harmonie
Still moves with thine, joyn'd in connexion sweet,
That thou on Earth hadst prosper'd, which thy looks
Now also evidence, but straight I felt
Though distant from thee Worlds between, yet felt
That I must after thee with this thy Son;
Such fatal consequence unites us three:
Hell could no longer hold us in her bounds,
Nor this unvoyageable Gulf obscure
Detain from following thy illustrious track.
Thou hast atchiev'd our libertie, confin'd
Within Hell Gates till now, thou us impow'rd
To fortifie thus farr, and overlay
With this portentous Bridge the dark Abyss.
Thine now is all this World, thy vertue hath won
What thy hands builded not, thy Wisdom gain'd
With odds what Warr hath lost, and fully aveng'd
Our foile in Heav'n; here thou shalt Monarch reign,
There didst not; there let him still Victor sway,
As Battel hath adjudg'd, from this new World
Retiring, by his own doom alienated,
And henceforth Monarchie with thee divide
Of all things, parted by th' Empyreal bounds,
His Quadrature, from thy Orbicular World,
Or trie thee now more dang'rous to his Throne.
Whom thus the Prince of Darkness answerd glad.
Fair Daughter, and thou Son and Grandchild both,
High proof ye now have giv'n to be the Race
Of SATAN (for I glorie in the name,
Antagonist of Heav'ns Almightie King)
Amply have merited of me, of all
Th' Infernal Empire, that so neer Heav'ns dore
Triumphal with triumphal act have met,
Mine with this glorious Work, & made one Realm
Hell and this World, one Realm, one Continent
Of easie thorough-fare. Therefore while I
Descend through Darkness, on your Rode with ease
To my associate Powers, them to acquaint
With these successes, and with them rejoyce,
You two this way, among those numerous Orbs
All yours, right down to Paradise descend;
There dwell & Reign in bliss, thence on the Earth
Dominion exercise and in the Aire,
Chiefly on Man, sole Lord of all declar'd,
Him first make sure your thrall, and lastly kill.
My Substitutes I send ye, and Create
Plenipotent on Earth, of matchless might
Issuing from mee: on your joynt vigor now
My hold of this new Kingdom all depends,
Through Sin to Death expos'd by my exploit.
If your joynt power prevaile, th' affaires of Hell
No detriment need feare, goe and be strong.
So saying he dismiss'd them, they with speed
Thir course through thickest Constellations held
Spreading thir bane; the blasted Starrs lookt wan,
And Planets, Planet-strook, real Eclips
Then sufferd. Th' other way SATAN went down
The Causey to Hell Gate; on either side
Disparted CHAOS over built exclaimd,
And with rebounding surge the barrs assaild,
That scorn'd his indignation: through the Gate,
Wide open and unguarded, SATAN pass'd,
And all about found desolate; for those
Appointed to sit there, had left thir charge,
Flown to the upper World; the rest were all
Farr to the inland retir'd, about the walls
Of PANDEMONIUM, Citie and proud seate
Of LUCIFER, so by allusion calld,
Of that bright Starr to SATAN paragond.
There kept thir Watch the Legions, while the Grand
In Council sate, sollicitous what chance
Might intercept thir Emperour sent, so hee
Departing gave command, and they observ'd.
As when the TARTAR from his RUSSIAN Foe
By ASTRACAN over the Snowie Plaines
Retires, or BACTRIAN Sophi from the hornes
Of TURKISH Crescent, leaves all waste beyond
The Realme of ALADULE, in his retreate
To TAURIS or CASBEEN. So these the late
Heav'n-banisht Host, left desert utmost Hell
Many a dark League, reduc't in careful Watch
Round thir Metropolis, and now expecting
Each hour their great adventurer from the search
Of Forrein Worlds: he through the midst unmarkt,
In shew plebeian Angel militant
Of lowest order, past; and from the dore
Of that PLUTONIAN Hall, invisible
Ascended his high Throne, which under state
Of richest texture spred, at th' upper end
Was plac't in regal lustre. Down a while
He sate, and round about him saw unseen:
At last as from a Cloud his fulgent head
And shape Starr bright appeer'd, or brighter, clad
With what permissive glory since his fall
Was left him, or false glitter: All amaz'd
At that so sudden blaze the STYGIAN throng
Bent thir aspect, and whom they wish'd beheld,
Thir mighty Chief returnd: loud was th' acclaime:
Forth rush'd in haste the great consulting Peers,
Rais'd from thir dark DIVAN, and with like joy
Congratulant approach'd him, who with hand
Silence, and with these words attention won.
Thrones, Dominations, Princedoms, Vertues, Powers,
For in possession such, not onely of right,
I call ye and declare ye now, returnd
Successful beyond hope, to lead ye forth
Triumphant out of this infernal Pit
Abominable, accurst, the house of woe,
And Dungeon of our Tyrant: Now possess,
As Lords, a spacious World, to our native Heaven
Little inferiour, by my adventure hard
With peril great atchiev'd. Long were to tell
What I have don, what sufferd, with what paine
Voyag'd the unreal, vast, unbounded deep
Of horrible confusion, over which
By Sin and Death a broad way now is pav'd
To expedite your glorious march; but I
Toild out my uncouth passage, forc't to ride
Th' untractable Abysse, plung'd in the womb
Of unoriginal NIGHT and CHAOS wilde,
That jealous of thir secrets fiercely oppos'd
My journey strange, with clamorous uproare
Protesting Fate supreame; thence how I found
The new created World, which fame in Heav'n
Long had foretold, a Fabrick wonderful
Of absolute perfection, therein Man
Plac't in a Paradise, by our exile
Made happie: Him by fraud I have seduc'd
From his Creator, and the more to increase
Your wonder, with an Apple; he thereat
Offended, worth your laughter, hath giv'n up
Both his beloved Man and all his World,
To Sin and Death a prey, and so to us,
Without our hazard, labour or allarme,
To range in, and to dwell, and over Man
To rule, as over all he should have rul'd.
True is, mee also he hath judg'd, or rather
Mee not, but the brute Serpent in whose shape
Man I deceav'd: that which to mee belongs,
Is enmity, which he will put between
Mee and Mankinde; I am to bruise his heel;
His Seed, when is not set, shall bruise my head:
A World who would not purchase with a bruise,
Or much more grievous pain? Ye have th' account
Of my performance: What remaines, ye Gods,
But up and enter now into full bliss.
So having said, a while he stood, expecting
Thir universal shout and high applause
To fill his eare, when contrary he hears
On all sides, from innumerable tongues
A dismal universal hiss, the sound
Of public scorn; he wonderd, but not long
Had leasure, wondring at himself now more;
His Visage drawn he felt to sharp and spare,
His Armes clung to his Ribs, his Leggs entwining
Each other, till supplanted down he fell
A monstrous Serpent on his Belly prone,
Reluctant, but in vaine, a greater power
Now rul'd him, punisht in the shape he sin'd,
According to his doom: he would have spoke,
But hiss for hiss returnd with forked tongue
To forked tongue, for now were all transform'd
Alike, to Serpents all as accessories
To his bold Riot: dreadful was the din
Of hissing through the Hall, thick swarming now
With complicated monsters, head and taile,
Scorpion and Asp, and AMPHISBAENA dire,
CERASTES hornd, HYDRUS, and ELLOPS drear,
And DIPSAS (Not so thick swarm'd once the Soil
Bedropt with blood of Gorgon, or the Isle
OPHIUSA) but still greatest hee the midst,
Now Dragon grown, larger then whom the Sun
Ingenderd in the PYTHIAN Vale on slime,
Huge PYTHON, and his Power no less he seem'd
Above the rest still to retain; they all
Him follow'd issuing forth to th' open Field,
Where all yet left of that revolted Rout
Heav'n-fall'n, in station stood or just array,
Sublime with expectation when to see
In Triumph issuing forth thir glorious Chief;
They saw, but other sight instead, a crowd
Of ugly Serpents; horror on them fell,
And horrid sympathie; for what they saw,
They felt themselvs now changing; down thir arms,
Down fell both Spear and Shield, down they as fast,
And the dire hiss renew'd, and the dire form
Catcht by Contagion, like in punishment,
As in thir crime. Thus was th' applause they meant,
Turnd to exploding hiss, triumph to shame
Cast on themselves from thir own mouths. There stood
A Grove hard by, sprung up with this thir change,
His will who reigns above, to aggravate
Thir penance, laden with fair Fruit, like that
VVhich grew in Paradise, the bait of EVE
Us'd by the Tempter: on that prospect strange
Thir earnest eyes they fix'd, imagining
For one forbidden Tree a multitude
Now ris'n, to work them furder woe or shame;
Yet parcht with scalding thurst and hunger fierce,
Though to delude them sent, could not abstain,
But on they rould in heaps, and up the Trees
Climbing, sat thicker then the snakie locks
That curld MEGAERA: greedily they pluck'd
The Frutage fair to sight, like that which grew
Neer that bituminous Lake where SODOM flam'd;
This more delusive, not the touch, but taste
Deceav'd; they fondly thinking to allay
Thir appetite with gust, instead of Fruit
Chewd bitter Ashes, which th' offended taste
VVith spattering noise rejected: oft they assayd,
Hunger and thirst constraining, drugd as oft,
VVith hatefullest disrelish writh'd thir jaws
VVith foot and cinders fill'd; so oft they fell
Into the same illusion, not as Man
Whom they triumph'd once lapst. Thus were they plagu'd
And worn with Famin, long and ceasless hiss,
Till thir lost shape, permitted, they resum'd,
Yearly enjoynd, some say, to undergo
This annual humbling certain number'd days,
To dash thir pride, and joy for Man seduc't.
However some tradition they dispers'd
Among the Heathen of thir purchase got,
And Fabl'd how the Serpent, whom they calld
OPHION with EURYNOME, the wide-
Encroaching EVE perhaps, had first the rule
Of high OLYMPUS, thence by SATURN driv'n
And OPS, ere yet DICTAEAN JOVE was born.
Mean while in Paradise the hellish pair
Too soon arriv'd, SIN there in power before,
Once actual, now in body, and to dwell
Habitual habitant; behind her DEATH
Close following pace for pace, not mounted yet
On his pale Horse: to whom SIN thus began.
Second of SATAN sprung, all conquering Death,
What thinkst thou of our Empire now, though earnd
With travail difficult, not better farr
Then stil at Hels dark threshold to have sate watch,
Unnam'd, undreaded, and thy self half starv'd?
Whom thus the Sin-born Monster answerd soon.
To mee, who with eternal Famin pine,
Alike is Hell, or Paradise, or Heaven,
There best, where most with ravin I may meet;
Which here, though plenteous, all too little seems
To stuff this Maw, this vast unhide-bound Corps.
To whom th' incestuous Mother thus repli'd.
Thou therefore on these Herbs, and Fruits, & Flours
Feed first, on each Beast next, and Fish, and Fowle,
No homely morsels, and whatever thing
The Sithe of Time mowes down, devour unspar'd,
Till I in Man residing through the Race,
His thoughts, his looks, words, actions all infect,
And season him thy last and sweetest prey.
This said, they both betook them several wayes,
Both to destroy, or unimmortal make
All kinds, and for destruction to mature
Sooner or later; which th' Almightie seeing,
From his transcendent Seat the Saints among,
To those bright Orders utterd thus his voice.
See with what heat these Dogs of Hell advance
To waste and havoc yonder VVorld, which I
So fair and good created, and had still
Kept in that state, had not the folly of Man
Let in these wastful Furies, who impute
Folly to mee, so doth the Prince of Hell
And his Adherents, that with so much ease
I suffer them to enter and possess
A place so heav'nly, and conniving seem
To gratifie my scornful Enemies,
That laugh, as if transported with some fit
Of Passion, I to them had quitted all,
At random yeilded up to their misrule;
And know not that I call'd and drew them thither
My Hell-hounds, to lick up the draff and filth
Which mans polluting Sin with taint hath shed
On what was pure, till cramm'd and gorg'd, nigh burst
With suckt and glutted offal, at one fling
Of thy victorious Arm, well-pleasing Son,
Both SIN, and DEATH, and yawning GRAVE at last
Through CHAOS hurld, obstruct the mouth of Hell
For ever, and seal up his ravenous Jawes.
Then Heav'n and Earth renewd shall be made pure
To sanctitie that shall receive no staine:
Till then the Curse pronounc't on both precedes.
Hee ended, and the heav'nly Audience loud
Sung HALLELUIA, as the sound of Seas,
Through multitude that sung: Just are thy ways,
Righteous are thy Decrees on all thy Works;
Who can extenuate thee? Next, to the Son,
Destin'd restorer of Mankind, by whom
New Heav'n and Earth shall to the Ages rise,
Or down from Heav'n descend. Such was thir song,
While the Creator calling forth by name
His mightie Angels gave them several charge,
As sorted best with present things. The Sun
Had first his precept so to move, so shine,
As might affect the Earth with cold and heat
Scarce tollerable, and from the North to call
Decrepit Winter, from the South to bring
Solstitial summers heat. To the blanc Moone
Her office they prescrib'd, to th' other five
Thir planetarie motions and aspects
In SEXTILE, SQUARE, and TRINE, and OPPOSITE,
Of noxious efficacie, and when to joyne
In Synod unbenigne, and taught the fixt
Thir influence malignant when to showre,
Which of them rising with the Sun, or falling,
Should prove tempestuous: To the Winds they set
Thir corners, when with bluster to confound
Sea, Aire, and Shoar, the Thunder when to rowle
With terror through the dark Aereal Hall.
Some say he bid his Angels turne ascanse
The Poles of Earth twice ten degrees and more
From the Suns Axle; they with labour push'd
Oblique the Centric Globe: Som say the Sun
Was bid turn Reines from th' Equinoctial Rode
Like distant breadth to TAURUS with the Seav'n
ATLANTICK Sisters, and the SPARTAN Twins
Up to the TROPIC Crab; thence down amaine
By LEO and the VIRGIN and the SCALES,
As deep as CAPRICORNE, to bring in change
Of Seasons to each Clime; else had the Spring
Perpetual smil'd on Earth with vernant Flours,
Equal in Days and Nights, except to those
Beyond the Polar Circles; to them Day
Had unbenighted shon, while the low Sun
To recompence his distance, in thir sight
Had rounded still th' HORIZON, and not known
Or East or West, which had forbid the Snow
From cold ESTOTILAND, and South as farr
Beneath MAGELLAN. At that tasted Fruit
The Sun, as from THYESTEAN Banquet, turn'd
His course intended; else how had the World
Inhabited, though sinless, more then now,
Avoided pinching cold and scorching heate?
These changes in the Heav'ns, though slow, produc'd
Like change on Sea and Land, sideral blast,
Vapour, and Mist, and Exhalation hot,
Corrupt and Pestilent: Now from the North
Of NORUMBEGA, and the SAMOED shoar
Bursting thir brazen Dungeon, armd with ice
And snow and haile and stormie gust and flaw,
BOREAS and CAECIAS and ARGESTES loud
And THRASCIAS rend the Woods and Seas upturn;
With adverse blast up-turns them from the South
NOTUS and AFER black with thundrous Clouds
From SERRALIONA; thwart of these as fierce
Forth rush the LEVANT and the PONENT VVindes
EURUS and ZEPHIR with thir lateral noise,
SIROCCO, and LIBECCHIO. Thus began
Outrage from liveless things; but Discord first
Daughter of Sin, among th' irrational,
Death introduc'd through fierce antipathie:
Beast now with Beast gan war, & Fowle with Fowle,
And Fish with Fish; to graze the Herb all leaving,
Devourd each other; nor stood much in awe
Of Man, but fled him, or with count'nance grim
Glar'd on him passing: these were from without
The growing miseries, which ADAM saw
Alreadie in part, though hid in gloomiest shade,
To sorrow abandond, but worse felt within,
And in a troubl'd Sea of passion tost,
Thus to disburd'n sought with sad complaint.
O miserable of happie! is this the end
Of this new glorious World, and mee so late
The Glory of that Glory, who now becom
Accurst of blessed, hide me from the face
Of God, whom to behold was then my highth
Of happiness: yet well, if here would end
The miserie, I deserv'd it, and would beare
My own deservings; but this will not serve;
All that I eate or drink, or shall beget,
Is propagated curse. O voice once heard
Delightfully, ENCREASE AND MULTIPLY,
Now death to heare! for what can I encrease
Or multiplie, but curses on my head?
Who of all Ages to succeed, but feeling
The evil on him brought by me, will curse
My Head, Ill fare our Ancestor impure,
For this we may thank ADAM; but his thanks
Shall be the execration; so besides
Mine own that bide upon me, all from mee
Shall with a fierce reflux on mee redound,
On mee as on thir natural center light
Heavie, though in thir place. O fleeting joyes
Of Paradise, deare bought with lasting woes!
Did I request thee, Maker, from my Clay
To mould me Man, did I sollicite thee
From darkness to promote me, or here place
In this delicious Garden? as my Will
Concurd not to my being, it were but right
And equal to reduce me to my dust,
Desirous to resigne, and render back
All I receav'd, unable to performe
Thy terms too hard, by which I was to hold
The good I sought not. To the loss of that,
Sufficient penaltie, why hast thou added
The sense of endless woes? inexplicable
Thy Justice seems; yet to say truth, too late,
I thus contest; then should have been refusd
Those terms whatever, when they were propos'd:
Thou didst accept them; wilt thou enjoy the good,
Then cavil the conditions? and though God
Made thee without thy leave, what if thy Son
Prove disobedient, and reprov'd, retort,
Wherefore didst thou beget me? I sought it not:
Wouldst thou admit for his contempt of thee
That proud excuse? yet him not thy election,
But Natural necessity begot.
God made thee of choice his own, and of his own
To serve him, thy reward was of his grace,
Thy punishment then justly is at his Will.
Be it so, for I submit, his doom is fair,
That dust I am, and shall to dust returne:
O welcom hour whenever! why delayes
His hand to execute what his Decree
Fixd on this day? why do I overlive,
Why am I mockt with death, and length'nd out
To deathless pain? how gladly would I meet
Mortalitie my sentence, and be Earth
Insensible, how glad would lay me down
As in my Mothers lap? there I should rest
And sleep secure; his dreadful voice no more
Would Thunder in my ears, no fear of worse
To mee and to my ofspring would torment me
With cruel expectation. Yet one doubt
Pursues me still, least all I cannot die,
Least that pure breath of Life, the Spirit of Man
Which God inspir'd, cannot together perish
With this corporeal Clod; then in the Grave,
Or in some other dismal place, who knows
But I shall die a living Death? O thought
Horrid, if true! yet why? it was but breath
Of Life that sinn'd; what dies but what had life
And sin? the Bodie properly hath neither.
All of me then shall die: let this appease
The doubt, since humane reach no further knows.
For though the Lord of all be infinite,
Is his wrauth also? be it, man is not so,
But mortal doom'd. How can he exercise
Wrath without end on Man whom Death must end?
Can he make deathless Death? that were to make
Strange contradiction, which to God himself
Impossible is held, as Argument
Of weakness, not of Power. Will he, draw out,
For angers sake, finite to infinite
In punisht man, to satisfie his rigour
Satisfi'd never; that were to extend
His Sentence beyond dust and Natures Law,
By which all Causes else according still
To the reception of thir matter act,
Not to th' extent of thir own Spheare. But say
That Death be not one stroak, as I suppos'd,
Bereaving sense, but endless miserie
From this day onward, which I feel begun
Both in me, and without me, and so last
To perpetuitie; Ay me, that fear
Comes thundring back with dreadful revolution
On my defensless head; both Death and I
Am found Eternal, and incorporate both,
Nor I on my part single, in mee all
Posteritie stands curst: Fair Patrimonie
That I must leave ye, Sons; O were I able
To waste it all my self, and leave ye none!
So disinherited how would ye bless
Me now your Curse! Ah, why should all mankind
For one mans fault thus guiltless be condemn'd,
If guiltless? But from mee what can proceed,
But all corrupt, both Mind and Will deprav'd,
Not to do onely, but to will the same
With me? how can they acquitted stand
In sight of God? Him after all Disputes
Forc't I absolve: all my evasions vain
And reasonings, though through Mazes, lead me still
But to my own conviction: first and last
On mee, mee onely, as the sourse and spring
Of all corruption, all the blame lights due;
So might the wrauth, Fond wish! couldst thou support
That burden heavier then the Earth to bear,
Then all the world much heavier, though divided
With that bad Woman? Thus what thou desir'st,
And what thou fearst, alike destroyes all hope
Of refuge, and concludes thee miserable
Beyond all past example and future,
To SATAN onely like both crime and doom.
O Conscience, into what Abyss of fears
And horrors hast thou driv'n me; out of which
I find no way, from deep to deeper plung'd!
Thus ADAM to himself lamented loud
Through the still Night, now now, as ere man fell,
Wholsom and cool, and mild, but with black Air
Accompanied, with damps and dreadful gloom,
Which to his evil Conscience represented
All things with double terror: On the ground
Outstretcht he lay, on the cold ground, and oft
Curs'd his Creation, Death as oft accus'd
Of tardie execution, since denounc't
The day of his offence. Why comes not Death,
Said hee, with one thrice acceptable stroke
To end me? Shall Truth fail to keep her word,
Justice Divine not hast'n to be just?
But Death comes not at call, Justice Divine
Mends not her slowest pace for prayers or cries.
O Woods, O Fountains, Hillocks, Dales and Bowrs,
VVith other echo farr I taught your Shades
To answer, and resound farr other Song.
VVhom thus afflicted when sad EVE beheld,
Desolate where she sate, approaching nigh,
Soft words to his fierce passion she assay'd:
But her with stern regard he thus repell'd.
Out of my sight, thou Serpent, that name best
Befits thee with him leagu'd, thy self as false
And hateful; nothing wants, but that thy shape,
Like his, and colour Serpentine may shew
Thy inward fraud, to warn all Creatures from thee
Henceforth; least that too heav'nly form, pretended
To hellish falshood, snare them. But for thee
I had persisted happie, had not thy pride
And wandring vanitie, when lest was safe,
Rejected my forewarning, and disdain'd
Not to be trusted, longing to be seen
Though by the Devil himself, him overweening
To over-reach, but with the Serpent meeting
Fool'd and beguil'd, by him thou, I by thee,
To trust thee from my side, imagin'd wise,
Constant, mature, proof against all assaults,
And understood not all was but a shew
Rather then solid vertu, all but a Rib
Crooked by nature, bent, as now appears,
More to the part sinister from me drawn,
Well if thrown out, as supernumerarie
To my just number found. O why did God,
Creator wise, that peopl'd highest Heav'n
With Spirits Masculine, create at last
This noveltie on Earth, this fair defect
Of Nature, and not fill the World at once
With Men as Angels without Feminine,
Or find some other way to generate
Mankind? this mischief had not then befall'n,
And more that shall befall, innumerable
Disturbances on Earth through Femal snares,
And straight conjunction with this Sex: for either
He never shall find out fit Mate, but such
As some misfortune brings him, or mistake,
Or whom he wishes most shall seldom gain
Through her perverseness, but shall see her gaind
By a farr worse, or if she love, withheld
By Parents, or his happiest choice too late
Shall meet, alreadie linkt and Wedlock-bound
To a fell Adversarie, his hate or shame:
Which infinite calamitie shall cause
To humane life, and houshold peace confound.
He added not, and from her turn'd, but EVE
Not so repulst, with Tears that ceas'd not flowing,
And tresses all disorderd, at his feet
Fell humble, and imbracing them, besaught
His peace, and thus proceeded in her plaint.
Forsake me not thus, ADAM, witness Heav'n
What love sincere, and reverence in my heart
I beare thee, and unweeting have offended,
Unhappilie deceav'd; thy suppliant
I beg, and clasp thy knees; bereave me not,
Whereon I live, thy gentle looks, thy aid,
Thy counsel in this uttermost distress,
My onely strength and stay: forlorn of thee,
Whither shall I betake me, where subsist?
While yet we live, scarse one short hour perhaps,
Between us two let there be peace, both joyning,
As joyn'd in injuries, one enmitie
Against a Foe by doom express assign'd us,
That cruel Serpent: On me exercise not
Thy hatred for this miserie befall'n,
On me already lost, mee then thy self
More miserable; both have sin'd, but thou
Against God onely, I against God and thee,
And to the place of judgement will return,
There with my cries importune Heaven, that all
The sentence from thy head remov'd may light
On me, sole cause to thee of all this woe,
Mee mee onely just object of his ire.
She ended weeping, and her lowlie plight,
Immoveable till peace obtain'd from fault
Acknowledg'd and deplor'd, in ADAM wraught
Commiseration; soon his heart relented
Towards her, his life so late and sole delight,
Now at his feet submissive in distress,
Creature so faire his reconcilement seeking,
His counsel whom she had displeas'd, his aide;
As one disarm'd, his anger all he lost,
And thus with peaceful words uprais'd her soon.
Unwarie, and too desirous, as before,
So now of what thou knowst not, who desir'st
The punishment all on thy self; alas,
Beare thine own first, ill able to sustaine
His full wrauth whose thou feelst as yet lest part,
And my displeasure bearst so ill. If Prayers
Could alter high Decrees, I to that place
Would speed before thee, and be louder heard,
That on my head all might be visited,
Thy frailtie and infirmer Sex forgiv'n,
To me committed and by me expos'd.
But rise, let us no more contend, nor blame
Each other, blam'd enough elsewhere, but strive
In offices of Love, how we may light'n
Each others burden in our share of woe;
Since this days Death denounc't, if ought I see,
Will prove no sudden, but a slow-pac't evill,
A long days dying to augment our paine,
And to our Seed (O hapless Seed!) deriv'd.
To whom thus EVE, recovering heart, repli'd.
ADAM, by sad experiment I know
How little weight my words with thee can finde,
Found so erroneous, thence by just event
Found so unfortunate; nevertheless,
Restor'd by thee, vile as I am, to place
Of new acceptance, hopeful to regaine
Thy Love, the sole contentment of my heart,
Living or dying from thee I will not hide
What thoughts in my unquiet brest are ris'n,
Tending to som relief of our extremes,
Or end, though sharp and sad, yet tolerable,
As in our evils, and of easier choice.
If care of our descent perplex us most,
Which must be born to certain woe, devourd
By Death at last, and miserable it is
To be to others cause of misery,
Our own begotten, and of our Loines to bring
Into this cursed World a woful Race,
That after wretched Life must be at last
Food for so foule a Monster, in thy power
It lies, yet ere Conception to prevent
The Race unblest, to being yet unbegot.
Childless thou art, Childless remaine:
So Death shall be deceav'd his glut, and with us two
Be forc'd to satisfie his Rav'nous Maw.
But if thou judge it hard and difficult,
Conversing, looking, loving, to abstain
From Loves due Rites, Nuptial embraces sweet,
And with desire to languish without hope,
Before the present object languishing
With like desire, which would be miserie
And torment less then none of what we dread,
Then both our selves and Seed at once to free
From what we fear for both, let us make short,
Let us seek Death, or hee not found, supply
With our own hands his Office on our selves;
Why stand we longer shivering under feares,
That shew no end but Death, and have the power,
Of many wayes to die the shortest choosing,
Destruction with destruction to destroy.
She ended heer, or vehement despaire
Broke off the rest; so much of Death her thoughts
Had entertaind, as di'd her Cheeks with pale.
But ADAM with such counsel nothing sway'd,
To better hopes his more attentive minde
Labouring had rais'd, and thus to EVE repli'd.
EVE, thy contempt of life and pleasure seems
To argue in thee somthing more sublime
And excellent then what thy minde contemnes;
But self-destruction therefore saught, refutes
That excellence thought in thee, and implies,
Not thy contempt, but anguish and regret
For loss of life and pleasure overlov'd.
Or if thou covet death, as utmost end
Of miserie, so thinking to evade
The penaltie pronounc't, doubt not but God
Hath wiselier arm'd his vengeful ire then so
To be forestall'd; much more I fear least Death
So snatcht will not exempt us from the paine
We are by doom to pay; rather such acts
Of contumacie will provoke the highest
To make death in us live: Then let us seek
Som safer resolution, which methinks
I have in view, calling to minde with heed
Part of our Sentence, that thy Seed shall bruise
The Serpents head; piteous amends, unless
Be meant, whom I conjecture, our grand Foe
SATAN, who in the Serpent hath contriv'd
Against us this deceit: to crush his head
Would be revenge indeed; which will be lost
By death brought on our selves, or childless days
Resolv'd, as thou proposest; so our Foe
Shall scape his punishment ordain'd, and wee
Instead shall double ours upon our heads.
No more be mention'd then of violence
Against our selves, and wilful barrenness,
That cuts us off from hope, and savours onely
Rancor and pride, impatience and despite,
Reluctance against God and his just yoke
Laid on our Necks. Remember with what mild
And gracious temper he both heard and judg'd
Without wrauth or reviling; wee expected
Immediate dissolution, which we thought
Was meant by Death that day, when lo, to thee
Pains onely in Child-bearing were foretold,
And bringing forth, soon recompenc't with joy,
Fruit of thy Womb: On mee the Curse aslope
Glanc'd on the ground, with labour I must earne
My bread; what harm? Idleness had bin worse;
My labour will sustain me; and least Cold
Or Heat should injure us, his timely care
Hath unbesaught provided, and his hands
Cloath'd us unworthie, pitying while he judg'd;
How much more, if we pray him, will his ear
Be open, and his heart to pitie incline,
And teach us further by what means to shun
Th' inclement Seasons, Rain, Ice, Hail and Snow,
Which now the Skie with various Face begins
To shew us in this Mountain, while the Winds
Blow moist and keen, shattering the graceful locks
Of these fair spreading Trees; which bids us seek
Som better shroud, som better warmth to cherish
Our Limbs benumm'd, ere this diurnal Starr
Leave cold the Night, how we his gather'd beams
Reflected, may with matter sere foment,
Or by collision of two bodies grinde
The Air attrite to Fire, as late the Clouds
Justling or pusht with Winds rude in thir shock
Tine the slant Lightning, whose thwart flame driv'n down
Kindles the gummie bark of Firr or Pine,
And sends a comfortable heat from farr,
Which might supplie the Sun: such Fire to use,
And what may else be remedie or cure
To evils which our own misdeeds have wrought,
Hee will instruct us praying, and of Grace
Beseeching him, so as we need not fear
To pass commodiously this life, sustain'd
By him with many comforts, till we end
In dust, our final rest and native home.
What better can we do, then to the place
Repairing where he judg'd us, prostrate fall
Before him reverent, and there confess
Humbly our faults, and pardon beg, with tears
VVatering the ground, and with our sighs the Air
Frequenting, sent from hearts contrite, in sign
Of sorrow unfeign'd, and humiliation meek.
Undoubtedly he will relent and turn
From his displeasure; in whose look serene,
VVhen angry most he seem'd and most severe,
VVhat else but favor, grace, and mercie shon?
So spake our Father penitent, nor EVE
Felt less remorse: they forthwith to the place
Repairing where he judg'd them prostrate fell
Before him reverent, and both confess'd
Humbly thir faults, and pardon beg'd, with tears
VVatering the ground, and with thir sighs the Air
Frequenting, sent from hearts contrite, in sign
Of sorrow unfeign'd, and humiliation meek.
THE END OF THE NINTH BOOK.
PARADISE LOST.
BOOK X.
Thus they in lowliest plight repentant stood
Praying, for from the Mercie-seat above
Prevenient Grace descending had remov'd
The stonie from thir hearts, and made new flesh
Regenerat grow instead, that sighs now breath'd
Unutterable, which the Spirit of prayer
Inspir'd, and wing'd for Heav'n with speedier flight
Then loudest Oratorie: yet thir port
Not of mean suiters, nor important less
Seem'd thir Petition, then when th' ancient Pair
In Fables old, less ancient yet then these,
DEUCALION and chaste PYRRHA to restore
The Race of Mankind drownd, before the Shrine
Of THEMIS stood devout. To Heav'n thir prayers
Flew up, nor missed the way, by envious windes
Blow'n vagabond or frustrate: in they passd
Dimentionless through Heav'nly dores; then clad
With incense, where the Golden Altar fum'd,
By thir great Intercessor, came in sight
Before the Fathers Throne: Them the glad Son
Presenting, thus to intercede began.
See Father, what first fruits on Earth are sprung
From thy implanted Grace in Man, these Sighs
And Prayers, which in this Golden Censer, mixt
With Incense, I thy Priest before thee bring,
Fruits of more pleasing savour from thy seed
Sow'n with contrition in his heart, then those
Which his own hand manuring all the Trees
Of Paradise could have produc't, ere fall'n
From innocence. Now therefore bend thine eare
To supplication, heare his sighs though mute;
Unskilful with what words to pray, let mee
Interpret for him, mee his Advocate
And propitiation, all his works on mee
Good or not good ingraft, my Merit those
Shall perfet, and for these my Death shall pay.
Accept me, and in mee from these receave
The smell of peace toward Mankinde, let him live
Before thee reconcil'd, at least his days
Numberd, though sad, till Death, his doom (which I
To mitigate thus plead, not to reverse)
To better life shall yeeld him, where with mee
All my redeemd may dwell in joy and bliss,
Made one with me as I with thee am one.
To whom the Father, without Cloud, serene.
All thy request for Man, accepted Son,
Obtain, all thy request was my Decree:
But longer in that Paradise to dwell,
The Law I gave to Nature him forbids:
Those pure immortal Elements that know
No gross, no unharmoneous mixture foule,
Eject him tainted now, and purge him off
As a distemper, gross to aire as gross,
And mortal food, as may dispose him best
For dissolution wrought by Sin, that first
Distemperd all things, and of incorrupt
Corrupted. I at first with two fair gifts
Created him endowd, with Happiness
And Immortalitie: that fondly lost,
This other serv'd but to eternize woe;
Till I provided Death; so Death becomes
His final remedie, and after Life
Tri'd in sharp tribulation, and refin'd
By Faith and faithful works, to second Life,
Wak't in the renovation of the just,
Resignes him up with Heav'n and Earth renewd.
But let us call to Synod all the Blest
Through Heav'ns wide bounds; from them I will not hide
My judgments, how with Mankind I proceed,
As how with peccant Angels late they saw;
And in thir state, though firm, stood more confirmd.
He ended, and the Son gave signal high
To the bright Minister that watchd, hee blew
His Trumpet, heard in OREB since perhaps
When God descended, and perhaps once more
To sound at general Doom. Th' Angelic blast
Filld all the Regions: from thir blissful Bowrs
Of AMARANTIN Shade, Fountain or Spring,
By the waters of Life, where ere they sate
In fellowships of joy: the Sons of Light
Hasted, resorting to the Summons high,
And took thir Seats; till from his Throne supream
Th' Almighty thus pronounced his sovran Will.
O Sons, like one of us Man is become
To know both Good and Evil, since his taste
Of that defended Fruit; but let him boast
His knowledge of Good lost, and Evil got,
Happier, had it suffic'd him to have known
Good by it self, and Evil not at all.
He sorrows now, repents, and prayes contrite,
My motions in him, longer then they move,
His heart I know, how variable and vain
Self-left. Least therefore his now bolder hand
Reach also of the Tree of Life, and eat,
And live for ever, dream at least to live
Forever, to remove him I decree,
And send him from the Garden forth to Till
The Ground whence he was taken, fitter soile.
MICHAEL, this my behest have thou in charge,
Take to thee from among the Cherubim
Thy choice of flaming Warriours, least the Fiend
Or in behalf of Man, or to invade
Vacant possession som new trouble raise:
Hast thee, and from the Paradise of God
Without remorse drive out the sinful Pair,
From hallowd ground th' unholie, and denounce
To them and to thir Progenie from thence
Perpetual banishment. Yet least they faint
At the sad Sentence rigorously urg'd,
For I behold them soft'nd and with tears
Bewailing thir excess, all terror hide.
If patiently thy bidding they obey,
Dismiss them not disconsolate; reveale
To ADAM what shall come in future dayes,
As I shall thee enlighten, intermix
My Cov'nant in the Womans seed renewd;
So send them forth, though sorrowing, yet in peace:
And on the East side of the Garden place,
Where entrance up from EDEN easiest climbes,
Cherubic watch, and of a Sword the flame
Wide waving, all approach farr off to fright,
And guard all passage to the Tree of Life:
Least Paradise a receptacle prove
To Spirits foule, and all my Trees thir prey,
With whose stol'n Fruit Man once more to delude.
He ceas'd; and th' Archangelic Power prepar'd
For swift descent, with him the Cohort bright
Of watchful Cherubim; four faces each
Had, like a double JANUS, all thir shape
Spangl'd with eyes more numerous then those
Of ARGUS, and more wakeful then to drouze,
Charm'd with ARCADIAN Pipe, the Pastoral Reed
Of HERMES, or his opiate Rod. Meanwhile
To resalute the World with sacred Light
LEUCOTHEA wak'd, and with fresh dews imbalmd
The Earth, when ADAM and first Matron EVE
Had ended now thir Orisons, and found,
Strength added from above, new hope to spring
Out of despaire, joy, but with fear yet linkt;
Which thus to EVE his welcome words renewd.
EVE, easily may Faith admit, that all
The good which we enjoy, from Heav'n descends
But that from us ought should ascend to Heav'n
So prevalent as to concerne the mind
Of God high blest, or to incline his will,
Hard to belief may seem; yet this will Prayer,
Or one short sigh of humane breath, up-borne
Ev'n to the Seat of God. For since I saught
By Prayer th' offended Deitie to appease,
Kneel'd and before him humbl'd all my heart,
Methought I saw him placable and mild,
Bending his eare; perswasion in me grew
That I was heard with favour; peace returnd
Home to my brest, and to my memorie
His promise, that thy Seed shall bruise our Foe;
Which then not minded in dismay, yet now
Assures me that the bitterness of death
Is past, and we shall live. Whence Haile to thee,
EVE rightly call'd, Mother of all Mankind,
Mother of all things living, since by thee
Man is to live, and all things live for Man.
To whom thus EVE with sad demeanour meek.
Ill worthie I such title should belong
To me transgressour, who for thee ordaind
A help, became thy snare; to mee reproach
Rather belongs, distrust and all dispraise:
But infinite in pardon was my Judge,
That I who first brought Death on all, am grac't
The sourse of life; next favourable thou,
Who highly thus to entitle me voutsaf't,
Farr other name deserving. But the Field
To labour calls us now with sweat impos'd,
Though after sleepless Night; for see the Morn,
All unconcern'd with our unrest, begins
Her rosie progress smiling; let us forth,
I never from thy side henceforth to stray,
Wherere our days work lies, though now enjoind
Laborious, till day droop; while here we dwell,
What can be toilsom in these pleasant Walkes?
Here let us live, though in fall'n state, content.
So spake, so wish'd much-humbl'd EVE, but Fate
Subscrib'd not; Nature first gave Signs, imprest
On Bird, Beast, Aire, Aire suddenly eclips'd
After short blush of Morn; nigh in her sight
The Bird of JOVE, stoopt from his aerie tour,
Two Birds of gayest plume before him drove:
Down from a Hill the Beast that reigns in Woods,
First Hunter then, pursu'd a gentle brace,
Goodliest of all the Forrest, Hart and Hinde;
Direct to th' Eastern Gate was bent thir flight.
ADAM observ'd, and with his Eye the chase
Pursuing, not unmov'd to EVE thus spake.
O EVE, some furder change awaits us nigh,
Which Heav'n by these mute signs in Nature shews
Forerunners of his purpose, or to warn
Us haply too secure of our discharge
From penaltie, because from death releast
Some days; how long, and what till then our life,
Who knows, or more then this, that we are dust,
And thither must return and be no more.
VVhy else this double object in our sight
Of flight pursu'd in th' Air and ore the ground
One way the self-same hour? why in the East
Darkness ere Dayes mid-course, and Morning light
More orient in yon VVestern Cloud that draws
O're the blew Firmament a radiant white,
And slow descends, with somthing heav'nly fraught.
He err'd not, for by this the heav'nly Bands
Down from a Skie of Jasper lighted now
In Paradise, and on a Hill made alt,
A glorious Apparition, had not doubt
And carnal fear that day dimm'd ADAMS eye.
Not that more glorious, when the Angels met
JACOB in MAHANAIM, where he saw
The field Pavilion'd with his Guardians bright;
Nor that which on the flaming Mount appeerd
In DOTHAN, cover'd with a Camp of Fire,
Against the SYRIAN King, who to surprize
One man, Assassin-like had levied Warr,
Warr unproclam'd. The Princely Hierarch
In thir bright stand, there left his Powers to seise
Possession of the Garden; hee alone,
To finde where ADAM shelterd, took his way,
Not unperceav'd of ADAM, who to EVE,
While the great Visitant approachd, thus spake.
EVE, now expect great tidings, which perhaps
Of us will soon determin, or impose
New Laws to be observ'd; for I descrie
From yonder blazing Cloud that veils the Hill
One of the heav'nly Host, and by his Gate
None of the meanest, some great Potentate
Or of the Thrones above, such Majestie
Invests him coming; yet not terrible,
That I should fear, nor sociably mild,
As RAPHAEL, that I should much confide,
But solemn and sublime, whom not to offend,
With reverence I must meet, and thou retire.
He ended; and th' Arch-Angel soon drew nigh,
Not in his shape Celestial, but as Man
Clad to meet Man; over his lucid Armes
A militarie Vest of purple flowd
Livelier then MELIBOEAN, or the graine
Of SARRA, worn by Kings and Hero's old
In time of Truce; IRIS had dipt the wooff;
His starrie Helme unbuckl'd shew'd him prime
In Manhood where Youth ended; by his side
As in a glistering ZODIAC hung the Sword,
Satans dire dread, and in his hand the Spear.
ADAM bowd low, hee Kingly from his State
Inclin'd not, but his coming thus declar'd.
ADAM, Heav'ns high behest no Preface needs:
Sufficient that thy Prayers are heard, and Death,
Then due by sentence when thou didst transgress,
Defeated of his seisure many dayes
Giv'n thee of Grace, wherein thou may'st repent,
And one bad act with many deeds well done
Mayst cover: well may then thy Lord appeas'd
Redeem thee quite from Deaths rapacious claimes;
But longer in this Paradise to dwell
Permits not; to remove thee I am come,
And send thee from the Garden forth to till
The ground whence thou wast tak'n, fitter Soile.
He added not, for ADAM at the newes
Heart-strook with chilling gripe of sorrow stood,
That all his senses bound; EVE, who unseen
Yet all had heard, with audible lament
Discover'd soon the place of her retire.
O unexpected stroke, worse then of Death!
Must I thus leave thee Paradise? thus leave
Thee Native Soile, these happie Walks and Shades,
Fit haunt of Gods? where I had hope to spend,
Quiet though sad, the respit of that day
That must be mortal to us both. O flours,
That never will in other Climate grow,
My early visitation, and my last
At Eev'n, which I bred up with tender hand
From the first op'ning bud, and gave ye Names,
Who now shall reare ye to the Sun, or ranke
Your Tribes, and water from th' ambrosial Fount?
Thee lastly nuptial Bowre, by mee adornd
With what to sight or smell was sweet; from thee
How shall I part, and whither wander down
Into a lower World, to this obscure
And wilde, how shall we breath in other Aire
Less pure, accustomd to immortal Fruits?
Whom thus the Angel interrupted milde.
Lament not EVE, but patiently resigne
What justly thou hast lost; nor set thy heart,
Thus over fond, on that which is not thine;
Thy going is not lonely, with thee goes
Thy Husband, him to follow thou art bound;
Where he abides, think there thy native soile.
ADAM by this from the cold sudden damp
Recovering, and his scatterd spirits returnd,
To MICHAEL thus his humble words addressd.
Celestial, whether among the Thrones, or nam'd
Of them the Highest, for such of shape may seem
Prince above Princes, gently hast thou tould
Thy message, which might else in telling wound,
And in performing end us; what besides
Of sorrow and dejection and despair
Our frailtie can sustain, thy tidings bring,
Departure from this happy place, our sweet
Recess, and onely consolation left
Familiar to our eyes, all places else
Inhospitable appeer and desolate,
Nor knowing us nor known: and if by prayer
Incessant I could hope to change the will
Of him who all things can, I would not cease
To wearie him with my assiduous cries:
But prayer against his absolute Decree
No more availes then breath against the winde,
Blown stifling back on him that breaths it forth:
Therefore to his great bidding I submit.
This most afflicts me, that departing hence,
As from his face I shall be hid, deprivd
His blessed count'nance; here I could frequent,
With worship, place by place where he voutsaf'd
Presence Divine, and to my Sons relate;
On this Mount he appeerd, under this Tree
Stood visible, among these Pines his voice
I heard, here with him at this Fountain talk'd:
So many grateful Altars I would reare
Of grassie Terfe, and pile up every Stone
Of lustre from the brook, in memorie,
Or monument to Ages, and thereon
Offer sweet smelling Gumms & Fruits and Flours:
In yonder nether World where shall I seek
His bright appearances, or footstep trace?
For though I fled him angrie, yet recall'd
To life prolongd and promisd Race, I now
Gladly behold though but his utmost skirts
Of glory, and farr off his steps adore.
To whom thus MICHAEL with regard benigne.
ADAM, thou know'st Heav'n his, and all the Earth
Not this Rock onely; his Omnipresence fills
Land, Sea, and Aire, and every kinde that lives,
Fomented by his virtual power and warmd:
All th' Earth he gave thee to possess and rule,
No despicable gift; surmise not then
His presence to these narrow bounds confin'd
Of Paradise or EDEN: this had been
Perhaps thy Capital Seate, from whence had spred
All generations, and had hither come
From all the ends of th' Earth, to celebrate
And reverence thee thir great Progenitor.
But this praeeminence thou hast lost, brought down
To dwell on eeven ground now with thy Sons:
Yet doubt not but in Vallie and in Plaine
God is as here, and will be found alike
Present, and of his presence many a signe
Still following thee, still compassing thee round
With goodness and paternal Love, his Face
Express, and of his steps the track Divine.
Which that thou mayst beleeve, and be confirmd,
Ere thou from hence depart, know I am sent
To shew thee what shall come in future dayes
To thee and to thy Ofspring; good with bad
Expect to hear, supernal Grace contending
With sinfulness of Men; thereby to learn
True patience, and to temper joy with fear
And pious sorrow, equally enur'd
By moderation either state to beare,
Prosperous or adverse: so shalt thou lead
Safest thy life, and best prepar'd endure
Thy mortal passage when it comes. Ascend
This Hill; let EVE (for I have drencht her eyes)
Here sleep below while thou to foresight wak'st,
As once thou slepst, while Shee to life was formd.
To whom thus ADAM gratefully repli'd.
Ascend, I follow thee, safe Guide, the path
Thou lead'st me, and to the hand of Heav'n submit,
However chast'ning, to the evil turne
My obvious breast, arming to overcom
By suffering, and earne rest from labour won,
If so I may attain. So both ascend
In the Visions of God: It was a Hill
Of Paradise the highest, from whose top
The Hemisphere of Earth in cleerest Ken
Stretcht out to amplest reach of prospect lay.
Not higher that Hill nor wider looking round,
Whereon for different cause the Tempter set
Our second ADAM in the Wilderness,
To shew him all Earths Kingdomes and thir Glory.
His Eye might there command wherever stood
City of old or modern Fame, the Seat
Of mightiest Empire, from the destind Walls
Of CAMBALU, seat of CATHAIAN CAN
And SAMARCHAND by OXUS, TEMIRS Throne,
To PAQUIN of SINAEAN Kings, and thence
To AGRA and LAHOR of great MOGUL
Down to the golden CHERSONESE, or where
The PERSIAN in ECBATAN sate, or since
In HISPAHAN, or where the RUSSIAN KSAR
In MOSCO, or the Sultan in BIZANCE,
TURCHESTAN-born; nor could his eye not ken
Th' Empire of NEGUS to his utmost Port
ERCOCO and the less Maritine Kings
MOMBAZA, and QUILOA, and MELIND,
And SOFALA thought OPHIR, to the Realme
Of CONGO, and ANGOLA fardest South;
Or thence from NIGER Flood to ATLAS Mount
The Kingdoms of ALMANSOR, FEZ, and SUS,
MAROCCO and ALGIERS, and TREMISEN;
On EUROPE thence, and where ROME was to sway
The VVorld: in Spirit perhaps he also saw
Rich MEXICO the seat of MOTEZUME,
And CUSCO in PERU, the richer seat
Of ATABALIPA, and yet unspoil'd
GUIANA, whose great Citie GERYONS Sons
Call EL DORADO: but to nobler sights
MICHAEL from ADAMS eyes the Filme remov'd
VVhich that false Fruit that promis'd clearer sight
Had bred; then purg'd with Euphrasie and Rue
The visual Nerve, for he had much to see;
And from the VVell of Life three drops instill'd.
So deep the power of these Ingredients pierc'd,
Eevn to the inmost seat of mental sight,
That ADAM now enforc't to close his eyes,
Sunk down and all his Spirits became intranst:
But him the gentle Angel by the hand
Soon rais'd, and his attention thus recall'd.
ADAM, now ope thine eyes, and first behold
Th' effects which thy original crime hath wrought
In some to spring from thee, who never touch'd
Th' excepted Tree, nor with the Snake conspir'd,
Nor sinn'd thy sin, yet from that sin derive
Corruption to bring forth more violent deeds.
His eyes he op'nd, and beheld a field,
Part arable and tilth, whereon were Sheaves
New reapt, the other part sheep-walks and foulds;
Ith' midst an Altar as the Land-mark stood
Rustic, of grassie sord; thither anon
A sweatie Reaper from his Tillage brought
First Fruits, the green Eare, and the yellow Sheaf,
Uncull'd, as came to hand; a Shepherd next
More meek came with the Firstlings of his Flock
Choicest and best; then sacrificing, laid
The Inwards and thir Fat, with Incense strew'd,
On the cleft Wood, and all due Rites perform'd.
His Offring soon propitious Fire from Heav'n
Consum'd with nimble glance, and grateful steame;
The others not, for his was not sincere;
Whereat hee inlie rag'd, and as they talk'd,
Smote him into the Midriff with a stone
That beat out life; he fell, and deadly pale
Groand out his Soul with gushing bloud effus'd.
Much at that sight was ADAM in his heart
Dismai'd, and thus in haste to th' Angel cri'd.
O Teacher, some great mischief hath befall'n
To that meek man, who well had sacrific'd;
Is Pietie thus and pure Devotion paid?
T' whom MICHAEL thus, hee also mov'd, repli'd.
These two are Brethren, ADAM, and to come
Out of thy loyns; th' unjust the just hath slain,
For envie that his Brothers Offering found
From Heav'n acceptance; but the bloodie Fact
Will be aveng'd, and th' others Faith approv'd
Loose no reward, though here thou see him die,
Rowling in dust and gore. To which our Sire.
Alas, both for the deed and for the cause!
But have I now seen Death? Is this the way
I must return to native dust? O sight
Of terrour, foul and ugly to behold,
Horrid to think, how horrible to feel!
To whom thus MICHAEL. Death thou hast seen
In his first shape on man; but many shapes
Of Death, and many are the wayes that lead
To his grim Cave, all dismal; yet to sense
More terrible at th' entrance then within.
Some, as thou saw'st, by violent stroke shall die,
By Fire, Flood, Famin, by Intemperance more
In Meats and Drinks, which on the Earth shal bring
Diseases dire, of which a monstrous crew
Before thee shall appear; that thou mayst know
What miserie th' inabstinence of EVE
Shall bring on men. Immediately a place
Before his eyes appeard, sad, noysom, dark,
A Lazar-house it seemd, wherein were laid
Numbers of all diseas'd, all maladies
Of gastly Spasm, or racking torture, qualmes
Of heart-sick Agonie, all feavorous kinds,
Convulsions, Epilepsies, fierce Catarrhs,
Intestin Stone and Ulcer, Colic pangs,
Dropsies, and Asthma's, and Joint-racking Rheums.
Dire was the tossing, deep the groans, despair
Tended the sick busiest from Couch to Couch;
And over them triumphant Death his Dart
Shook, but delaid to strike, though oft invok't
With vows, as thir chief good, and final hope.
Sight so deform what heart of Rock could long
Drie-ey'd behold? ADAM could not, but wept,
Though not of Woman born; compassion quell'd
His best of Man, and gave him up to tears
A space, till firmer thoughts restraind excess,
And scarce recovering words his plaint renew'd.
O miserable Mankind, to what fall
Degraded, to what wretched state reserv'd?
Better end heer unborn. Why is life giv'n
To be thus wrested from us? rather why
Obtruded on us thus? who if we knew
What we receive, would either not accept
Life offer'd, or soon beg to lay it down,
Glad to be so dismist in peace. Can thus
Th' Image of God in man created once
So goodly and erect, though faultie since,
To such unsightly sufferings be debas't
Under inhuman pains? Why should not Man,
Retaining still Divine similitude
In part, from such deformities be free,
And for his Makers Image sake exempt?
Thir Makers Image, answerd MICHAEL, then
Forsook them, when themselves they villifi'd
To serve ungovern'd appetite, and took
His Image whom they serv'd, a brutish vice,
Inductive mainly to the sin of EVE.
Therefore so abject is thir punishment,
Disfiguring not Gods likeness, but thir own,
Or if his likeness, by themselves defac't
While they pervert pure Natures healthful rules
To loathsom sickness, worthily, since they
Gods Image did not reverence in themselves.
I yeild it just, said ADAM, and submit.
But is there yet no other way, besides
These painful passages, how we may come
To Death, and mix with our connatural dust?
There is, said MICHAEL, if thou well observe
The rule of not too much, by temperance taught
In what thou eatst and drinkst, seeking from thence
Due nourishment, not gluttonous delight,
Till many years over thy head return:
So maist thou live, till like ripe Fruit thou drop
Into thy Mothers lap, or be with ease
Gatherd, not harshly pluckt, for death mature:
This is old age; but then thou must outlive
Thy youth, thy strength, thy beauty, which will change
To witherd weak & gray; thy Senses then
Obtuse, all taste of pleasure must forgoe,
To what thou hast, and for the Aire of youth
Hopeful and cheerful, in thy blood will reigne
A melancholly damp of cold and dry
To waigh thy spirits down, and last consume
The Balme of Life. To whom our Ancestor.
Henceforth I flie not Death, nor would prolong
Life much, bent rather how I may be quit
Fairest and easiest of this combrous charge,
Which I must keep till my appointed day
Of rendring up. MICHAEL to him repli'd.
Nor love thy Life, nor hate; but what thou livst
Live well, how long or short permit to Heav'n:
And now prepare thee for another sight.
He lookd and saw a spacious Plaine, whereon
Were Tents of various hue; by some were herds
Of Cattel grazing: others, whence the sound
Of Instruments that made melodious chime
Was heard, of Harp and Organ; and who moovd
Thir stops and chords was seen: his volant touch
Instinct through all proportions low and high
Fled and pursu'd transverse the resonant fugue.
In other part stood one who at the Forge
Labouring, two massie clods of Iron and Brass
Had melted (whether found where casual fire
Had wasted woods on Mountain or in Vale,
Down to the veins of Earth, thence gliding hot
To som Caves mouth, or whether washt by stream
From underground) the liquid Ore he dreind
Into fit moulds prepar'd; from which he formd
First his own Tooles; then, what might else be wrought
Fulfil or grav'n in mettle. After these,
But on the hether side a different sort
From the high neighbouring Hills, which was thir Seat,
Down to the Plain descended: by thir guise
Just men they seemd, and all thir study bent
To worship God aright, and know his works
Not hid, nor those things lost which might preserve
Freedom and Peace to men: they on the Plain
Long had not walkt, when from the Tents behold
A Beavie of fair Women, richly gay
In Gems and wanton dress; to the Harp they sung
Soft amorous Ditties, and in dance came on:
The Men though grave, ey'd them, and let thir eyes
Rove without rein, till in the amorous Net
Fast caught, they lik'd, and each his liking chose;
And now of love they treat till th' Eevning Star
Loves Harbinger appeerd; then all in heat
They light the Nuptial Torch, and bid invoke
Hymen, then first to marriage Rites invok't;
With Feast and Musick all the Tents resound.
Such happy interview and fair event
Of love & youth not lost, Songs, Garlands, Flours,
And charming Symphonies attach'd the heart
Of ADAM, soon enclin'd to admit delight,
The bent of Nature; which he thus express'd.
True opener of mine eyes, prime Angel blest,
Much better seems this Vision, and more hope
Of peaceful dayes portends, then those two past;
Those were of hate and death, or pain much worse,
Here Nature seems fulfilld in all her ends.
To whom thus MICHAEL. Judg not what is best
By pleasure, though to Nature seeming meet,
Created, as thou art, to nobler end
Holie and pure, conformitie divine.
Those Tents thou sawst so pleasant, were the Tents
Of wickedness, wherein shall dwell his Race
Who slew his Brother; studious they appere
Of Arts that polish Life, Inventers rare,
Unmindful of thir Maker, though his Spirit
Taught them, but they his gifts acknowledg'd none.
Yet they a beauteous ofspring shall beget;
For that fair femal Troop thou sawst, that seemd
Of Goddesses, so blithe, so smooth, so gay,
Yet empty of all good wherein consists
Womans domestic honour and chief praise;
Bred onely and completed to the taste
Of lustful apperence, to sing, to dance,
To dress, and troule the Tongue, and roule the Eye.
To these that sober Race of Men, whose lives
Religious titl'd them the Sons of God,
Shall yeild up all thir vertue, all thir fame
Ignobly, to the trains and to the smiles
Of these fair Atheists, and now swim in joy,
(Erelong to swim at larg) and laugh; for which
The world erelong a world of tears must weepe.
To whom thus ADAM of short joy bereft.
O pittie and shame, that they who to live well
Enterd so faire, should turn aside to tread
Paths indirect, or in the mid way faint!
But still I see the tenor of Mans woe
Holds on the same, from Woman to begin.
From Mans effeminate slackness it begins,
Said th' Angel, who should better hold his place
By wisdome, and superiour gifts receavd.
But now prepare thee for another Scene.
He lookd and saw wide Territorie spred
Before him, Towns, and rural works between,
Cities of Men with lofty Gates and Towrs,
Concours in Arms, fierce Faces threatning Warr,
Giants of mightie Bone, and bould emprise;
Part wield thir Arms, part courb the foaming Steed,
Single or in Array of Battel rang'd
Both Horse and Foot, nor idely mustring stood;
One way a Band select from forage drives
A herd of Beeves, faire Oxen and faire Kine
From a fat Meddow ground; or fleecy Flock,
Ewes and thir bleating Lambs over the Plaine,
Thir Bootie; scarce with Life the Shepherds flye,
But call in aide, which tacks a bloody Fray;
With cruel Tournament the Squadrons joine;
Where Cattel pastur'd late, now scatterd lies
With Carcasses and Arms th' ensanguind Field
Deserted: Others to a Citie strong
Lay Siege, encampt; by Batterie, Scale, and Mine,
Assaulting; others from the Wall defend
With Dart and Jav'lin, Stones and sulfurous Fire;
On each hand slaughter and gigantic deeds.
In other part the scepter'd Haralds call
To Council in the Citie Gates: anon
Grey-headed men and grave, with Warriours mixt,
Assemble, and Harangues are heard, but soon
In factious opposition, till at last
Of middle Age one rising, eminent
In wise deport, spake much of Right and Wrong,
Of Justice, of Religion, Truth and Peace,
And Judgement from above: him old and young
Exploded, and had seiz'd with violent hands,
Had not a Cloud descending snatch'd him thence
Unseen amid the throng: so violence
Proceeded, and Oppression, and Sword-Law
Through all the Plain, and refuge none was found.
ADAM was all in tears, and to his guide
Lamenting turnd full sad; O what are these,
Deaths Ministers, not Men, who thus deal Death
Inhumanly to men, and multiply
Ten thousand fould the sin of him who slew
His Brother; for of whom such massacher
Make they but of thir Brethren, men of men?
But who was that Just Man, whom had not Heav'n
Rescu'd, had in his Righteousness bin lost?
To whom thus MICHAEL; These are the product
Of those ill-mated Marriages thou saw'st;
Where good with bad were matcht, who of themselves
Abhor to joyn; and by imprudence mixt,
Produce prodigious Births of bodie or mind.
Such were these Giants, men of high renown;
For in those dayes Might onely shall be admir'd,
And Valour and Heroic Vertu call'd;
To overcome in Battel, and subdue
Nations, and bring home spoils with infinite
Man-slaughter, shall be held the highest pitch
Of human Glorie, and for Glorie done
Of triumph, to be styl'd great Conquerours,
Patrons of Mankind, Gods, and Sons of Gods,
Destroyers rightlier call'd and Plagues of men.
Thus Fame shall be achiev'd, renown on Earth,
And what most merits fame in silence hid.
But hee the seventh from thee, whom thou beheldst
The onely righteous in a World perverse,
And therefore hated, therefore so beset
With Foes for daring single to be just,
And utter odious Truth, that God would come
To judge them with his Saints: Him the most High
Rapt in a balmie Cloud with winged Steeds
Did, as thou sawst, receave, to walk with God
High in Salvation and the Climes of bliss,
Exempt from Death; to shew thee what reward
Awaits the good, the rest what punishment;
Which now direct thine eyes and soon behold.
He look'd, & saw the face of things quite chang'd;
The brazen Throat of Warr had ceast to roar,
All now was turn'd to jollitie and game,
To luxurie and riot, feast and dance,
Marrying or prostituting, as befell,
Rape or Adulterie, where passing faire
Allurd them; thence from Cups to civil Broiles.
At length a Reverend Sire among them came,
And of thir doings great dislike declar'd,
And testifi'd against thir wayes; hee oft
Frequented thir Assemblies, whereso met,
Triumphs or Festivals, and to them preachd
Conversion and Repentance, as to Souls
In prison under Judgements imminent:
But all in vain: which when he saw, he ceas'd
Contending, and remov'd his Tents farr off;
Then from the Mountain hewing Timber tall,
Began to build a Vessel of huge bulk,
Measur'd by Cubit, length, & breadth, and highth,
Smeard round with Pitch, and in the side a dore
Contriv'd, and of provisions laid in large
For Man and Beast: when loe a wonder strange!
Of everie Beast, and Bird, and Insect small
Came seavens, and pairs, and enterd in, as taught
Thir order; last the Sire, and his three Sons
With thir four Wives, and God made fast the dore.
Meanwhile the Southwind rose, & with black wings
Wide hovering, all the Clouds together drove
From under Heav'n; the Hills to their supplie
Vapour, and Exhalation dusk and moist,
Sent up amain; and now the thick'nd Skie
Like a dark Ceeling stood; down rush'd the Rain
Impetuous, and continu'd till the Earth
No more was seen; the floating Vessel swum
Uplifted; and secure with beaked prow
Rode tilting o're the Waves, all dwellings else
Flood overwhelmd, and them with all thir pomp
Deep under water rould; Sea cover'd Sea,
Sea without shoar; and in thir Palaces
Where luxurie late reign'd, Sea-monsters whelp'd
And stabl'd; of Mankind, so numerous late,
All left, in one small bottom swum imbark't.
How didst thou grieve then, ADAM, to behold
The end of all thy Ofspring, end so sad,
Depopulation; thee another Floud,
Of tears and sorrow a Floud thee also drown'd,
And sunk thee as thy Sons; till gently reard
By th' Angel, on thy feet thou stoodst at last,
Though comfortless, as when a Father mourns
His Childern, all in view destroyd at once;
And scarce to th' Angel utterdst thus thy plaint.
O Visions ill foreseen! better had I
Liv'd ignorant of future, so had borne
My part of evil onely, each dayes lot
Anough to bear; those now, that were dispenst
The burd'n of many Ages, on me light
At once, by my foreknowledge gaining Birth
Abortive, to torment me ere thir being,
With thought that they must be. Let no man seek
Henceforth to be foretold what shall befall
Him or his Childern, evil he may be sure,
Which neither his foreknowing can prevent,
And hee the future evil shall no less
In apprehension then in substance feel
Grievous to bear: but that care now is past,
Man is not whom to warne: those few escap't
Famin and anguish will at last consume
Wandring that watrie Desert: I had hope
When violence was ceas't, and Warr on Earth,
All would have then gon well, peace would have crownd
With length of happy days the race of man;
But I was farr deceav'd; for now I see
Peace to corrupt no less then Warr to waste.
How comes it thus? unfould, Celestial Guide,
And whether here the Race of man will end.
To whom thus MICHAEL. Those whom last thou sawst
In triumph and luxurious wealth, are they
First seen in acts of prowess eminent
And great exploits, but of true vertu void;
Who having spilt much blood, and don much waste
Subduing Nations, and achievd thereby
Fame in the World, high titles, and rich prey,
Shall change thir course to pleasure, ease, and sloth,
Surfet, and lust, till wantonness and pride
Raise out of friendship hostil deeds in Peace.
The conquerd also, and enslav'd by Warr
Shall with thir freedom lost all vertu loose
And feare of God, from whom thir pietie feign'd
In sharp contest of Battel found no aide
Against invaders; therefore coold in zeale
Thenceforth shall practice how to live secure,
Worldlie or dissolute, on what thir Lords
Shall leave them to enjoy; for th' Earth shall bear
More then anough, that temperance may be tri'd:
So all shall turn degenerate, all deprav'd,
Justice and Temperance, Truth and Faith forgot;
One Man except, the onely Son of light
In a dark Age, against example good,
Against allurement, custom, and a World
Offended; fearless of reproach and scorn,
Or violence, hee of thir wicked wayes
Shall them admonish, and before them set
The paths of righteousness, how much more safe,
And full of peace, denouncing wrauth to come
On thir impenitence; and shall returne
Of them derided, but of God observd
The one just Man alive; by his command
Shall build a wondrous Ark, as thou beheldst,
To save himself and houshold from amidst
A World devote to universal rack.
No sooner hee with them of Man and Beast
Select for life shall in the Ark be lodg'd,
And shelterd round, but all the Cataracts
Of Heav'n set open on the Earth shall powre
Raine day and night, all fountaines of the Deep
Broke up, shall heave the Ocean to usurp
Beyond all bounds, till inundation rise
Above the highest Hills: then shall this Mount
Of Paradise by might of Waves be moovd
Out of his place, pushd by the horned floud,
With all his verdure spoil'd, and Trees adrift
Down the great River to the op'ning Gulf,
And there take root an Iland salt and bare,
The haunt of Seales and Orcs, and Sea-mews clang.
To teach thee that God attributes to place
No sanctitie, if none be thither brought
By Men who there frequent, or therein dwell.
And now what further shall ensue, behold.
He lookd, and saw the Ark hull on the floud,
Which now abated, for the Clouds were fled,
Drivn by a keen North-winde, that blowing drie
Wrinkl'd the face of Deluge, as decai'd;
And the cleer Sun on his wide watrie Glass
Gaz'd hot, and of the fresh Wave largely drew,
As after thirst, which made thir flowing shrink
From standing lake to tripping ebbe, that stole
With soft foot towards the deep, who now had stopt
His Sluces, as the Heav'n his windows shut.
The Ark no more now flotes, but seems on ground
Fast on the top of som high mountain fixt.
And now the tops of Hills as Rocks appeer;
With clamor thence the rapid Currents drive
Towards the retreating Sea thir furious tyde.
Forthwith from out the Arke a Raven flies,
And after him, the surer messenger,
A Dove sent forth once and agen to spie
Green Tree or ground whereon his foot may light;
The second time returning, in his Bill
An Olive leafe he brings, pacific signe:
Anon drie ground appeers, and from his Arke
The ancient Sire descends with all his Train;
Then with uplifted hands, and eyes devout,
Grateful to Heav'n, over his head beholds
A dewie Cloud, and in the Cloud a Bow
Conspicuous with three lifted colours gay,
Betok'ning peace from God, and Cov'nant new.
Whereat the heart of ADAM erst so sad
Greatly rejoyc'd, and thus his joy broke forth.
O thou that future things canst represent
As present, Heav'nly instructer, I revive
At this last sight, assur'd that Man shall live
With all the Creatures, and thir seed preserve.
Farr less I now lament for one whole World
Of wicked Sons destroyd, then I rejoyce
For one Man found so perfet and so just,
That God voutsafes to raise another World
From him, and all his anger to forget.
But say, what mean those colourd streaks in Heavn,
Distended as the Brow of God appeas'd,
Or serve they as a flourie verge to binde
The fluid skirts of that same watrie Cloud,
Least it again dissolve and showr the Earth?
To whom th' Archangel. Dextrously thou aim'st;
So willingly doth God remit his Ire,
Though late repenting him of Man deprav'd,
Griev'd at his heart, when looking down he saw
The whole Earth fill'd with violence, and all flesh
Corrupting each thir way; yet those remoov'd,
Such grace shall one just Man find in his sight,
That he relents, not to blot out mankind,
And makes a Covenant never to destroy
The Earth again by flood, nor let the Sea
Surpass his bounds, nor Rain to drown the World
With Man therein or Beast; but when he brings
Over the Earth a Cloud, will therein set
His triple-colour'd Bow, whereon to look
And call to mind his Cov'nant: Day and Night,
Seed time and Harvest, Heat and hoary Frost
Shall hold thir course, till fire purge all things new,
Both Heav'n and Earth, wherein the just shall dwell.
Thus thou hast seen one World begin and end;
And Man as from a second stock proceed.
Much thou hast yet to see, but I perceave
Thy mortal sight to faile; objects divine
Must needs impaire and wearie human sense:
Henceforth what is to com I will relate,
Thou therefore give due audience, and attend.
This second sours of Men, while yet but few,
And while the dread of judgement past remains
Fresh in thir mindes, fearing the Deitie,
With some regard to what is just and right
Shall lead thir lives, and multiplie apace,
Labouring the soile, and reaping plenteous crop,
Corn wine and oyle; and from the herd or flock,
Oft sacrificing Bullock, Lamb, or Kid,
With large Wine-offerings pour'd, and sacred Feast
Shal spend thir dayes in joy unblam'd, and dwell
Long time in peace by Families and Tribes
Under paternal rule; till one shall rise
Of proud ambitious heart, who not content
With fair equalitie, fraternal state,
Will arrogate Dominion undeserv'd
Over his brethren, and quite dispossess
Concord and law of Nature from the Earth;
Hunting (and Men not Beasts shall be his game)
With Warr and hostile snare such as refuse
Subjection to his Empire tyrannous:
A mightie Hunter thence he shall be styl'd
Before the Lord, as in despite of Heav'n,
Or from Heav'n claming second Sovrantie;
And from Rebellion shall derive his name,
Though of Rebellion others he accuse.
Hee with a crew, whom like Ambition joyns
With him or under him to tyrannize,
Marching from EDEN towards the West, shall finde
The Plain, wherein a black bituminous gurge
Boiles out from under ground, the mouth of Hell;
Of Brick, and of that stuff they cast to build
A Citie & Towre, whose top may reach to Heav'n;
And get themselves a name, least far disperst
In foraign Lands thir memorie be lost,
Regardless whether good or evil fame.
But God who oft descends to visit men
Unseen, and through thir habitations walks
To mark thir doings, them beholding soon,
Comes down to see thir Citie, ere the Tower
Obstruct Heav'n Towrs, and in derision sets
Upon thir Tongues a various Spirit to rase
Quite out thir Native Language, and instead
To sow a jangling noise of words unknown:
Forthwith a hideous gabble rises loud
Among the Builders; each to other calls
Not understood, till hoarse, and all in rage,
As mockt they storm; great laughter was in Heav'n
And looking down, to see the hubbub strange
And hear the din; thus was the building left
Ridiculous, and the work Confusion nam'd.
Whereto thus ADAM fatherly displeas'd.
O execrable Son so to aspire
Above his Brethren, to himself affirming
Authoritie usurpt, from God not giv'n:
He gave us onely over Beast, Fish, Fowl
Dominion absolute; that right we hold
By his donation; but Man over men
He made not Lord; such title to himself
Reserving, human left from human free.
But this Usurper his encroachment proud
Stayes not on Man; to God his Tower intends
Siege and defiance: Wretched man! what food
Will he convey up thither to sustain
Himself and his rash Armie, where thin Aire
Above the Clouds will pine his entrails gross,
And famish him of Breath, if not of Bread?
To whom thus MICHAEL. Justly thou abhorr'st
That Son, who on the quiet state of men
Such trouble brought, affecting to subdue
Rational Libertie; yet know withall,
Since thy original lapse, true Libertie
Is lost, which alwayes with right Reason dwells
Twinn'd, and from her hath no dividual being:
Reason in man obscur'd, or not obeyd,
Immediately inordinate desires
And upstart Passions catch the Government
From Reason, and to servitude reduce
Man till then free. Therefore since hee permits
Within himself unworthie Powers to reign
Over free Reason, God in Judgement just
Subjects him from without to violent Lords;
Who oft as undeservedly enthrall
His outward freedom: Tyrannie must be,
Though to the Tyrant thereby no excuse.
Yet somtimes Nations will decline so low
From vertue, which is reason, that no wrong,
But Justice, and some fatal curse annext
Deprives them of thir outward libertie,
Thir inward lost: Witness th' irreverent Son
Of him who built the Ark, who for the shame
Don to his Father, heard this heavie curse,
SERVANT OF SERVANTS, on his vitious Race.
Thus will this latter, as the former World,
Still tend from bad to worse, till God at last
Wearied with their iniquities, withdraw
His presence from among them, and avert
His holy Eyes; resolving from thenceforth
To leave them to thir own polluted wayes;
And one peculiar Nation to select
From all the rest, of whom to be invok'd,
A Nation from one faithful man to spring:
Him on this side EUPHRATES yet residing,
Bred up in Idol-worship; O that men
(Canst thou believe?) should be so stupid grown,
While yet the Patriark liv'd, who scap'd the Flood,
As to forsake the living God, and fall
To-worship thir own work in Wood and Stone
For Gods! yet him God the most High voutsafes
To call by Vision from his Fathers house,
His kindred and false Gods, into a Land
Which he will shew him, and from him will raise
A mightie Nation, and upon him showre
His benediction so, that in his Seed
All Nations shall be blest; hee straight obeys,
Not knowing to what Land, yet firm believes:
I see him, but thou canst not, with what Faith
He leaves his Gods, his Friends, and native Soile
UR of CHALDAEA, passing now the Ford
To HARAN, after him a cumbrous Train
Of Herds and Flocks, and numerous servitude;
Not wandring poor, but trusting all his wealth
With God, who call'd him, in a land unknown.
CANAAN he now attains, I see his Tents
Pitcht about SECHEM, and the neighbouring Plaine
Of MOREB; there by promise he receaves
Gift to his Progenie of all that Land;
From HAMATH Northward to the Desert South
(Things by thir names I call, though yet unnam'd)
From HERMON East to the great Western Sea,
Mount HERMON, yonder Sea, each place behold
In prospect, as I point them; on the shoare
Mount CARMEL; here the double-founted stream
JORDAN, true limit Eastward; but his Sons
Shall dwell to SENIR, that long ridge of Hills.
This ponder, that all Nations of the Earth
Shall in his Seed be blessed; by that Seed
Is meant thy great deliverer, who shall bruise
The Serpents head; whereof to thee anon
Plainlier shall be reveald. This Patriarch blest,
Whom FAITHFUL ABRAHAM due time shall call,
A Son, and of his Son a Grand-childe leaves,
Like him in faith, in wisdom, and renown;
The Grandchilde with twelve Sons increast, departs
From CANAAN, to a Land hereafter call'd
EGYPT, divided by the River NILE;
See where it flows, disgorging at seaven mouthes
Into the Sea: to sojourn in that Land
He comes invited by a yonger Son
In time of dearth, a Son whose worthy deeds
Raise him to be the second in that Realme
Of PHARAO: there he dies, and leaves his Race
Growing into a Nation, and now grown
Suspected to a sequent King, who seeks
To stop thir overgrowth, as inmate guests
Too numerous; whence of guests he makes them slaves
Inhospitably, and kills thir infant Males:
Till by two brethren (those two brethren call
MOSES and AARON) sent from God to claime
His people from enthralment, they return
With glory and spoile back to thir promis'd Land.
But first the lawless Tyrant, who denies
To know thir God, or message to regard,
Must be compelld by Signes and Judgements dire;
To blood unshed the Rivers must be turnd,
Frogs, Lice and Flies must all his Palace fill
With loath'd intrusion, and fill all the land;
His Cattel must of Rot and Murren die,
Botches and blaines must all his flesh imboss,
And all his people; Thunder mixt with Haile,
Haile mixt with fire must rend th' EGYPTIAN Skie
And wheel on th' Earth, devouring where it rouls;
What it devours not, Herb, or Fruit, or Graine,
A darksom Cloud of Locusts swarming down
Must eat, and on the ground leave nothing green:
Darkness must overshadow all his bounds,
Palpable darkness, and blot out three dayes;
Last with one midnight stroke all the first-born
Of EGYPT must lie dead. Thus with ten wounds
This River-dragon tam'd at length submits
To let his sojourners depart, and oft
Humbles his stubborn heart, but still as Ice
More hard'nd after thaw, till in his rage
Pursuing whom he late dismissd, the Sea
Swallows him with his Host, but them lets pass
As on drie land between two christal walls,
Aw'd by the rod of MOSES so to stand
Divided, till his rescu'd gain thir shoar:
Such wondrous power God to his Saint will lend,
Though present in his Angel, who shall goe
Before them in a Cloud, and Pillar of Fire,
To guide them in thir journey, and remove
Behinde them, while th' obdurat King pursues:
All night he will pursue, but his approach
Darkness defends between till morning Watch;
Then through the Firey Pillar and the Cloud
God looking forth will trouble all his Host
And craze thir Chariot wheels: when by command
MOSES once more his potent Rod extends
Over the Sea; the Sea his Rod obeys;
On thir imbattelld ranks the Waves return,
And overwhelm thir Warr: the Race elect
Safe towards CANAAN from the shoar advance
Through the wilde Desert, not the readiest way,
Least entring on the CANAANITE allarmd
Warr terrifie them inexpert, and feare
Return them back to EGYPT, choosing rather
Inglorious life with servitude; for life
To noble and ignoble is more sweet
Untraind in Armes, where rashness leads not on.
This also shall they gain by thir delay
In the wide Wilderness, there they shall found
Thir government, and thir great Senate choose
Through the twelve Tribes, to rule by Laws ordaind:
God from the Mount of SINAI, whose gray top
Shall tremble, he descending, will himself
In Thunder Lightning and loud Trumpets sound
Ordaine them Lawes; part such as appertaine
To civil Justice, part religious Rites
Of sacrifice, informing them, by types
And shadowes, of that destind Seed to bruise
The Serpent, by what meanes he shall achieve
Mankinds deliverance. But the voice of God
To mortal eare is dreadful; they beseech
That MOSES might report to them his will,
And terror cease; he grants them thir desire,
Instructed that to God is no access
Without Mediator, whose high Office now
MOSES in figure beares, to introduce
One greater, of whose day he shall foretell,
And all the Prophets in thir Age the times
Of great MESSIAH shall sing. Thus Laws and Rites
Establisht, such delight hath God in Men
Obedient to his will, that he voutsafes
Among them to set up his Tabernacle,
The holy One with mortal Men to dwell:
By his prescript a Sanctuary is fram'd
Of Cedar, overlaid with Gold, therein
An Ark, and in the Ark his Testimony,
The Records of his Cov'nant, over these
A Mercie-seat of Gold between the wings
Of two bright Cherubim, before him burn
Seaven Lamps as in a Zodiac representing
The Heav'nly fires; over the Tent a Cloud
Shall rest by Day, a fierie gleame by Night,
Save when they journie, and at length they come,
Conducted by his Angel to the Land
Promisd to ABRAHAM and his Seed: the rest
Were long to tell, how many Battels fought,
How many Kings destroyd, and Kingdoms won,
Or how the Sun shall in mid Heav'n stand still
A day entire, and Nights due course adjourne,
Mans voice commanding, Sun in GIBEON stand,
And thou Moon in the vale of AIALON,
Till ISRAEL overcome; so call the third
From ABRAHAM, Son of ISAAC, and from him
His whole descent, who thus shall CANAAN win.
Here ADAM interpos'd. O sent from Heav'n,
Enlightner of my darkness, gracious things
Thou hast reveald, those chiefly which concerne
Just ABRAHAM and his Seed: now first I finde
Mine eyes true op'ning, and my heart much eas'd,
Erwhile perplext with thoughts what would becom
Of mee and all Mankind; but now I see
His day, in whom all Nations shall be blest,
Favour unmerited by me, who sought
Forbidd'n knowledge by forbidd'n means.
This yet I apprehend not, why to those
Among whom God will deigne to dwell on Earth
So many and so various Laws are giv'n;
So many Laws argue so many sins
Among them; how can God with such reside?
To whom thus MICHAEL. Doubt not but that sin
Will reign among them, as of thee begot;
And therefore was Law given them to evince
Thir natural pravitie, by stirring up
Sin against Law to fight; that when they see
Law can discover sin, but not remove,
Save by those shadowie expiations weak,
The bloud of Bulls and Goats, they may conclude
Some bloud more precious must be paid for Man,
Just for unjust, that in such righteousness
To them by Faith imputed, they may finde
Justification towards God, and peace
Of Conscience, which the Law by Ceremonies
Cannot appease, nor Man the moral part
Perform, and not performing cannot live.
So Law appears imperfet, and but giv'n
With purpose to resign them in full time
Up to a better Cov'nant, disciplin'd
From shadowie Types to Truth, from Flesh to Spirit,
From imposition of strict Laws, to free
Acceptance of large Grace, from servil fear
To filial, works of Law to works of Faith.
And therefore shall not MOSES, though of God
Highly belov'd, being but the Minister
Of Law, his people into CANAAN lead;
But JOSHUA whom the Gentiles JESUS call,
His Name and Office bearing, who shall quell
The adversarie Serpent, and bring back
Through the worlds wilderness long wanderd man
Safe to eternal Paradise of rest.
Meanwhile they in thir earthly CANAAN plac't
Long time shall dwell and prosper, but when sins
National interrupt thir public peace,
Provoking God to raise them enemies:
From whom as oft he saves them penitent
By Judges first, then under Kings; of whom
The second, both for pietie renownd
And puissant deeds, a promise shall receive
Irrevocable, that his Regal Throne
For ever shall endure; the like shall sing
All Prophecie, That of the Royal Stock
Of DAVID (so I name this King) shall rise
A Son, the Womans Seed to thee foretold,
Foretold to ABRAHAM, as in whom shall trust
All Nations, and to Kings foretold, of Kings
The last, for of his Reign shall be no end.
But first a long succession must ensue,
And his next Son for Wealth and Wisdom fam'd,
The clouded Ark of God till then in Tents
Wandring, shall in a glorious Temple enshrine.
Such follow him, as shall be registerd
Part good, part bad, of bad the longer scrowle,
Whose foul Idolatries, and other faults
Heapt to the popular summe, will so incense
God, as to leave them, and expose thir Land,
Thir Citie, his Temple, and his holy Ark
With all his sacred things, a scorn and prey
To that proud Citie, whose high Walls thou saw'st
Left in confusion, BABYLON thence call'd.
There in captivitie he lets them dwell
The space of seventie years, then brings them back,
Remembring mercie, and his Cov'nant sworn
To DAVID, stablisht as the dayes of Heav'n.
Returnd from BABYLON by leave of Kings
Thir Lords, whom God dispos'd, the house of God
They first re-edifie, and for a while
In mean estate live moderate, till grown
In wealth and multitude, factious they grow;
But first among the Priests dissension springs,
Men who attend the Altar, and should most
Endeavour Peace: thir strife pollution brings
Upon the Temple it self: at last they seise
The Scepter, and regard not DAVIDS Sons,
Then loose it to a stranger, that the true
Anointed King MESSIAH might be born
Barr'd of his right; yet at his Birth a Starr
Unseen before in Heav'n proclaims him com,
And guides the Eastern Sages, who enquire
His place, to offer Incense, Myrrh, and Gold;
His place of birth a solemn Angel tells
To simple Shepherds, keeping watch by night;
They gladly thither haste, and by a Quire
Of squadrond Angels hear his Carol sung.
A Virgin is his Mother, but his Sire
The Power of the most High; he shall ascend
The Throne hereditarie, and bound his Reign
With earths wide bounds, his glory with the Heav'ns.
He ceas'd, discerning ADAM with such joy
Surcharg'd, as had like grief bin dew'd in tears,
Without the vent of words, which these he breathd.
O Prophet of glad tidings, finisher
Of utmost hope! now clear I understand
What oft my steddiest thoughts have searcht in vain,
Why our great expectation should be call'd
The seed of Woman: Virgin Mother, Haile,
High in the love of Heav'n, yet from my Loynes
Thou shalt proceed, and from thy Womb the Son
Of God most High; So God with man unites.
Needs must the Serpent now his capital bruise
Expect with mortal paine: say where and when
Thir fight, what stroke shall bruise the Victors heel.
To whom thus MICHAEL. Dream not of thir fight,
As of a Duel, or the local wounds
Of head or heel: not therefore joynes the Son
Manhood to God-head, with more strength to foil
Thy enemie; nor so is overcome
SATAN, whose fall from Heav'n, a deadlier bruise,
Disabl'd not to give thee thy deaths wound:
Which hee, who comes thy Saviour, shall recure,
Not by destroying SATAN, but his works
In thee and in thy Seed: nor can this be,
But by fulfilling that which thou didst want,
Obedience to the Law of God, impos'd
On penaltie of death, and suffering death,
The penaltie to thy transgression due,
And due to theirs which out of thine will grow:
So onely can high Justice rest appaid.
The Law of God exact he shall fulfill
Both by obedience and by love, though love
Alone fulfill the Law; thy punishment
He shall endure by coming in the Flesh
To a reproachful life and cursed death,
Proclaiming Life to all who shall believe
In his redemption, and that his obedience
Imputed becomes theirs by Faith, his merits
To save them, not thir own, though legal works.
For this he shall live hated, be blasphem'd,
Seis'd on by force, judg'd, and to death condemnd
A shameful and accurst, naild to the Cross
By his own Nation, slaine for bringing Life;
But to the Cross he nailes thy Enemies,
The Law that is against thee, and the sins
Of all mankinde, with him there crucifi'd,
Never to hurt them more who rightly trust
In this his satisfaction; so he dies,
But soon revives, Death over him no power
Shall long usurp; ere the third dawning light
Returne, the Starres of Morn shall see him rise
Out of his grave, fresh as the dawning light,
Thy ransom paid, which Man from death redeems,
His death for Man, as many as offerd Life
Neglect not, and the benefit imbrace
By Faith not void of works: this God-like act
Annuls thy doom, the death thou shouldst have dy'd,
In sin for ever lost from life; this act
Shall bruise the head of SATAN, crush his strength
Defeating Sin and Death, his two maine armes,
And fix farr deeper in his head thir stings
Then temporal death shall bruise the Victors heel,
Or theirs whom he redeems, a death like sleep,
A gentle wafting to immortal Life.
Nor after resurrection shall he stay
Longer on Earth then certaine times to appeer
To his Disciples, Men who in his Life
Still follow'd him; to them shall leave in charge
To teach all nations what of him they learn'd
And his Salvation, them who shall beleeve
Baptizing in the profluent streame, the signe
Of washing them from guilt of sin to Life
Pure, and in mind prepar'd, if so befall,
For death, like that which the redeemer dy'd.
All Nations they shall teach; for from that day
Not onely to the Sons of ABRAHAMS Loines
Salvation shall be Preacht, but to the Sons
Of ABRAHAMS Faith wherever through the world;
So in his seed all Nations shall be blest.
Then to the Heav'n of Heav'ns he shall ascend
With victory, triumphing through the aire
Over his foes and thine; there shall surprise
The Serpent, Prince of aire, and drag in Chaines
Through all his realme, & there confounded leave;
Then enter into glory, and resume
His Seat at Gods right hand, exalted high
Above all names in Heav'n; and thence shall come,
When this worlds dissolution shall be ripe,
With glory and power to judge both quick & dead,
To judge th' unfaithful dead, but to reward
His faithful, and receave them into bliss,
Whether in Heav'n or Earth, for then the Earth
Shall all be Paradise, far happier place
Then this of EDEN, and far happier daies.
So spake th' Archangel MICHAEL, then paus'd,
As at the Worlds great period; and our Sire
Replete with joy and wonder thus repli'd.
O goodness infinite, goodness immense!
That all this good of evil shall produce,
And evil turn to good; more wonderful
Then that which by creation first brought forth
Light out of darkness! full of doubt I stand,
Whether I should repent me now of sin
By mee done and occasiond, or rejoyce
Much more, that much more good thereof shall spring,
To God more glory, more good will to Men
From God, and over wrauth grace shall abound.
But say, if our deliverer up to Heav'n
Must reascend, what will betide the few
His faithful, left among th' unfaithful herd,
The enemies of truth; who then shall guide
His people, who defend? will they not deale
Wors with his followers then with him they dealt?
Be sure they will, said th' Angel; but from Heav'n
Hee to his own a Comforter will send,
The promise of the Father, who shall dwell
His Spirit within them, and the Law of Faith
Working through love, upon thir hearts shall write,
To guide them in all truth, and also arme
With spiritual Armour, able to resist
SATANS assaults, and quench his fierie darts
What Man can do against them, not affraid,
Though to the death, against such cruelties
With inward consolations recompenc't,
And oft supported so as shall amaze
Thir proudest persecuters: for the Spirit
Powrd first on his Apostles, whom he sends
To evangelize the Nations, then on all
Baptiz'd, shall them with wondrous gifts endue
To speak all Tongues, and do all Miracles,
As did thir Lord before them. Thus they win
Great numbers of each Nation to receave
With joy the tidings brought from Heav'n: at length
Thir Ministry perform'd, and race well run,
Thir doctrine and thir story written left,
They die; but in thir room, as they forewarne,
Wolves shall succeed for teachers, grievous Wolves,
Who all the sacred mysteries of Heav'n
To thir own vile advantages shall turne
Of lucre and ambition, and the truth
With superstitions and traditions taint,
Left onely in those written Records pure,
Though not but by the Spirit understood.
Then shall they seek to avail themselves of names,
Places and titles, and with these to joine
Secular power, though feigning still to act
By spiritual, to themselves appropriating
The Spirit of God, promisd alike and giv'n
To all Beleevers; and from that pretense,
Spiritual Lawes by carnal power shall force
On every conscience; Laws which none shall finde
Left them inrould, or what the Spirit within
Shall on the heart engrave. What will they then
But force the Spirit of Grace it self, and binde
His consort Libertie; what, but unbuild
His living Temples, built by Faith to stand,
Thir own Faith not anothers: for on Earth
Who against Faith and Conscience can be heard
Infallible? yet many will presume:
Whence heavie persecution shall arise
On all who in the worship persevere
Of Spirit and Truth; the rest, farr greater part,
Will deem in outward Rites and specious formes
Religion satisfi'd; Truth shall retire
Bestuck with slandrous darts, and works of Faith
Rarely be found: so shall the World goe on,
To good malignant, to bad men benigne,
Under her own waight groaning, till the day
Appeer of respiration to the just,
And vengeance to the wicked, at return
Of him so lately promis'd to thy aid,
The Womans seed, obscurely then foretold,
Now amplier known thy Saviour and thy Lord,
Last in the Clouds from Heav'n to be reveald
In glory of the Father, to dissolve
SATAN with his perverted World, then raise
From the conflagrant mass, purg'd and refin'd,
New Heav'ns, new Earth, Ages of endless date
Founded in righteousness and peace and love,
To bring forth fruits Joy and eternal Bliss.
He ended; and thus ADAM last reply'd.
How soon hath thy prediction, Seer blest,
Measur'd this transient World, the Race of time,
Till time stand fixt: beyond is all abyss,
Eternitie, whose end no eye can reach.
Greatly instructed I shall hence depart,
Greatly in peace of thought, and have my fill
Of knowledge, what this vessel can containe;
Beyond which was my folly to aspire.
Henceforth I learne, that to obey is best,
And love with feare the onely God, to walk
As in his presence, ever to observe
His providence, and on him sole depend,
Merciful over all his works, with good
Still overcoming evil, and by small
Accomplishing great things, by things deemd weak
Subverting worldly strong, and worldly wise
By simply meek; that suffering for Truths sake
Is fortitude to highest victorie,
And to the faithful Death the Gate of Life;
Taught this by his example whom I now
Acknowledge my Redeemer ever blest.
To whom thus also th' Angel last repli'd:
This having learnt, thou hast attaind the summe
Of wisdom; hope no higher, though all the Starrs
Thou knewst by name, and all th' ethereal Powers,
All secrets of the deep, all Natures works,
Or works of God in Heav'n, Air, Earth, or Sea,
And all the riches of this World enjoydst,
And all the rule, one Empire; onely add
Deeds to thy knowledge answerable, add Faith,
Add Vertue, Patience, Temperance, add Love,
By name to come call'd Charitie, the soul
Of all the rest: then wilt thou not be loath
To leave this Paradise, but shalt possess
A Paradise within thee, happier farr.
Let us descend now therefore from this top
Of Speculation; for the hour precise
Exacts our parting hence; and see the Guards,
By mee encampt on yonder Hill, expect
Thir motion, at whose Front a flaming Sword,
In signal of remove, waves fiercely round;
We may no longer stay: go, waken Eve;
Her also I with gentle Dreams have calm'd
Portending good, and all her spirits compos'd
To meek submission: thou at season fit
Let her with thee partake what thou hast heard,
Chiefly what may concern her Faith to know,
The great deliverance by her Seed to come
(For by the Womans Seed) on all Mankind.
That ye may live, which will be many dayes,
Both in one Faith unanimous though sad,
With cause for evils past, yet much more cheer'd
With meditation on the happie end.
He ended, and they both descend the Hill;
Descended, ADAM to the Bowre where EVE
Lay sleeping ran before, but found her wak't;
And thus with words not sad she him receav'd.
Whence thou returnst, & whither wentst, I know;
For God is also in sleep, and Dreams advise,
Which he hath sent propitious, some great good
Presaging, since with sorrow and hearts distress
VVearied I fell asleep: but now lead on;
In mee is no delay; with thee to goe,
Is to stay here; without thee here to stay,
Is to go hence unwilling; thou to mee
Art all things under Heav'n, all places thou,
VVho for my wilful crime art banisht hence.
This further consolation yet secure
I carry hence; though all by mee is lost,
Such favour I unworthie am voutsaft,
By mee the Promis'd Seed shall all restore.
So spake our Mother EVE, and ADAM heard
VVell pleas'd, but answer'd not; for now too nigh
Th' Archangel stood, and from the other Hill
To thir fixt Station, all in bright array
The Cherubim descended; on the ground
Gliding meteorous, as Ev'ning Mist
Ris'n from a River o're the marish glides,
And gathers ground fast at the Labourers heel
Homeward returning. High in Front advanc't,
The brandisht Sword of God before them blaz'd
Fierce as a Comet; which with torrid heat,
And vapour as the LIBYAN Air adust,
Began to parch that temperate Clime; whereat
In either hand the hastning Angel caught
Our lingring Parents, and to th' Eastern Gate
Let them direct, and down the Cliff as fast
To the subjected Plaine; then disappeer'd.
They looking back, all th' Eastern side beheld
Of Paradise, so late thir happie seat,
Wav'd over by that flaming Brand, the Gate
With dreadful Faces throng'd and fierie Armes:
Som natural tears they drop'd, but wip'd them soon;
The World was all before them, where to choose
Thir place of rest, and Providence thir guide:
They hand in hand with wandring steps and slow,
Through EDEN took thir solitarie way.
THE END.
xappy-0.5/testsuite/ 0000755 0001750 0001750 00000000000 11005556727 014372 5 ustar richard richard xappy-0.5/testsuite/unittests/ 0000755 0001750 0001750 00000000000 11005556727 016434 5 ustar richard richard xappy-0.5/testsuite/unittests/facet_hierarchy_1.py 0000644 0001750 0001750 00000011155 10770031412 022334 0 ustar richard richard from unittest import TestCase, main
import tempfile, os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
from xappy.indexerconnection import *
from xappy.fieldactions import *
from xappy.searchconnection import *
# Facets used in documents and their parent facets (or None for top-level facets)
facets = {
'category': None,
'colour': None,
'type': 'category',
'make': 'category',
'species': 'category',
'strings': 'type',
}
# Documents
docvalues = [
{
'category': 'instrument',
'colour': 'blue',
'type': 'drums',
'make': 'Gretsch',
},
{
'category': 'instrument',
'colour': 'red',
'type': 'drums',
'make': 'Stagg',
'offer': '2 for 1',
},
{
'category': 'instrument',
'colour': 'black',
'type': 'accessories',
'make': 'Yamaha',
},
{
'category': 'instrument',
'colour': 'brown',
'type': 'bass guitar',
'make': 'Musicman',
'strings': '4',
},
{
'category': 'instrument',
'colour': 'green',
'type': 'bass guitar',
'make': 'Yamaha',
'strings': '5',
},
{
'category': 'animal',
'colour': 'black',
'species': 'Persian',
},
{
'category': 'animal',
'colour': 'grey',
'species': 'husky',
},
]
class TestFacetHierarchy(TestCase):
def setUp(self):
tempdir = tempfile.mkdtemp()
self.indexpath = os.path.join(tempdir, 'foo')
iconn = IndexerConnection(self.indexpath)
for name in facets:
iconn.add_field_action(name, FieldActions.INDEX_EXACT)
iconn.add_field_action(name, FieldActions.STORE_CONTENT)
iconn.add_field_action(name, FieldActions.FACET)
for name, parent in facets.iteritems():
if parent: iconn.add_subfacet(name, parent)
for values in docvalues:
doc = UnprocessedDocument()
for name, value in values.iteritems():
doc.fields.append(Field(name, value))
iconn.add(doc)
iconn.flush()
iconn.close()
self.sconn = SearchConnection(self.indexpath)
self.faceted_query = self.sconn.query_facet('category', 'instrument')
def _get_facets(self, query, usesubfacets=None, maxfacets=100, required_facets=None):
results = self.sconn.search(query, 0, 10, getfacets=True, usesubfacets=usesubfacets)
tuples = results.get_suggested_facets(maxfacets=maxfacets, required_facets=required_facets)
return set([tuple[0] for tuple in tuples])
def test_non_hierarchy(self):
# Test that all facets with > 1 value are suggested when the m-set is all documents
assert self._get_facets(self.sconn.query_all()) == set(['colour', 'category', 'species', 'type', 'make', 'strings'])
# Test that all facets on instruments are returned for the faceted query
assert self._get_facets(self.faceted_query) == set(['colour', 'type', 'make', 'strings'])
def test_hierarchy(self):
# Test that only top-level facets are suggested for a non-faceted query for all documents
assert self._get_facets(self.sconn.query_all(), usesubfacets=True) == set(['colour', 'category'])
# Test that only top-level facets and subfacets of category are suggested for the faceted query,
# but not 'category' for which there is only 1 value
assert self._get_facets(self.faceted_query, usesubfacets=True) == set(['make', 'type', 'colour'])
# Test that subfacets 'make' and 'type' are suggested first over the top-level facet 'colour'
assert self._get_facets(self.faceted_query, usesubfacets=True, maxfacets=2) == set(['make', 'type'])
# Test that if we explicitely ask for 'category' then we get it regardless
assert self._get_facets(self.faceted_query, usesubfacets=True, required_facets='category') == set(['make', 'type', 'colour', 'category'])
def tearDown(self):
self.sconn.close()
if __name__ == '__main__':
main()
xappy-0.5/testsuite/unittests/facet_query_type_1.py 0000644 0001750 0001750 00000010525 10772155125 022576 0 ustar richard richard from unittest import TestCase, main
import tempfile, os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
from xappy.indexerconnection import *
from xappy.fieldactions import *
from xappy.searchconnection import *
# Facets used in documents
facets = [
'category',
'colour',
'type',
'make',
'species',
'strings',
]
# Documents
docvalues = [
{
'category': 'instrument',
'colour': 'blue',
'type': 'drums',
'make': 'Gretsch',
},
{
'category': 'instrument',
'colour': 'red',
'type': 'drums',
'make': 'Stagg',
},
{
'category': 'instrument',
'colour': 'black',
'type': 'accessories',
'make': 'Yamaha',
},
{
'category': 'instrument',
'colour': 'brown',
'type': 'bass guitar',
'make': 'Musicman',
'strings': '4',
},
{
'category': 'instrument',
'colour': 'green',
'type': 'bass guitar',
'make': 'Yamaha',
'strings': '5',
},
]
class TestFacetHierarchy(TestCase):
def setUp(self):
tempdir = tempfile.mkdtemp()
indexpath = os.path.join(tempdir, 'foo')
self.iconn = IndexerConnection(indexpath)
for name in facets:
self.iconn.add_field_action(name, FieldActions.INDEX_EXACT)
self.iconn.add_field_action(name, FieldActions.STORE_CONTENT)
self.iconn.add_field_action(name, FieldActions.FACET)
for values in docvalues:
doc = UnprocessedDocument()
for name, value in values.iteritems():
doc.fields.append(Field(name, value))
self.iconn.add(doc)
self.iconn.set_facet_for_query_type('type1', 'colour', self.iconn.FacetQueryType_Preferred)
self.iconn.set_facet_for_query_type('type1', 'colour', self.iconn.FacetQueryType_Never)
self.iconn.set_facet_for_query_type('type2', 'colour', self.iconn.FacetQueryType_Preferred)
self.iconn.set_facet_for_query_type('type2', 'make', self.iconn.FacetQueryType_Preferred)
self.iconn.set_facet_for_query_type('type3', 'colour', self.iconn.FacetQueryType_Preferred)
self.iconn.set_facet_for_query_type('type3', 'colour', None)
self.iconn.flush()
self.sconn = SearchConnection(indexpath)
def _get_facets(self, query, maxfacets=100, query_type=None):
results = self.sconn.search(query, 0, 10, getfacets=True, query_type=query_type)
tuples = results.get_suggested_facets(maxfacets=maxfacets)
return set([tuple[0] for tuple in tuples])
def test_facet_query_types(self):
# Test facets have the right preference for query types
assert self.iconn.get_facets_for_query_type('type1', self.iconn.FacetQueryType_Never) == set(['colour'])
assert self.iconn.get_facets_for_query_type('type1', self.iconn.FacetQueryType_Preferred) == set()
assert self.iconn.get_facets_for_query_type('type2', self.iconn.FacetQueryType_Preferred) == set(['colour', 'make'])
assert self.iconn.get_facets_for_query_type('type3', self.iconn.FacetQueryType_Preferred) == None
assert self.iconn.get_facets_for_query_type('not_a_type', self.iconn.FacetQueryType_Preferred) == None
def test_facet_search(self):
query = self.sconn.query_facet('category', 'instrument')
# Test suggested facets are what we expect
assert self._get_facets(query) == set(['colour', 'type', 'make', 'strings']);
# Test 'colour' not suggested for query_type 'type1'
assert self._get_facets(query, query_type='type1') == set(['type', 'make', 'strings']);
# Test 'colour' and 'make' preferred for query_type 'type2'
assert self._get_facets(query, query_type='type2', maxfacets=2) == set(['colour', 'make']);
def tearDown(self):
self.iconn.close()
self.sconn.close()
if __name__ == '__main__':
main()
xappy-0.5/testsuite/unittests/freetext_1.py 0000644 0001750 0001750 00000012122 11001754033 021034 0 ustar richard richard from unittest import TestCase, main
import os, shutil, sys, tempfile
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
from xappy import *
class TestFreeText(TestCase):
def setUp(self):
self.tempdir = tempfile.mkdtemp()
self.indexpath = os.path.join(self.tempdir, 'foo')
iconn = IndexerConnection(self.indexpath)
iconn.add_field_action('a', FieldActions.INDEX_FREETEXT)
iconn.add_field_action('b', FieldActions.INDEX_FREETEXT, search_by_default=False)
iconn.add_field_action('c', FieldActions.INDEX_FREETEXT, search_by_default=True)
iconn.add_field_action('d', FieldActions.INDEX_FREETEXT, allow_field_specific=False)
iconn.add_field_action('e', FieldActions.INDEX_FREETEXT, allow_field_specific=True)
iconn.add_field_action('f', FieldActions.INDEX_FREETEXT, search_by_default=False, allow_field_specific=False)
iconn.add_field_action('a', FieldActions.STORE_CONTENT)
iconn.add_field_action('b', FieldActions.STORE_CONTENT)
iconn.add_field_action('c', FieldActions.STORE_CONTENT)
for i in xrange(32):
doc = UnprocessedDocument()
if i % 2:
doc.fields.append(Field('a', 'termA'))
if (i / 2) % 2:
doc.fields.append(Field('b', 'termB'))
if (i / 4) % 2:
doc.fields.append(Field('c', 'termC'))
if (i / 8) % 2:
doc.fields.append(Field('d', 'termD'))
if (i / 16) % 2:
doc.fields.append(Field('e', 'termE'))
if (i / 3) % 3 == 0:
doc.fields.append(Field('f', 'termF'))
iconn.add(doc)
iconn.flush()
iconn.close()
self.sconn = SearchConnection(self.indexpath)
def test_search_by_default1(self):
# Search by default (due to default handling)
q = self.sconn.query_parse('termA')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]))
# Not searched by default
q = self.sconn.query_parse('termB')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([]))
# Explicitly searched by default
q = self.sconn.query_parse('termC')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31]))
# Not searched by default
q = self.sconn.query_parse('termF')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([]))
def test_search_by_default2(self):
# Search by default (due to default handling)
q = self.sconn.query_parse('termA', default_allow=('a', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]))
# Not searched by default, but can be explicitly specified
q = self.sconn.query_parse('termB', default_allow=('b', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31]))
# Explicitly searched by default
q = self.sconn.query_parse('termC', default_allow=('c', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31]))
# Not searched by default, by can't be explicitly specified either
# because it's not indexed as allow_field_specific
q = self.sconn.query_parse('termF')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([]))
def test_allow_field_specific1(self):
# Search by default (due to default handling)
q = self.sconn.query_parse('a:termA', allow=('a', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]))
# Not indexed for field specific searching
q = self.sconn.query_parse('d:termD', allow=('d', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([]))
# Explicitly indexed for field specific searching
q = self.sconn.query_parse('e:termE', allow=('e', ))
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]))
# Not indexed for field specific searching
q = self.sconn.query_parse('termF')
res = self.sconn.search(q, 0, 100)
self.assertEqual(set([int(item.id, 16) for item in res]), set([]))
def tearDown(self):
self.sconn.close()
#shutil.rmtree(self.tempdir)
if __name__ == '__main__':
main()
xappy-0.5/testsuite/unittests/spell_correct_1.py 0000644 0001750 0001750 00000002107 10711422250 022050 0 ustar richard richard from unittest import TestCase, main
import tempfile, os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
from xappy.indexerconnection import *
from xappy.fieldactions import *
from xappy.searchconnection import *
class TestSpellCorrect(TestCase):
def setUp(self):
tempdir = tempfile.mkdtemp()
self.indexpath = os.path.join(tempdir, 'foo')
iconn = IndexerConnection(self.indexpath)
iconn.add_field_action('name', FieldActions.INDEX_FREETEXT, spell=True,)
for i in xrange(5):
doc = UnprocessedDocument()
doc.fields.append(Field('name', 'bruno is a nice guy'))
iconn.add(doc)
iconn.flush()
iconn.close()
self.sconn = SearchConnection(self.indexpath)
def test_spell_correct(self):
query = 'brunore'
self.assertEqual('bruno', self.sconn.spell_correct(query))
query = 'brunore-brunore'
self.sconn.spell_correct(query)#will throw RuntimeError
def tearDown(self):
self.sconn.close()
if __name__ == '__main__':
main()
xappy-0.5/testsuite/coverage.py 0000755 0001750 0001750 00000123577 10677214601 016555 0 ustar richard richard #!/usr/bin/python
#
# Perforce Defect Tracking Integration Project
#
#
# COVERAGE.PY -- COVERAGE TESTING
#
# Gareth Rees, Ravenbrook Limited, 2001-12-04
# Ned Batchelder, 2004-12-12
# http://nedbatchelder.com/code/modules/coverage.html
#
#
# 1. INTRODUCTION
#
# This module provides coverage testing for Python code.
#
# The intended readership is all Python developers.
#
# This document is not confidential.
#
# See [GDR 2001-12-04a] for the command-line interface, programmatic
# interface and limitations. See [GDR 2001-12-04b] for requirements and
# design.
r"""Usage:
coverage.py -x [-p] MODULE.py [ARG1 ARG2 ...]
Execute module, passing the given command-line arguments, collecting
coverage data. With the -p option, write to a temporary file containing
the machine name and process ID.
coverage.py -e
Erase collected coverage data.
coverage.py -c
Collect data from multiple coverage files (as created by -p option above)
and store it into a single file representing the union of the coverage.
coverage.py -r [-m] [-o dir1,dir2,...] FILE1 FILE2 ...
Report on the statement coverage for the given files. With the -m
option, show line numbers of the statements that weren't executed.
coverage.py -a [-d dir] [-o dir1,dir2,...] FILE1 FILE2 ...
Make annotated copies of the given files, marking statements that
are executed with > and statements that are missed with !. With
the -d option, make the copies in that directory. Without the -d
option, make each copy in the same directory as the original.
-o dir,dir2,...
Omit reporting or annotating files when their filename path starts with
a directory listed in the omit list.
e.g. python coverage.py -i -r -o c:\python23,lib\enthought\traits
Coverage data is saved in the file .coverage by default. Set the
COVERAGE_FILE environment variable to save it somewhere else."""
__version__ = "2.77.20070729" # see detailed history at the end of this file.
import compiler
import compiler.visitor
import glob
import os
import re
import string
import symbol
import sys
import threading
import token
import types
from socket import gethostname
# Python version compatibility
try:
strclass = basestring # new to 2.3
except:
strclass = str
import doctest
#
# Doctest and coverage both need to hook into the debugger, and if we don't do
# special handling, doctest tends to take over and cause coverage not to see
# lines which are executed. Note that this handling is only needed if doctest
# is used, but we do it anyway because that's simplest.
#
# This patch is based on this changeset in nose:
# http://nose.python-hosting.com/changeset/133
#
# which is in turn based on this patch from Zope:
#
# zope patch:
# http://svn.zope.org/Zope3/trunk/src/zope/testing/doctest.py?rev=28679&r1=28703&r2=28705
#
_orp = doctest._OutputRedirectingPdb
class CoverageOutputRedirectingPdb(_orp):
def __init__(self, out):
self.__debugger_used = False
_orp.__init__(self, out)
def set_trace(self):
self.__debugger_used = True
_orp.set_trace(self)
def set_continue(self):
# Calling set_continue unconditionally would break unit test coverage
# reporting, as Bdb.set_continue calls sys.settrace(None).
if self.__debugger_used:
_orp.set_continue(self)
doctest._OutputRedirectingPdb = CoverageOutputRedirectingPdb
# 2. IMPLEMENTATION
#
# This uses the "singleton" pattern.
#
# The word "morf" means a module object (from which the source file can
# be deduced by suitable manipulation of the __file__ attribute) or a
# filename.
#
# When we generate a coverage report we have to canonicalize every
# filename in the coverage dictionary just in case it refers to the
# module we are reporting on. It seems a shame to throw away this
# information so the data in the coverage dictionary is transferred to
# the 'cexecuted' dictionary under the canonical filenames.
#
# The coverage dictionary is called "c" and the trace function "t". The
# reason for these short names is that Python looks up variables by name
# at runtime and so execution time depends on the length of variables!
# In the bottleneck of this application it's appropriate to abbreviate
# names to increase speed.
class StatementFindingAstVisitor(compiler.visitor.ASTVisitor):
""" A visitor for a parsed Abstract Syntax Tree which finds executable
statements.
"""
def __init__(self, statements, excluded, suite_spots):
compiler.visitor.ASTVisitor.__init__(self)
self.statements = statements
self.excluded = excluded
self.suite_spots = suite_spots
self.excluding_suite = 0
def doRecursive(self, node):
for n in node.getChildNodes():
self.dispatch(n)
visitStmt = visitModule = doRecursive
def doCode(self, node):
if hasattr(node, 'decorators') and node.decorators:
self.dispatch(node.decorators)
self.recordAndDispatch(node.code)
else:
self.doSuite(node, node.code)
visitFunction = visitClass = doCode
def getFirstLine(self, node):
# Find the first line in the tree node.
lineno = node.lineno
for n in node.getChildNodes():
f = self.getFirstLine(n)
if lineno and f:
lineno = min(lineno, f)
else:
lineno = lineno or f
return lineno
def getLastLine(self, node):
# Find the first line in the tree node.
lineno = node.lineno
for n in node.getChildNodes():
lineno = max(lineno, self.getLastLine(n))
return lineno
def doStatement(self, node):
self.recordLine(self.getFirstLine(node))
visitAssert = visitAssign = visitAssTuple = visitPrint = \
visitPrintnl = visitRaise = visitSubscript = visitDecorators = \
doStatement
def visitPass(self, node):
# Pass statements have weird interactions with docstrings. If this
# pass statement is part of one of those pairs, claim that the statement
# is on the later of the two lines.
l = node.lineno
if l:
lines = self.suite_spots.get(l, [l,l])
self.statements[lines[1]] = 1
def visitDiscard(self, node):
# Discard nodes are statements that execute an expression, but then
# discard the results. This includes function calls, so we can't
# ignore them all. But if the expression is a constant, the statement
# won't be "executed", so don't count it now.
if node.expr.__class__.__name__ != 'Const':
self.doStatement(node)
def recordNodeLine(self, node):
# Stmt nodes often have None, but shouldn't claim the first line of
# their children (because the first child might be an ignorable line
# like "global a").
if node.__class__.__name__ != 'Stmt':
return self.recordLine(self.getFirstLine(node))
else:
return 0
def recordLine(self, lineno):
# Returns a bool, whether the line is included or excluded.
if lineno:
# Multi-line tests introducing suites have to get charged to their
# keyword.
if lineno in self.suite_spots:
lineno = self.suite_spots[lineno][0]
# If we're inside an excluded suite, record that this line was
# excluded.
if self.excluding_suite:
self.excluded[lineno] = 1
return 0
# If this line is excluded, or suite_spots maps this line to
# another line that is exlcuded, then we're excluded.
elif self.excluded.has_key(lineno) or \
self.suite_spots.has_key(lineno) and \
self.excluded.has_key(self.suite_spots[lineno][1]):
return 0
# Otherwise, this is an executable line.
else:
self.statements[lineno] = 1
return 1
return 0
default = recordNodeLine
def recordAndDispatch(self, node):
self.recordNodeLine(node)
self.dispatch(node)
def doSuite(self, intro, body, exclude=0):
exsuite = self.excluding_suite
if exclude or (intro and not self.recordNodeLine(intro)):
self.excluding_suite = 1
self.recordAndDispatch(body)
self.excluding_suite = exsuite
def doPlainWordSuite(self, prevsuite, suite):
# Finding the exclude lines for else's is tricky, because they aren't
# present in the compiler parse tree. Look at the previous suite,
# and find its last line. If any line between there and the else's
# first line are excluded, then we exclude the else.
lastprev = self.getLastLine(prevsuite)
firstelse = self.getFirstLine(suite)
for l in range(lastprev+1, firstelse):
if self.suite_spots.has_key(l):
self.doSuite(None, suite, exclude=self.excluded.has_key(l))
break
else:
self.doSuite(None, suite)
def doElse(self, prevsuite, node):
if node.else_:
self.doPlainWordSuite(prevsuite, node.else_)
def visitFor(self, node):
self.doSuite(node, node.body)
self.doElse(node.body, node)
visitWhile = visitFor
def visitIf(self, node):
# The first test has to be handled separately from the rest.
# The first test is credited to the line with the "if", but the others
# are credited to the line with the test for the elif.
self.doSuite(node, node.tests[0][1])
for t, n in node.tests[1:]:
self.doSuite(t, n)
self.doElse(node.tests[-1][1], node)
def visitTryExcept(self, node):
self.doSuite(node, node.body)
for i in range(len(node.handlers)):
a, b, h = node.handlers[i]
if not a:
# It's a plain "except:". Find the previous suite.
if i > 0:
prev = node.handlers[i-1][2]
else:
prev = node.body
self.doPlainWordSuite(prev, h)
else:
self.doSuite(a, h)
self.doElse(node.handlers[-1][2], node)
def visitTryFinally(self, node):
self.doSuite(node, node.body)
self.doPlainWordSuite(node.body, node.final)
def visitWith(self, node):
self.doSuite(node, node.body)
def visitGlobal(self, node):
# "global" statements don't execute like others (they don't call the
# trace function), so don't record their line numbers.
pass
the_coverage = None
class CoverageException(Exception): pass
class coverage:
# Name of the cache file (unless environment variable is set).
cache_default = ".coverage"
# Environment variable naming the cache file.
cache_env = "COVERAGE_FILE"
# A dictionary with an entry for (Python source file name, line number
# in that file) if that line has been executed.
c = {}
# A map from canonical Python source file name to a dictionary in
# which there's an entry for each line number that has been
# executed.
cexecuted = {}
# Cache of results of calling the analysis2() method, so that you can
# specify both -r and -a without doing double work.
analysis_cache = {}
# Cache of results of calling the canonical_filename() method, to
# avoid duplicating work.
canonical_filename_cache = {}
def __init__(self):
global the_coverage
if the_coverage:
raise CoverageException, "Only one coverage object allowed."
self.usecache = 1
self.cache = None
self.clear_cache = False
self.parallel_mode = False
self.exclude_re = ''
self.nesting = 0
self.cstack = []
self.xstack = []
self.relative_dir = os.path.normcase(os.path.abspath(os.curdir)+os.sep)
self.exclude('# *pragma[: ]*[nN][oO] *[cC][oO][vV][eE][rR]')
# t(f, x, y). This method is passed to sys.settrace as a trace function.
# See [van Rossum 2001-07-20b, 9.2] for an explanation of sys.settrace and
# the arguments and return value of the trace function.
# See [van Rossum 2001-07-20a, 3.2] for a description of frame and code
# objects.
def t(self, f, w, unused): #pragma: no cover
if w == 'line':
#print "Executing %s @ %d" % (f.f_code.co_filename, f.f_lineno)
self.c[(f.f_code.co_filename, f.f_lineno)] = 1
for c in self.cstack:
c[(f.f_code.co_filename, f.f_lineno)] = 1
return self.t
def help(self, error=None): #pragma: no cover
if error:
print error
print
print __doc__
sys.exit(1)
def command_line(self, argv, help_fn=None):
import getopt
help_fn = help_fn or self.help
settings = {}
optmap = {
'-a': 'annotate',
'-c': 'collect',
'-d:': 'directory=',
'-e': 'erase',
'-h': 'help',
'-i': 'ignore-errors',
'-m': 'show-missing',
'-p': 'parallel-mode',
'-r': 'report',
'-x': 'execute',
'-o:': 'omit=',
}
short_opts = string.join(map(lambda o: o[1:], optmap.keys()), '')
long_opts = optmap.values()
options, args = getopt.getopt(argv, short_opts, long_opts)
for o, a in options:
if optmap.has_key(o):
settings[optmap[o]] = 1
elif optmap.has_key(o + ':'):
settings[optmap[o + ':']] = a
elif o[2:] in long_opts:
settings[o[2:]] = 1
elif o[2:] + '=' in long_opts:
settings[o[2:]+'='] = a
else: #pragma: no cover
pass # Can't get here, because getopt won't return anything unknown.
if settings.get('help'):
help_fn()
for i in ['erase', 'execute']:
for j in ['annotate', 'report', 'collect']:
if settings.get(i) and settings.get(j):
help_fn("You can't specify the '%s' and '%s' "
"options at the same time." % (i, j))
args_needed = (settings.get('execute')
or settings.get('annotate')
or settings.get('report'))
action = (settings.get('erase')
or settings.get('collect')
or args_needed)
if not action:
help_fn("You must specify at least one of -e, -x, -c, -r, or -a.")
if not args_needed and args:
help_fn("Unexpected arguments: %s" % " ".join(args))
self.parallel_mode = settings.get('parallel-mode')
self.get_ready()
if settings.get('erase'):
self.erase()
if settings.get('execute'):
if not args:
help_fn("Nothing to do.")
sys.argv = args
self.start()
import __main__
sys.path[0] = os.path.dirname(sys.argv[0])
execfile(sys.argv[0], __main__.__dict__)
if settings.get('collect'):
self.collect()
if not args:
args = self.cexecuted.keys()
ignore_errors = settings.get('ignore-errors')
show_missing = settings.get('show-missing')
directory = settings.get('directory=')
omit = settings.get('omit=')
if omit is not None:
omit = omit.split(',')
else:
omit = []
if settings.get('report'):
self.report(args, show_missing, ignore_errors, omit_prefixes=omit)
if settings.get('annotate'):
self.annotate(args, directory, ignore_errors, omit_prefixes=omit)
def use_cache(self, usecache, cache_file=None):
self.usecache = usecache
if cache_file and not self.cache:
self.cache_default = cache_file
def get_ready(self, parallel_mode=False):
if self.usecache and not self.cache:
self.cache = os.environ.get(self.cache_env, self.cache_default)
if self.parallel_mode:
self.cache += "." + gethostname() + "." + str(os.getpid())
if self.clear_cache:
try:
os.remove(self.cache)
except OSError:
pass
self.restore()
self.analysis_cache = {}
def start(self, parallel_mode=False):
self.get_ready()
if self.nesting == 0: #pragma: no cover
sys.settrace(self.t)
if hasattr(threading, 'settrace'):
threading.settrace(self.t)
self.nesting += 1
def stop(self):
self.nesting -= 1
if self.nesting == 0: #pragma: no cover
sys.settrace(None)
if hasattr(threading, 'settrace'):
threading.settrace(None)
def erase(self):
self.get_ready()
self.c = {}
self.analysis_cache = {}
self.cexecuted = {}
if self.cache and os.path.exists(self.cache):
os.remove(self.cache)
self.clear_cache = True
self.exclude_re = ""
def exclude(self, re):
if self.exclude_re:
self.exclude_re += "|"
self.exclude_re += "(" + re + ")"
def begin_recursive(self):
self.cstack.append(self.c)
self.xstack.append(self.exclude_re)
def end_recursive(self):
self.c = self.cstack.pop()
self.exclude_re = self.xstack.pop()
# save(). Save coverage data to the coverage cache.
def save(self):
if self.usecache and self.cache:
self.canonicalize_filenames()
cache = open(self.cache, 'wb')
import marshal
marshal.dump(self.cexecuted, cache)
cache.close()
# restore(). Restore coverage data from the coverage cache (if it exists).
def restore(self):
self.c = {}
self.cexecuted = {}
assert self.usecache
if os.path.exists(self.cache):
self.cexecuted = self.restore_file(self.cache)
def restore_file(self, file_name):
try:
cache = open(file_name, 'rb')
import marshal
cexecuted = marshal.load(cache)
cache.close()
if isinstance(cexecuted, types.DictType):
return cexecuted
else:
return {}
except:
return {}
# collect(). Collect data in multiple files produced by parallel mode
def collect(self):
cache_dir, local = os.path.split(self.cache)
for f in os.listdir(cache_dir or '.'):
if not f.startswith(local):
continue
full_path = os.path.join(cache_dir, f)
cexecuted = self.restore_file(full_path)
self.merge_data(cexecuted)
def merge_data(self, new_data):
for file_name, file_data in new_data.items():
if self.cexecuted.has_key(file_name):
self.merge_file_data(self.cexecuted[file_name], file_data)
else:
self.cexecuted[file_name] = file_data
def merge_file_data(self, cache_data, new_data):
for line_number in new_data.keys():
if not cache_data.has_key(line_number):
cache_data[line_number] = new_data[line_number]
# canonical_filename(filename). Return a canonical filename for the
# file (that is, an absolute path with no redundant components and
# normalized case). See [GDR 2001-12-04b, 3.3].
def canonical_filename(self, filename):
if not self.canonical_filename_cache.has_key(filename):
f = filename
if os.path.isabs(f) and not os.path.exists(f):
f = os.path.basename(f)
if not os.path.isabs(f):
for path in [os.curdir] + sys.path:
g = os.path.join(path, f)
if os.path.exists(g):
f = g
break
cf = os.path.normcase(os.path.abspath(f))
self.canonical_filename_cache[filename] = cf
return self.canonical_filename_cache[filename]
# canonicalize_filenames(). Copy results from "c" to "cexecuted",
# canonicalizing filenames on the way. Clear the "c" map.
def canonicalize_filenames(self):
for filename, lineno in self.c.keys():
if filename == '':
# Can't do anything useful with exec'd strings, so skip them.
continue
f = self.canonical_filename(filename)
if not self.cexecuted.has_key(f):
self.cexecuted[f] = {}
self.cexecuted[f][lineno] = 1
self.c = {}
# morf_filename(morf). Return the filename for a module or file.
def morf_filename(self, morf):
if isinstance(morf, types.ModuleType):
if not hasattr(morf, '__file__'):
raise CoverageException, "Module has no __file__ attribute."
f = morf.__file__
else:
f = morf
return self.canonical_filename(f)
# analyze_morf(morf). Analyze the module or filename passed as
# the argument. If the source code can't be found, raise an error.
# Otherwise, return a tuple of (1) the canonical filename of the
# source code for the module, (2) a list of lines of statements
# in the source code, (3) a list of lines of excluded statements,
# and (4), a map of line numbers to multi-line line number ranges, for
# statements that cross lines.
def analyze_morf(self, morf):
if self.analysis_cache.has_key(morf):
return self.analysis_cache[morf]
filename = self.morf_filename(morf)
ext = os.path.splitext(filename)[1]
if ext == '.pyc':
if not os.path.exists(filename[0:-1]):
raise CoverageException, ("No source for compiled code '%s'."
% filename)
filename = filename[0:-1]
elif ext != '.py':
raise CoverageException, "File '%s' not Python source." % filename
source = open(filename, 'r')
lines, excluded_lines, line_map = self.find_executable_statements(
source.read(), exclude=self.exclude_re
)
source.close()
result = filename, lines, excluded_lines, line_map
self.analysis_cache[morf] = result
return result
def first_line_of_tree(self, tree):
while True:
if len(tree) == 3 and type(tree[2]) == type(1):
return tree[2]
tree = tree[1]
def last_line_of_tree(self, tree):
while True:
if len(tree) == 3 and type(tree[2]) == type(1):
return tree[2]
tree = tree[-1]
def find_docstring_pass_pair(self, tree, spots):
for i in range(1, len(tree)):
if self.is_string_constant(tree[i]) and self.is_pass_stmt(tree[i+1]):
first_line = self.first_line_of_tree(tree[i])
last_line = self.last_line_of_tree(tree[i+1])
self.record_multiline(spots, first_line, last_line)
def is_string_constant(self, tree):
try:
return tree[0] == symbol.stmt and tree[1][1][1][0] == symbol.expr_stmt
except:
return False
def is_pass_stmt(self, tree):
try:
return tree[0] == symbol.stmt and tree[1][1][1][0] == symbol.pass_stmt
except:
return False
def record_multiline(self, spots, i, j):
for l in range(i, j+1):
spots[l] = (i, j)
def get_suite_spots(self, tree, spots):
""" Analyze a parse tree to find suite introducers which span a number
of lines.
"""
for i in range(1, len(tree)):
if type(tree[i]) == type(()):
if tree[i][0] == symbol.suite:
# Found a suite, look back for the colon and keyword.
lineno_colon = lineno_word = None
for j in range(i-1, 0, -1):
if tree[j][0] == token.COLON:
# Colons are never executed themselves: we want the
# line number of the last token before the colon.
lineno_colon = self.last_line_of_tree(tree[j-1])
elif tree[j][0] == token.NAME:
if tree[j][1] == 'elif':
# Find the line number of the first non-terminal
# after the keyword.
t = tree[j+1]
while t and token.ISNONTERMINAL(t[0]):
t = t[1]
if t:
lineno_word = t[2]
else:
lineno_word = tree[j][2]
break
elif tree[j][0] == symbol.except_clause:
# "except" clauses look like:
# ('except_clause', ('NAME', 'except', lineno), ...)
if tree[j][1][0] == token.NAME:
lineno_word = tree[j][1][2]
break
if lineno_colon and lineno_word:
# Found colon and keyword, mark all the lines
# between the two with the two line numbers.
self.record_multiline(spots, lineno_word, lineno_colon)
# "pass" statements are tricky: different versions of Python
# treat them differently, especially in the common case of a
# function with a doc string and a single pass statement.
self.find_docstring_pass_pair(tree[i], spots)
elif tree[i][0] == symbol.simple_stmt:
first_line = self.first_line_of_tree(tree[i])
last_line = self.last_line_of_tree(tree[i])
if first_line != last_line:
self.record_multiline(spots, first_line, last_line)
self.get_suite_spots(tree[i], spots)
def find_executable_statements(self, text, exclude=None):
# Find lines which match an exclusion pattern.
excluded = {}
suite_spots = {}
if exclude:
reExclude = re.compile(exclude)
lines = text.split('\n')
for i in range(len(lines)):
if reExclude.search(lines[i]):
excluded[i+1] = 1
# Parse the code and analyze the parse tree to find out which statements
# are multiline, and where suites begin and end.
import parser
tree = parser.suite(text+'\n\n').totuple(1)
self.get_suite_spots(tree, suite_spots)
#print "Suite spots:", suite_spots
# Use the compiler module to parse the text and find the executable
# statements. We add newlines to be impervious to final partial lines.
statements = {}
ast = compiler.parse(text+'\n\n')
visitor = StatementFindingAstVisitor(statements, excluded, suite_spots)
compiler.walk(ast, visitor, walker=visitor)
lines = statements.keys()
lines.sort()
excluded_lines = excluded.keys()
excluded_lines.sort()
return lines, excluded_lines, suite_spots
# format_lines(statements, lines). Format a list of line numbers
# for printing by coalescing groups of lines as long as the lines
# represent consecutive statements. This will coalesce even if
# there are gaps between statements, so if statements =
# [1,2,3,4,5,10,11,12,13,14] and lines = [1,2,5,10,11,13,14] then
# format_lines will return "1-2, 5-11, 13-14".
def format_lines(self, statements, lines):
pairs = []
i = 0
j = 0
start = None
pairs = []
while i < len(statements) and j < len(lines):
if statements[i] == lines[j]:
if start == None:
start = lines[j]
end = lines[j]
j = j + 1
elif start:
pairs.append((start, end))
start = None
i = i + 1
if start:
pairs.append((start, end))
def stringify(pair):
start, end = pair
if start == end:
return "%d" % start
else:
return "%d-%d" % (start, end)
ret = string.join(map(stringify, pairs), ", ")
return ret
# Backward compatibility with version 1.
def analysis(self, morf):
f, s, _, m, mf = self.analysis2(morf)
return f, s, m, mf
def analysis2(self, morf):
filename, statements, excluded, line_map = self.analyze_morf(morf)
self.canonicalize_filenames()
if not self.cexecuted.has_key(filename):
self.cexecuted[filename] = {}
missing = []
for line in statements:
lines = line_map.get(line, [line, line])
for l in range(lines[0], lines[1]+1):
if self.cexecuted[filename].has_key(l):
break
else:
missing.append(line)
return (filename, statements, excluded, missing,
self.format_lines(statements, missing))
def relative_filename(self, filename):
""" Convert filename to relative filename from self.relative_dir.
"""
return filename.replace(self.relative_dir, "")
def morf_name(self, morf):
""" Return the name of morf as used in report.
"""
if isinstance(morf, types.ModuleType):
return morf.__name__
else:
return self.relative_filename(os.path.splitext(morf)[0])
def filter_by_prefix(self, morfs, omit_prefixes):
""" Return list of morfs where the morf name does not begin
with any one of the omit_prefixes.
"""
filtered_morfs = []
for morf in morfs:
for prefix in omit_prefixes:
if self.morf_name(morf).startswith(prefix):
break
else:
filtered_morfs.append(morf)
return filtered_morfs
def morf_name_compare(self, x, y):
return cmp(self.morf_name(x), self.morf_name(y))
def report(self, morfs, show_missing=1, ignore_errors=0, file=None, omit_prefixes=[]):
if not isinstance(morfs, types.ListType):
morfs = [morfs]
# On windows, the shell doesn't expand wildcards. Do it here.
globbed = []
for morf in morfs:
if isinstance(morf, strclass):
globbed.extend(glob.glob(morf))
else:
globbed.append(morf)
morfs = globbed
morfs = self.filter_by_prefix(morfs, omit_prefixes)
morfs.sort(self.morf_name_compare)
max_name = max([5,] + map(len, map(self.morf_name, morfs)))
fmt_name = "%%- %ds " % max_name
fmt_err = fmt_name + "%s: %s"
header = fmt_name % "Name" + " Stmts Exec Cover"
fmt_coverage = fmt_name + "% 6d % 6d % 5d%%"
if show_missing:
header = header + " Missing"
fmt_coverage = fmt_coverage + " %s"
if not file:
file = sys.stdout
print >>file, header
print >>file, "-" * len(header)
total_statements = 0
total_executed = 0
for morf in morfs:
name = self.morf_name(morf)
try:
_, statements, _, missing, readable = self.analysis2(morf)
n = len(statements)
m = n - len(missing)
if n > 0:
pc = 100.0 * m / n
else:
pc = 100.0
args = (name, n, m, pc)
if show_missing:
args = args + (readable,)
print >>file, fmt_coverage % args
total_statements = total_statements + n
total_executed = total_executed + m
except KeyboardInterrupt: #pragma: no cover
raise
except:
if not ignore_errors:
typ, msg = sys.exc_info()[0:2]
print >>file, fmt_err % (name, typ, msg)
if len(morfs) > 1:
print >>file, "-" * len(header)
if total_statements > 0:
pc = 100.0 * total_executed / total_statements
else:
pc = 100.0
args = ("TOTAL", total_statements, total_executed, pc)
if show_missing:
args = args + ("",)
print >>file, fmt_coverage % args
# annotate(morfs, ignore_errors).
blank_re = re.compile(r"\s*(#|$)")
else_re = re.compile(r"\s*else\s*:\s*(#|$)")
def annotate(self, morfs, directory=None, ignore_errors=0, omit_prefixes=[]):
morfs = self.filter_by_prefix(morfs, omit_prefixes)
for morf in morfs:
try:
filename, statements, excluded, missing, _ = self.analysis2(morf)
self.annotate_file(filename, statements, excluded, missing, directory)
except KeyboardInterrupt:
raise
except:
if not ignore_errors:
raise
def annotate_file(self, filename, statements, excluded, missing, directory=None):
source = open(filename, 'r')
if directory:
dest_file = os.path.join(directory,
os.path.basename(filename)
+ ',cover')
else:
dest_file = filename + ',cover'
dest = open(dest_file, 'w')
lineno = 0
i = 0
j = 0
covered = 1
while 1:
line = source.readline()
if line == '':
break
lineno = lineno + 1
while i < len(statements) and statements[i] < lineno:
i = i + 1
while j < len(missing) and missing[j] < lineno:
j = j + 1
if i < len(statements) and statements[i] == lineno:
covered = j >= len(missing) or missing[j] > lineno
if self.blank_re.match(line):
dest.write(' ')
elif self.else_re.match(line):
# Special logic for lines containing only 'else:'.
# See [GDR 2001-12-04b, 3.2].
if i >= len(statements) and j >= len(missing):
dest.write('! ')
elif i >= len(statements) or j >= len(missing):
dest.write('> ')
elif statements[i] == missing[j]:
dest.write('! ')
else:
dest.write('> ')
elif lineno in excluded:
dest.write('- ')
elif covered:
dest.write('> ')
else:
dest.write('! ')
dest.write(line)
source.close()
dest.close()
# Singleton object.
the_coverage = coverage()
# Module functions call methods in the singleton object.
def use_cache(*args, **kw):
return the_coverage.use_cache(*args, **kw)
def start(*args, **kw):
return the_coverage.start(*args, **kw)
def stop(*args, **kw):
return the_coverage.stop(*args, **kw)
def erase(*args, **kw):
return the_coverage.erase(*args, **kw)
def begin_recursive(*args, **kw):
return the_coverage.begin_recursive(*args, **kw)
def end_recursive(*args, **kw):
return the_coverage.end_recursive(*args, **kw)
def exclude(*args, **kw):
return the_coverage.exclude(*args, **kw)
def analysis(*args, **kw):
return the_coverage.analysis(*args, **kw)
def analysis2(*args, **kw):
return the_coverage.analysis2(*args, **kw)
def report(*args, **kw):
return the_coverage.report(*args, **kw)
def annotate(*args, **kw):
return the_coverage.annotate(*args, **kw)
def annotate_file(*args, **kw):
return the_coverage.annotate_file(*args, **kw)
# Save coverage data when Python exits. (The atexit module wasn't
# introduced until Python 2.0, so use sys.exitfunc when it's not
# available.)
try:
import atexit
atexit.register(the_coverage.save)
except ImportError:
sys.exitfunc = the_coverage.save
# Command-line interface.
if __name__ == '__main__':
the_coverage.command_line(sys.argv[1:])
# A. REFERENCES
#
# [GDR 2001-12-04a] "Statement coverage for Python"; Gareth Rees;
# Ravenbrook Limited; 2001-12-04;
# .
#
# [GDR 2001-12-04b] "Statement coverage for Python: design and
# analysis"; Gareth Rees; Ravenbrook Limited; 2001-12-04;
# .
#
# [van Rossum 2001-07-20a] "Python Reference Manual (releae 2.1.1)";
# Guide van Rossum; 2001-07-20;
# .
#
# [van Rossum 2001-07-20b] "Python Library Reference"; Guido van Rossum;
# 2001-07-20; .
#
#
# B. DOCUMENT HISTORY
#
# 2001-12-04 GDR Created.
#
# 2001-12-06 GDR Added command-line interface and source code
# annotation.
#
# 2001-12-09 GDR Moved design and interface to separate documents.
#
# 2001-12-10 GDR Open cache file as binary on Windows. Allow
# simultaneous -e and -x, or -a and -r.
#
# 2001-12-12 GDR Added command-line help. Cache analysis so that it
# only needs to be done once when you specify -a and -r.
#
# 2001-12-13 GDR Improved speed while recording. Portable between
# Python 1.5.2 and 2.1.1.
#
# 2002-01-03 GDR Module-level functions work correctly.
#
# 2002-01-07 GDR Update sys.path when running a file with the -x option,
# so that it matches the value the program would get if it were run on
# its own.
#
# 2004-12-12 NMB Significant code changes.
# - Finding executable statements has been rewritten so that docstrings and
# other quirks of Python execution aren't mistakenly identified as missing
# lines.
# - Lines can be excluded from consideration, even entire suites of lines.
# - The filesystem cache of covered lines can be disabled programmatically.
# - Modernized the code.
#
# 2004-12-14 NMB Minor tweaks. Return 'analysis' to its original behavior
# and add 'analysis2'. Add a global for 'annotate', and factor it, adding
# 'annotate_file'.
#
# 2004-12-31 NMB Allow for keyword arguments in the module global functions.
# Thanks, Allen.
#
# 2005-12-02 NMB Call threading.settrace so that all threads are measured.
# Thanks Martin Fuzzey. Add a file argument to report so that reports can be
# captured to a different destination.
#
# 2005-12-03 NMB coverage.py can now measure itself.
#
# 2005-12-04 NMB Adapted Greg Rogers' patch for using relative filenames,
# and sorting and omitting files to report on.
#
# 2006-07-23 NMB Applied Joseph Tate's patch for function decorators.
#
# 2006-08-21 NMB Applied Sigve Tjora and Mark van der Wal's fixes for argument
# handling.
#
# 2006-08-22 NMB Applied Geoff Bache's parallel mode patch.
#
# 2006-08-23 NMB Refactorings to improve testability. Fixes to command-line
# logic for parallel mode and collect.
#
# 2006-08-25 NMB "#pragma: nocover" is excluded by default.
#
# 2006-09-10 NMB Properly ignore docstrings and other constant expressions that
# appear in the middle of a function, a problem reported by Tim Leslie.
# Minor changes to avoid lint warnings.
#
# 2006-09-17 NMB coverage.erase() shouldn't clobber the exclude regex.
# Change how parallel mode is invoked, and fix erase() so that it erases the
# cache when called programmatically.
#
# 2007-07-21 NMB In reports, ignore code executed from strings, since we can't
# do anything useful with it anyway.
# Better file handling on Linux, thanks Guillaume Chazarain.
# Better shell support on Windows, thanks Noel O'Boyle.
# Python 2.2 support maintained, thanks Catherine Proulx.
#
# 2007-07-22 NMB Python 2.5 now fully supported. The method of dealing with
# multi-line statements is now less sensitive to the exact line that Python
# reports during execution. Pass statements are handled specially so that their
# disappearance during execution won't throw off the measurement.
#
# 2007-07-23 NMB Now Python 2.5 is *really* fully supported: the body of the
# new with statement is counted as executable.
#
# 2007-07-29 NMB Better packaging.
# C. COPYRIGHT AND LICENCE
#
# Copyright 2001 Gareth Rees. All rights reserved.
# Copyright 2004-2007 Ned Batchelder. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the
# distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# $Id: coverage.py 74 2007-07-29 22:28:35Z nedbat $
xappy-0.5/testsuite/runtests.py 0000755 0001750 0001750 00000026654 11004346430 016636 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""runtests.py: Run a set of tests with doctest and unittest.
The list of modules to test is specified at the top of the file, in the
MODNAMES variable.
Other files containing documentation to be tested is listed in the OTHER_FILES
variable.
A subset of the modules can be tested by specifying a list of module names on
the command line.
"""
__docformat__ = "restructuredtext en"
#######################
# Begin configuration #
#######################
# List the modules to test with doctest (please keep this list in alphabetical
# order, for ease of maintenance).
MODNAMES = (
'secore',
'secore.datastructures',
'secore.errors',
'secore.fieldactions',
'secore.fieldmappings',
'secore.highlight',
'secore.indexerconnection',
'secore.marshall',
'secore.parsedate',
'secore.searchconnection',
'xappy',
'xappy.datastructures',
'xappy.errors',
'xappy.fieldactions',
'xappy.fieldmappings',
'xappy.highlight',
'xappy.indexerconnection',
'xappy.marshall',
'xappy.parsedate',
'xappy.searchconnection',
)
# List the documentation files which should be valid doctest inputs
OTHER_FILES = (
'docs/introduction.rst',
)
# Whitelist lines for coverage report (ie, lines which should always be
# considered as having been executed). The first item in each line is a line
# number that the line can appear at, which may be negative to indicate lines
# from the end of the file. The second item is a regular expression to match
# against the line: if the expression matches, the line will be considered
# executed.
COVERED_LINES = (
(-2, r'\s*import doctest, sys'),
(-1, r'\s*doctest.testmod'),
)
########################
# End of configuration #
########################
import sys
import os
import re
import unittest
import doctest
import traceback
import copy
def canonical_path(path):
return os.path.normcase(os.path.normpath(os.path.realpath(path)))
def check_whitelist(lines, checklinenum, covered_lines):
"""Check whether line `checklinenum`, for the file with contents `lines`
is in the whitelist. Return True if so, False otherwise.
"""
for linenum, pattern in covered_lines:
if linenum < 0:
linenum += len(lines) + 1
if linenum <= 0 or linenum > len(lines):
continue
if checklinenum != linenum:
continue
if not pattern.match(lines[checklinenum - 1]):
continue
return True
return False
def create_docfile_suite(mod, modpath):
"""Create a suite of tests from a text file containing doctests.
The dictionary of the module is imported into the namespace which the tests
are run in (excluding any entries which begin with a double underscore), so
the tests can be written as if they were entries in the modules __test__
dictionary.
"""
globs = {'__file__': modpath,
}
for key in mod.__dict__.keys():
if not key.startswith('__'):
globs[key] = mod.__dict__[key]
return doctest.DocFileSuite(modpath,
module_relative=False,
globs=globs,
setUp=setup_test,
tearDown=teardown_test,
)
def recursive_rm(path):
"""Recursively remove a directory and its contents.
"""
if os.path.isdir(path):
for root, dirs, files in os.walk(path, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
for dir in dirs:
os.rmdir(os.path.join(root, dir))
os.rmdir(path)
_orig_vals = {}
def setup_test(dtobj):
"""Prepare for running a test.
"""
tmpdir = 'test_tmp'
recursive_rm(tmpdir)
_orig_vals['wd'] = os.path.abspath(os.getcwd())
_orig_vals['path'] = sys.path
sys.path = copy.copy(sys.path)
sys.path.insert(0, _orig_vals['wd'])
testdir = os.path.dirname(dtobj.globs['__file__'])
sys.path.insert(0, testdir)
os.mkdir(tmpdir)
os.chdir(tmpdir)
def teardown_test(dtobj):
"""Cleanup after running a test.
"""
for key, val in list(dtobj.globs.iteritems()):
if hasattr(val, '__module__') and \
val.__module__ is not None and \
val.__module__.startswith('xappy'):
if hasattr(val, 'close'):
if not isinstance(val, type):
val.close()
del dtobj.globs[key]
del key
del val
dtobj.globs.clear()
# Try really hard to make sure any xapian databases have been closed
# properly, so that windows doesn't give errors when we try and delete
# them.
import gc
gc.collect()
tmpdir = 'test_tmp'
os.chdir(_orig_vals['wd'])
sys.path = _orig_vals['path']
recursive_rm(tmpdir)
def run_tests(topdir, modnames, other_files, use_coverage):
"""Run tests on the specified modules.
Returns a list of modules which were tested.
"""
# Check command line for overrides to module names
if len(sys.argv) > 1:
newnames = []
for arg in sys.argv[1:]:
if arg in modnames:
newnames.append(arg)
else:
print "Module `%s' not known" % arg
sys.exit(1)
modnames = newnames
# Make a test suite to put all the tests in.
suite = unittest.TestSuite()
if use_coverage:
# Use the coverage test module to get coverage information.
import coverage
coverage.erase()
coverage.start()
coverage.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]')
# Add all the doctest tests.
modules = []
for modname in modnames:
try:
# Get the path of the module (to search for associated tests)
modpath = os.path.join(*(modname.split('.')))
modpath = canonical_path(modpath)
if os.path.isdir(modpath):
modpath = os.path.join(modpath, '__init__')
# Import the module
sys.path.insert(0, topdir)
mod = __import__(modname, None, None, [''])
del sys.path[0]
# Check that the module imported came from the expected path.
if os.path.splitext(mod.__file__)[0] != modpath:
print "Couldn't import module `%s`: got module of same name, from wrong path (%r)" % (modname, mod.__file__)
continue
# Add module to test suite.
suite.addTest(doctest.DocTestSuite(mod, setUp=setup_test, tearDown=teardown_test))
modules.append(mod)
# Check for additional doctest files
modpath = modpath + '_doctest%d.txt'
num = 1
while os.path.exists(modpath % num):
suite.addTest(create_docfile_suite(mod, modpath % num))
num += 1
except ImportError, e:
print "Couldn't import module `%s`: %s" % (modname, e)
traceback.print_exc()
# Add any other files with doctests in them.
for file in other_files:
fullpath = os.path.join(topdir, file)
globs = {'__file__': os.path.join(canonical_path("xappy"), '__init__'),}
suite.addTest(doctest.DocFileSuite(fullpath,
module_relative=False,
globs=globs,
setUp=setup_test,
tearDown=teardown_test,
))
# Now, run everything.
runner = unittest.TextTestRunner()
runner.run(suite)
if use_coverage:
# Finished run - stop the coverage tests
coverage.stop()
return modules
def get_coverage(topdir, modules, covered_lines):
import coverage
# Compile the expressions in COVERED_LINES
covered_lines = [(lines, re.compile(pattern))
for (lines, pattern) in covered_lines]
# Get the coverage statistics
stats = []
for module in modules:
(filename, stmtlines, stmtmissed, stmtmissed_desc) = coverage.analysis(module)
filename = canonical_path(filename)
if filename.startswith(topdir):
filename = filename[len(topdir) + 1:]
lines = open(filename).readlines()
linenum = len(lines)
# Remove whitelisted lines
stmtmissed = [linenum for linenum in stmtmissed
if not check_whitelist(lines, linenum, covered_lines)]
# Sort the lines (probably already in order, but let's double-check)
stmtlines.sort()
stmtmissed.sort()
# Build a compressed list of ranges of lines which have no statements
# which were executed, but do contain statements.
missed_ranges = []
stmtpos = 0
currrange = None
for linenum in stmtmissed:
while stmtlines[stmtpos] < linenum:
# If there are any statements before the current linenum, we
# end the current range of missed statements
currrange = None
stmtpos += 1
if currrange is None:
currrange = [linenum, linenum]
missed_ranges.append(currrange)
else:
currrange[1] = linenum
stmtpos += 1
percent = (len(stmtlines) - len(stmtmissed)) * 100.0 / len(stmtlines)
stats.append((filename, percent, len(stmtlines), missed_ranges))
return stats
def display_coverage(stats):
print "Coverage report:"
max_filename_len = max(len(stat[0]) for stat in stats)
for filename, percent, total, missed in stats:
msg = "%r%s %5.1f%% of %d" % (filename, ' ' * (max_filename_len - len(filename)), percent, total)
if len(missed) != 0:
for pos in xrange(len(missed)):
if missed[pos][0] == missed[pos][1]:
missed[pos] = str(missed[pos][0])
elif missed[pos][0] + 1 == missed[pos][1]:
missed[pos] = "%d,%d" % tuple(missed[pos])
else:
missed[pos] = "%d-%d" % tuple(missed[pos])
msg += "\t Missed: %s" % ','.join(missed)
print msg
def run(use_coverage=False, use_profiling=False):
topdir = canonical_path(os.path.join(os.path.dirname(__file__), '..'))
if use_profiling:
try:
import cProfile as profile
except ImportError:
import profile
modules = profile.run('run_tests(%r, MODNAMES, OTHER_FILES, %r)' % (topdir, use_profiling), os.path.join(topdir, '.runtests.prof'))
else:
modules = run_tests(topdir, MODNAMES, OTHER_FILES, use_coverage)
if use_coverage:
display_coverage(get_coverage(topdir, modules, COVERED_LINES))
run()
#run(use_profiling=True)
xappy-0.5/utils/ 0000755 0001750 0001750 00000000000 11005556727 013501 5 ustar richard richard xappy-0.5/utils/make_xappy_tarballs 0000755 0001750 0001750 00000013712 11005462312 017437 0 ustar richard richard #!/bin/sh -e
# This script is used to generate the tarballs of xapian for xappy.
#
# These tarballs are based on SVN HEAD, but with the changes from two branches
# merged in. Some of the contents of these branches may be merged into HEAD
# shortly, but other changes on the branches can't easily be merged to HEAD
# during the 1.0.x release series, so will be merged after the 1.0.x series has
# been moved into maintenance mode, and HEAD is being used to work towards the
# 1.1 series.
#
# The script depends on various directories being set up, and is probably only
# usable on my machine without a fair bit of work first.
# The directories used are:
#
# $basedir/branchpoints/matchspy: a checkout of the matchspy branch at the
# revision the branch was made (ie, before any changes were made on it).
#
# $basedir/branchpoints/opsynonym: a checkout of the opsynonym branch at the
# revision the branch was made (ie, before any changes were made on it).
#
# $basedir/branchpoints/clustering: a checkout of the clustering branch at the
# revision the branch was made (ie, before any changes were made on it).
#
# $basedir/branches/matchspy: a checkout of the matchspy branch at the latest
# revision.
#
# $basedir/branches/opsynonym: a checkout of the opsynonym branch at the
# latest revision.
#
# $basedir/branches/clustering: a checkout of the clustering branch at the
# latest revision.
#
# $basedir/head/trunk: a checkout of HEAD, at the latest revision.
#
# $xappylibdir: a checkout of xappy/trunk.
rev="1.0.6"
matchspy_branchpoint="10407"
opsynonym_branchpoint="10407"
clustering_branchpoint="10407"
basedir="$HOME/private/Working/xapian/pristine/"
xappylibdir="$HOME/xappy/libs/"
echo "Updating branchpoint trees"
cd $basedir/branchpoints/matchspy
svn update -r$matchspy_branchpoint
cd $basedir/branchpoints/opsynonym
svn update -r$opsynonym_branchpoint
cd $basedir/branchpoints/clustering
svn update -r$clustering_branchpoint
echo "Updating branch trees"
cd $basedir/branches/matchspy
svn update
cd $basedir/branches/opsynonym
svn update
cd $basedir/branches/clustering
svn update
echo "Updating head"
cd $basedir/head/trunk
svn update
head_rev=`svn info | grep Revision | cut -f 2 -d ' '`
echo "Exporting clean trees"
rm -rf $basedir/branchpoints/matchspy_export
svn export $basedir/branchpoints/matchspy $basedir/branchpoints/matchspy_export
rm -rf $basedir/branchpoints/opsynonym_export
svn export $basedir/branchpoints/opsynonym $basedir/branchpoints/opsynonym_export
rm -rf $basedir/branchpoints/clustering_export
svn export $basedir/branchpoints/clustering $basedir/branchpoints/clustering_export
rm -rf $basedir/branches/matchspy_export
svn export $basedir/branches/matchspy $basedir/branches/matchspy_export
rm -rf $basedir/branches/opsynonym_export
svn export $basedir/branches/opsynonym $basedir/branches/opsynonym_export
rm -rf $basedir/branches/clustering_export
svn export $basedir/branches/clustering $basedir/branches/clustering_export
rm -rf $basedir/head/trunk_export
svn export $basedir/head/trunk $basedir/head/trunk_export
# Get the diffs we made on branches.
echo "Getting patches from matchspy branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/matchspy_export \
branches/matchspy_export \
| filterdiff -x '*/ChangeLog' -x '*/NEWS' -x '*/docs/index.html' \
>$basedir/matchspy_changes.patch
echo "Getting patches from opsynonym branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/opsynonym_export \
branches/opsynonym_export \
| filterdiff -x '*/ChangeLog' -x '*/NEWS' -x '*/docs/index.html' \
>$basedir/opsynonym_changes.patch
echo "Getting patches from clustering branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/clustering_export \
branches/clustering_export \
| filterdiff -x '*/ChangeLog' -x '*/NEWS' -x '*/docs/index.html' \
>$basedir/clustering_changes.patch
# Get the diffs made to HEAD since the branch points
echo "Getting changes to HEAD since matchspy branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/matchspy_export \
head/trunk_export \
>$basedir/head_changes_since_matchspy_branch.patch && true
echo "Getting changes to HEAD since opsynonym branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/opsynonym_export \
head/trunk_export \
>$basedir/head_changes_since_opsynonym_branch.patch && true
echo "Getting changes to HEAD since clustering branch"
cd $basedir
diff -Nur --ignore-matching-lines='\$Author' \
branchpoints/clustering_export \
head/trunk_export \
>$basedir/head_changes_since_clustering_branch.patch && true
# Apply the patches to HEAD
echo "Applying patches"
cd $basedir/head/trunk_export
patch -p2 < $basedir/matchspy_changes.patch
patch -p2 < $basedir/opsynonym_changes.patch
patch -p2 < $basedir/clustering_changes.patch
# Make tarballs
echo "Building tarballs"
cd $basedir/head/trunk_export
./bootstrap
./configure
(cd xapian-core && make && make dist)
(cd xapian-bindings && make && make dist)
# Copy the tarballs into xappy
echo "Repacking tarballs"
cd $xappylibdir
mkdir -p tmp
cd tmp
rm -rf xapian-core-* xapian-bindings-*
cd $basedir/head/trunk_export
cp xapian-core/xapian-core-${rev}.tar.gz $xappylibdir/tmp/
cp xapian-bindings/xapian-bindings-${rev}.tar.gz $xappylibdir/tmp/
cd $xappylibdir/tmp
tar zxf $xappylibdir/tmp/xapian-core-${rev}.tar.gz
tar zxf $xappylibdir/tmp/xapian-bindings-${rev}.tar.gz
mv xapian-core-${rev} xapian-core
mv xapian-bindings-${rev} xapian-bindings
tar -H ustar -zcf xapian-core-${head_rev}.tgz xapian-core
tar -H ustar -zcf xapian-bindings-${head_rev}.tgz xapian-bindings
rm -r xapian-core xapian-bindings
rm xapian-core-${rev}.tar.gz
rm xapian-bindings-${rev}.tar.gz
cd $xappylibdir
mv tmp/xapian-core-${head_rev}.tgz .
mv tmp/xapian-bindings-${head_rev}.tgz .
# Make a tarball of the windows build files
cd $basedir/head/trunk_export/xapian-maintainer-tools/
tar -H ustar -zcf win32msvc-${head_rev}.tgz win32msvc
cp win32msvc-${head_rev}.tgz $xappylibdir/
rmdir tmp
xappy-0.5/xappy/ 0000755 0001750 0001750 00000000000 11005556727 013502 5 ustar richard richard xappy-0.5/xappy/__init__.py 0000644 0001750 0001750 00000002463 11005445777 015622 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Xappy.
See the accompanying documentation for details. In particular, there should be
an accompanying file "introduction.html" (or "introduction.rst") which gives
details of how to use the xappy package.
"""
__docformat__ = "restructuredtext en"
__version__ = '0.5'
import _checkxapian
from datastructures import Field, UnprocessedDocument, ProcessedDocument
from errors import *
from fieldactions import FieldActions
from indexerconnection import IndexerConnection
from searchconnection import SearchConnection
from replaylog import set_replay_path
xappy-0.5/xappy/_checkxapian.py 0000644 0001750 0001750 00000003145 11005456013 016457 0 ustar richard richard # Copyright (C) 2008 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""_checkxapian.py: Check the version of xapian used.
Raises an ImportError on import if the version used is too old to be used at
all.
"""
__docformat__ = "restructuredtext en"
# The minimum version of xapian required to work at all.
min_xapian_version = (1, 0, 6)
# Dictionary of features we can't support do to them being missing from the
# available version of xapian.
missing_features = {}
import xapian
versions = xapian.major_version(), xapian.minor_version(), xapian.revision()
if versions < min_xapian_version:
raise ImportError("""
Xapian Python bindings installed, but need at least version %d.%d.%d - got %s
""".strip() % tuple(list(min_xapian_version) + [xapian.version_string()]))
if not hasattr(xapian, 'TermCountMatchSpy'):
missing_features['tags'] = 1
if not hasattr(xapian, 'CategorySelectMatchSpy'):
missing_features['facets'] = 1
xappy-0.5/xappy/datastructures.py 0000644 0001750 0001750 00000021452 10772400231 017121 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""datastructures.py: Datastructures for search engine core.
"""
__docformat__ = "restructuredtext en"
import errors
from replaylog import log
import xapian
import cPickle
class Field(object):
# Use __slots__ because we're going to have very many Field objects in
# typical usage.
__slots__ = 'name', 'value'
def __init__(self, name, value):
self.name = name
self.value = value
def __repr__(self):
return 'Field(%r, %r)' % (self.name, self.value)
class UnprocessedDocument(object):
"""A unprocessed document to be passed to the indexer.
This represents an item to be processed and stored in the search engine.
Each document will be processed by the indexer to generate a
ProcessedDocument, which can then be stored in the search engine index.
Note that some information in an UnprocessedDocument will not be
represented in the ProcessedDocument: therefore, it is not possible to
retrieve an UnprocessedDocument from the search engine index.
An unprocessed document is a simple container with two attributes:
- `fields` is a list of Field objects, or an iterator returning Field
objects.
- `id` is a string holding a unique identifier for the document (or
None to get the database to allocate a unique identifier automatically
when the document is added).
"""
__slots__ = 'id', 'fields',
def __init__(self, id=None, fields=None):
self.id = id
if fields is None:
self.fields = []
else:
self.fields = fields
def __repr__(self):
return 'UnprocessedDocument(%r, %r)' % (self.id, self.fields)
class ProcessedDocument(object):
"""A processed document, as stored in the index.
This represents an item which is ready to be stored in the search engine,
or which has been returned by the search engine.
"""
__slots__ = '_doc', '_fieldmappings', '_data',
def __init__(self, fieldmappings, xapdoc=None):
"""Create a ProcessedDocument.
`fieldmappings` is the configuration from a database connection used lookup
the configuration to use to store each field.
If supplied, `xapdoc` is a Xapian document to store in the processed
document. Otherwise, a new Xapian document is created.
"""
if xapdoc is None:
self._doc = log(xapian.Document)
else:
self._doc = xapdoc
self._fieldmappings = fieldmappings
self._data = None
def add_term(self, field, term, wdfinc=1, positions=None):
"""Add a term to the document.
Terms are the main unit of information used for performing searches.
- `field` is the field to add the term to.
- `term` is the term to add.
- `wdfinc` is the value to increase the within-document-frequency
measure for the term by.
- `positions` is the positional information to add for the term.
This may be None to indicate that there is no positional information,
or may be an integer to specify one position, or may be a sequence of
integers to specify several positions. (Note that the wdf is not
increased automatically for each position: if you add a term at 7
positions, and the wdfinc value is 2, the total wdf for the term will
only be increased by 2, not by 14.)
"""
prefix = self._fieldmappings.get_prefix(field)
if len(term) > 0:
# We use the following check, rather than "isupper()" to ensure
# that we match the check performed by the queryparser, regardless
# of our locale.
if ord(term[0]) >= ord('A') and ord(term[0]) <= ord('Z'):
prefix = prefix + ':'
# Note - xapian currently restricts term lengths to about 248
# characters - except that zero bytes are encoded in two bytes, so
# in practice a term of length 125 characters could be too long.
# Xapian will give an error when commit() is called after such
# documents have been added to the database.
# As a simple workaround, we give an error here for terms over 220
# characters, which will catch most occurrences of the error early.
#
# In future, it might be good to change to a hashing scheme in this
# situation (or for terms over, say, 64 characters), where the
# characters after position 64 are hashed (we obviously need to do this
# hashing at search time, too).
if len(prefix + term) > 220:
raise errors.IndexerError("Field %r is too long: maximum length "
"220 - was %d (%r)" %
(field, len(prefix + term),
prefix + term))
if positions is None:
self._doc.add_term(prefix + term, wdfinc)
elif isinstance(positions, int):
self._doc.add_posting(prefix + term, positions, wdfinc)
else:
self._doc.add_term(prefix + term, wdfinc)
for pos in positions:
self._doc.add_posting(prefix + term, pos, 0)
def add_value(self, field, value, purpose=''):
"""Add a value to the document.
Values are additional units of information used when performing
searches. Note that values are _not_ intended to be used to store
information for display in the search results - use the document data
for that. The intention is that as little information as possible is
stored in values, so that they can be accessed as quickly as possible
during the search operation.
Unlike terms, each document may have at most one value in each field
(whereas there may be an arbitrary number of terms in a given field).
If an attempt to add multiple values to a single field is made, only
the last value added will be stored.
"""
slot = self._fieldmappings.get_slot(field, purpose)
self._doc.add_value(slot, value)
def get_value(self, field, purpose=''):
"""Get a value from the document.
"""
slot = self._fieldmappings.get_slot(field, purpose)
return self._doc.get_value(slot)
def prepare(self):
"""Prepare the document for adding to a xapian database.
This updates the internal xapian document with any changes which have
been made, and then returns it.
"""
if self._data is not None:
self._doc.set_data(cPickle.dumps(self._data, 2))
self._data = None
return self._doc
def _get_data(self):
if self._data is None:
rawdata = self._doc.get_data()
if rawdata == '':
self._data = {}
else:
self._data = cPickle.loads(rawdata)
return self._data
def _set_data(self, data):
if not isinstance(data, dict):
raise TypeError("Cannot set data to any type other than a dict")
self._data = data
data = property(_get_data, _set_data, doc=
"""The data stored in this processed document.
This data is a dictionary of entries, where the key is a fieldname, and the
value is a list of strings.
""")
def _get_id(self):
tl = self._doc.termlist()
try:
term = tl.skip_to('Q').term
if len(term) == 0 or term[0] != 'Q':
return None
except StopIteration:
return None
return term[1:]
def _set_id(self, id):
tl = self._doc.termlist()
try:
term = tl.skip_to('Q').term
except StopIteration:
term = ''
if len(term) != 0 and term[0] == 'Q':
self._doc.remove_term(term)
if id is not None:
self._doc.add_term('Q' + id, 0)
id = property(_get_id, _set_id, doc=
"""The unique ID for this document.
""")
def __repr__(self):
return '' % (self.id)
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/datastructures_doctest1.txt 0000644 0001750 0001750 00000001473 10667526666 021147 0 ustar richard richard
>>> from fieldmappings import FieldMappings
>>> maps = FieldMappings()
Make a processed document.
>>> doc = ProcessedDocument(maps)
>>> print doc.id
None
>>> doc.id = '1'
>>> print doc.id
1
>>> doc.id = '_'
>>> print doc.id
_
>>> print repr(doc.data)
{}
>>> doc.data['foo'] = ['1', '2']
>>> print repr(doc.data)
{'foo': ['1', '2']}
Adding terms which are too long gives an error straight-away.
>>> maps.add_prefix('foo')
>>> doc.add_term('foo', 'a' * 250)
Traceback (most recent call last):
...
IndexerError: Field 'foo' is too long: maximum length 220 - was 252 ('XAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
xappy-0.5/xappy/errors.py 0000644 0001750 0001750 00000005732 10700703107 015362 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""errors.py: Exceptions for the search engine core.
"""
__docformat__ = "restructuredtext en"
class SearchEngineError(Exception):
r"""Base class for exceptions thrown by the search engine.
Any errors generated by xappy itself, or by xapian, will be instances of
this class or its subclasses.
"""
class IndexerError(SearchEngineError):
r"""Class used to report errors relating to the indexing API.
"""
class SearchError(SearchEngineError):
r"""Class used to report errors relating to the search API.
"""
class XapianError(SearchEngineError):
r"""Base class for exceptions thrown by the xapian.
Any errors generated by xapian will be instances of this class or its
subclasses.
"""
def _rebase_xapian_exceptions():
"""Add new base classes for all the xapian exceptions.
"""
import xapian
for name in (
'AssertionError',
'DatabaseCorruptError',
'DatabaseCreateError',
'DatabaseError',
'DatabaseLockError',
'DatabaseModifiedError',
'DatabaseOpeningError',
'DatabaseVersionError',
'DocNotFoundError',
# We skip 'Error' because it inherits directly from exception
# and this causes problems with method resolution order.
# However, we probably don't need it anyway, because it's
# just a base class, and shouldn't ever actually be raised.
# Users can catch xappy.XapianError instead.
'FeatureUnavailableError',
'InternalError',
'InvalidArgumentError',
'InvalidOperationError',
'LogicError',
'NetworkError',
'NetworkTimeoutError',
'QueryParserError',
'RangeError',
'RuntimeError',
'UnimplementedError',
):
xapian_exception = getattr(xapian, name, None)
if xapian_exception is not None:
xapian_exception.__bases__ += (XapianError, )
globals()['Xapian' + name] = xapian_exception
_rebase_xapian_exceptions()
xappy-0.5/xappy/errors_doctest1.txt 0000644 0001750 0001750 00000001750 10700703214 017352 0 ustar richard richard Xappy exports all the xapian errors as "XapianFooError", corresponding to
xapian.FooError. Firstly, we need to test that we can catch one of these
errors. Lets play with DatabaseLockError because it's easy to generate.
>>> import xappy
>>> db1 = xappy.IndexerConnection('foo')
>>> try:
... db2 = xappy.IndexerConnection('foo')
... except xappy.XapianDatabaseLockError:
... print "Got XapianDatabaseLockError"
Got XapianDatabaseLockError
Xappy also modifies all the Xapian errors so that they inherit from
xappy.XapianError, so we can catch all Xapian errors this way:
>>> try:
... db2 = xappy.IndexerConnection('foo')
... except xappy.XapianError:
... print "Got XapianError"
Got XapianError
xappy.XapianError is a subclass of xappy.SearchEngineError, so all errors from
xappy can be caught using xappy.SearchEngineError:
>>> try:
... db2 = xappy.IndexerConnection('foo')
... except xappy.SearchEngineError:
... print "Got SearchEngineError"
Got SearchEngineError
xappy-0.5/xappy/fieldactions.py 0000644 0001750 0001750 00000041451 11005455561 016517 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""fieldactions.py: Definitions and implementations of field actions.
"""
__docformat__ = "restructuredtext en"
import _checkxapian
import errors
import marshall
from replaylog import log
import xapian
import parsedate
def _act_store_content(fieldname, doc, value, context):
"""Perform the STORE_CONTENT action.
"""
try:
fielddata = doc.data[fieldname]
except KeyError:
fielddata = []
doc.data[fieldname] = fielddata
fielddata.append(value)
def _act_index_exact(fieldname, doc, value, context):
"""Perform the INDEX_EXACT action.
"""
doc.add_term(fieldname, value, 0)
def _act_tag(fieldname, doc, value, context):
"""Perform the TAG action.
"""
doc.add_term(fieldname, value.lower(), 0)
def _act_facet(fieldname, doc, value, context, type=None):
"""Perform the FACET action.
"""
if type is None or type == 'string':
value = value.lower()
doc.add_term(fieldname, value, 0)
serialiser = log(xapian.StringListSerialiser,
doc.get_value(fieldname, 'facet'))
serialiser.append(value)
doc.add_value(fieldname, serialiser.get(), 'facet')
else:
marshaller = SortableMarshaller()
fn = marshaller.get_marshall_function(fieldname, type)
doc.add_value(fieldname, fn(fieldname, value), 'facet')
def _act_index_freetext(fieldname, doc, value, context, weight=1,
language=None, stop=None, spell=False,
nopos=False,
allow_field_specific=True,
search_by_default=True):
"""Perform the INDEX_FREETEXT action.
"""
termgen = log(xapian.TermGenerator)
if language is not None:
termgen.set_stemmer(log(xapian.Stem, language))
if stop is not None:
stopper = log(xapian.SimpleStopper)
for term in stop:
stopper.add (term)
termgen.set_stopper (stopper)
if spell:
termgen.set_database(context.index)
termgen.set_flags(termgen.FLAG_SPELLING)
termgen.set_document(doc._doc)
if search_by_default:
termgen.set_termpos(context.current_position)
# Store a copy of the field without a prefix, for non-field-specific
# searches.
if nopos:
termgen.index_text_without_positions(value, weight, '')
else:
termgen.index_text(value, weight, '')
if allow_field_specific:
# Store a second copy of the term with a prefix, for field-specific
# searches.
prefix = doc._fieldmappings.get_prefix(fieldname)
if len(prefix) != 0:
termgen.set_termpos(context.current_position)
if nopos:
termgen.index_text_without_positions(value, weight, prefix)
else:
termgen.index_text(value, weight, prefix)
# Add a gap between each field instance, so that phrase searches don't
# match across instances.
termgen.increase_termpos(10)
context.current_position = termgen.get_termpos()
class SortableMarshaller(object):
"""Implementation of marshalling for sortable values.
"""
def __init__(self, indexing=True):
if indexing:
self._err = errors.IndexerError
else:
self._err = errors.SearchError
def marshall_string(self, fieldname, value):
"""Marshall a value for sorting in lexicograpical order.
This returns the input as the output, since strings already sort in
lexicographical order.
"""
return value
def marshall_float(self, fieldname, value):
"""Marshall a value for sorting as a floating point value.
"""
# convert the value to a float
try:
value = float(value)
except ValueError:
raise self._err("Value supplied to field %r must be a "
"valid floating point number: was %r" %
(fieldname, value))
return marshall.float_to_string(value)
def marshall_date(self, fieldname, value):
"""Marshall a value for sorting as a date.
"""
try:
value = parsedate.date_from_string(value)
except ValueError, e:
raise self._err("Value supplied to field %r must be a "
"valid date: was %r: error is '%s'" %
(fieldname, value, str(e)))
return marshall.date_to_string(value)
def get_marshall_function(self, fieldname, sorttype):
"""Get a function used to marshall values of a given sorttype.
"""
try:
return {
None: self.marshall_string,
'string': self.marshall_string,
'float': self.marshall_float,
'date': self.marshall_date,
}[sorttype]
except KeyError:
raise self._err("Unknown sort type %r for field %r" %
(sorttype, fieldname))
def _act_sort_and_collapse(fieldname, doc, value, context, type=None):
"""Perform the SORTABLE action.
"""
marshaller = SortableMarshaller()
fn = marshaller.get_marshall_function(fieldname, type)
value = fn(fieldname, value)
doc.add_value(fieldname, value, 'collsort')
class ActionContext(object):
"""The context in which an action is performed.
This is just used to pass term generators, word positions, and the like
around.
"""
def __init__(self, index):
self.current_language = None
self.current_position = 0
self.index = index
class FieldActions(object):
"""An object describing the actions to be performed on a field.
The supported actions are:
- `STORE_CONTENT`: store the unprocessed content of the field in the search
engine database. All fields which need to be displayed or used when
displaying the search results need to be given this action.
- `INDEX_EXACT`: index the exact content of the field as a single search
term. Fields whose contents need to be searchable as an "exact match"
need to be given this action.
- `INDEX_FREETEXT`: index the content of this field as text. The content
will be split into terms, allowing free text searching of the field. Four
optional parameters may be supplied:
- 'weight' is a multiplier to apply to the importance of the field. This
must be an integer, and the default value is 1.
- 'language' is the language to use when processing the field. This can
be expressed as an ISO 2-letter language code. The supported languages
are those supported by the xapian core in use.
- 'stop' is an iterable of stopwords to filter out of the generated
terms. Note that due to Xapian design, only non-positional terms are
affected, so this is of limited use.
- 'spell' is a boolean flag - if true, the contents of the field will be
used for spelling correction.
- 'nopos' is a boolean flag - if true, positional information is not
stored.
- 'allow_field_specific' is a boolean flag - if False, prevents terms with the field
prefix being generated. This means that searches specific to this
field will not work, and thus should only be used when only non-field
specific searches are desired. Defaults to True.
- 'search_by_default' is a boolean flag - if False, the field will not be
searched by non-field specific searches. If True, or omitted, the
field will be included in searches for non field-specific searches.
- `SORTABLE`: index the content of the field such that it can be used to
sort result sets. It also allows result sets to be restricted to those
documents with a field values in a given range. One optional parameter
may be supplied:
- 'type' is a value indicating how to sort the field. It has several
possible values:
- 'string' - sort in lexicographic (ie, alphabetical) order.
This is the default, used if no type is set.
- 'float' - treat the values as (decimal representations of) floating
point numbers, and sort in numerical order. The values in the field
must be valid floating point numbers (according to Python's float()
function).
- 'date' - sort in date order. The values must be valid dates (either
Python datetime.date objects, or ISO 8601 format (ie, YYYYMMDD or
YYYY-MM-DD).
- `COLLAPSE`: index the content of the field such that it can be used to
"collapse" result sets, such that only the highest result with each value
of the field will be returned.
- `TAG`: the field contains tags; these are strings, which will be matched
in a case insensitive way, but otherwise must be exact matches. Tag
fields can be searched for by making an explict query (ie, using
query_field(), but not with query_parse()). A list of the most frequent
tags in a result set can also be accessed easily.
- `FACET`: the field represents a classification facet; these are strings
which will be matched exactly, but a list of all the facets present in
the result set can also be accessed easily - in addition, a suitable
subset of the facets, and a selection of the facet values, present in the
result set can be calculated. One optional parameter may be supplied:
- 'type' is a value indicating the type of facet contained in the field:
- 'string' - the facet values are exact binary strings.
- 'float' - the facet values are floating point numbers.
"""
# See the class docstring for the meanings of the following constants.
STORE_CONTENT = 1
INDEX_EXACT = 2
INDEX_FREETEXT = 3
SORTABLE = 4
COLLAPSE = 5
TAG = 6
FACET = 7
# Sorting and collapsing store the data in a value, but the format depends
# on the sort type. Easiest way to implement is to treat them as the same
# action.
SORT_AND_COLLAPSE = -1
_unsupported_actions = []
if 'tags' in _checkxapian.missing_features:
_unsupported_actions.append(TAG)
if 'facets' in _checkxapian.missing_features:
_unsupported_actions.append(FACET)
def __init__(self, fieldname):
# Dictionary of actions, keyed by type.
self._actions = {}
self._fieldname = fieldname
def add(self, field_mappings, action, **kwargs):
"""Add an action to perform on a field.
"""
if action in self._unsupported_actions:
raise errors.IndexerError("Action unsupported with this release of xapian")
if action not in (FieldActions.STORE_CONTENT,
FieldActions.INDEX_EXACT,
FieldActions.INDEX_FREETEXT,
FieldActions.SORTABLE,
FieldActions.COLLAPSE,
FieldActions.TAG,
FieldActions.FACET,
):
raise errors.IndexerError("Unknown field action: %r" % action)
info = self._action_info[action]
# Check parameter names
for key in kwargs.keys():
if key not in info[1]:
raise errors.IndexerError("Unknown parameter name for action %r: %r" % (info[0], key))
# Fields cannot be indexed both with "EXACT" and "FREETEXT": whilst we
# could implement this, the query parser wouldn't know what to do with
# searches.
if action == FieldActions.INDEX_EXACT:
if FieldActions.INDEX_FREETEXT in self._actions:
raise errors.IndexerError("Field %r is already marked for indexing "
"as free text: cannot mark for indexing "
"as exact text as well" % self._fieldname)
if action == FieldActions.INDEX_FREETEXT:
if FieldActions.INDEX_EXACT in self._actions:
raise errors.IndexerError("Field %r is already marked for indexing "
"as exact text: cannot mark for indexing "
"as free text as well" % self._fieldname)
# Fields cannot be indexed as more than one type for "SORTABLE": to
# implement this, we'd need to use a different prefix for each sortable
# type, but even then the search end wouldn't know what to sort on when
# searching. Also, if they're indexed as "COLLAPSE", the value must be
# stored in the right format for the type "SORTABLE".
if action == FieldActions.SORTABLE or action == FieldActions.COLLAPSE:
if action == FieldActions.COLLAPSE:
sorttype = None
else:
try:
sorttype = kwargs['type']
except KeyError:
sorttype = 'string'
kwargs['type'] = sorttype
action = FieldActions.SORT_AND_COLLAPSE
try:
oldsortactions = self._actions[FieldActions.SORT_AND_COLLAPSE]
except KeyError:
oldsortactions = ()
if len(oldsortactions) > 0:
for oldsortaction in oldsortactions:
oldsorttype = oldsortaction['type']
if sorttype == oldsorttype or oldsorttype is None:
# Use new type
self._actions[action] = []
elif sorttype is None:
# Use old type
return
else:
raise errors.IndexerError("Field %r is already marked for "
"sorting, with a different "
"sort type" % self._fieldname)
if 'prefix' in info[3]:
field_mappings.add_prefix(self._fieldname)
if 'slot' in info[3]:
purposes = info[3]['slot']
if isinstance(purposes, basestring):
field_mappings.add_slot(self._fieldname, purposes)
else:
slotnum = None
for purpose in purposes:
slotnum = field_mappings.get_slot(self._fieldname, purpose)
if slotnum is not None:
break
for purpose in purposes:
field_mappings.add_slot(self._fieldname, purpose, slotnum=slotnum)
# Make an entry for the action
if action not in self._actions:
self._actions[action] = []
# Check for repetitions of actions
for old_action in self._actions[action]:
if old_action == kwargs:
return
# Append the action to the list of actions
self._actions[action].append(kwargs)
def perform(self, doc, value, context):
"""Perform the actions on the field.
- `doc` is a ProcessedDocument to store the result of the actions in.
- `value` is a string holding the value of the field.
- `context` is an ActionContext object used to keep state in.
"""
for type, actionlist in self._actions.iteritems():
info = self._action_info[type]
for kwargs in actionlist:
info[2](self._fieldname, doc, value, context, **kwargs)
_action_info = {
STORE_CONTENT: ('STORE_CONTENT', (), _act_store_content, {}, ),
INDEX_EXACT: ('INDEX_EXACT', (), _act_index_exact, {'prefix': True}, ),
INDEX_FREETEXT: ('INDEX_FREETEXT', ('weight', 'language', 'stop', 'spell', 'nopos', 'allow_field_specific', 'search_by_default', ),
_act_index_freetext, {'prefix': True, }, ),
SORTABLE: ('SORTABLE', ('type', ), None, {'slot': 'collsort',}, ),
COLLAPSE: ('COLLAPSE', (), None, {'slot': 'collsort',}, ),
TAG: ('TAG', (), _act_tag, {'prefix': True,}, ),
FACET: ('FACET', ('type', ), _act_facet, {'prefix': True, 'slot': 'facet',}, ),
SORT_AND_COLLAPSE: ('SORT_AND_COLLAPSE', ('type', ), _act_sort_and_collapse, {'slot': 'collsort',}, ),
}
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/fieldmappings.py 0000644 0001750 0001750 00000012624 10667526666 016717 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""fieldmappings.py: Mappings from field names to term prefixes, etc.
"""
__docformat__ = "restructuredtext en"
import cPickle as _cPickle
class FieldMappings(object):
"""Mappings from field names to term prefixes, slot values, etc.
The following mappings are maintained:
- a mapping from field name to the string prefix to insert at the start of
terms.
- a mapping from field name to the slot numbers to store the field contents
in.
"""
__slots__ = '_prefixes', '_prefixcount', '_slots', '_slotcount',
def __init__(self, serialised=None):
"""Create a new field mapping object, or unserialise a saved one.
"""
if serialised is not None:
(self._prefixes, self._prefixcount,
self._slots, self._slotcount) = _cPickle.loads(serialised)
else:
self._prefixes = {}
self._prefixcount = 0
self._slots = {}
self._slotcount = 0
def _genPrefix(self):
"""Generate a previously unused prefix.
Prefixes are uppercase letters, and start with 'X' (this is a Xapian
convention, for compatibility with other Xapian tools: other starting
letters are reserved for special meanings):
>>> maps = FieldMappings()
>>> maps._genPrefix()
'XA'
>>> maps._genPrefix()
'XB'
>>> [maps._genPrefix() for i in xrange(60)]
['XC', 'XD', 'XE', 'XF', 'XG', 'XH', 'XI', 'XJ', 'XK', 'XL', 'XM', 'XN', 'XO', 'XP', 'XQ', 'XR', 'XS', 'XT', 'XU', 'XV', 'XW', 'XX', 'XY', 'XZ', 'XAA', 'XBA', 'XCA', 'XDA', 'XEA', 'XFA', 'XGA', 'XHA', 'XIA', 'XJA', 'XKA', 'XLA', 'XMA', 'XNA', 'XOA', 'XPA', 'XQA', 'XRA', 'XSA', 'XTA', 'XUA', 'XVA', 'XWA', 'XXA', 'XYA', 'XZA', 'XAB', 'XBB', 'XCB', 'XDB', 'XEB', 'XFB', 'XGB', 'XHB', 'XIB', 'XJB']
>>> maps = FieldMappings()
>>> [maps._genPrefix() for i in xrange(27*26 + 5)][-10:]
['XVZ', 'XWZ', 'XXZ', 'XYZ', 'XZZ', 'XAAA', 'XBAA', 'XCAA', 'XDAA', 'XEAA']
"""
res = []
self._prefixcount += 1
num = self._prefixcount
while num != 0:
ch = (num - 1) % 26
res.append(chr(ch + ord('A')))
num -= ch
num = num // 26
return 'X' + ''.join(res)
def get_fieldname_from_prefix(self, prefix):
"""Get a fieldname from a prefix.
If the prefix is not found, return None.
"""
for key, val in self._prefixes.iteritems():
if val == prefix:
return key
return None
def get_prefix(self, fieldname):
"""Get the prefix used for a given field name.
"""
return self._prefixes[fieldname]
def get_slot(self, fieldname, purpose):
"""Get the slot number used for a given field name and purpose.
"""
return self._slots[(fieldname, purpose)]
def add_prefix(self, fieldname):
"""Allocate a prefix for the given field.
If a prefix is already allocated for this field, this has no effect.
"""
if fieldname in self._prefixes:
return
self._prefixes[fieldname] = self._genPrefix()
def add_slot(self, fieldname, purpose, slotnum=None):
"""Allocate a slot number for the given field and purpose.
If a slot number is already allocated for this field and purpose, this
has no effect.
Returns the slot number allocated for the field and purpose (whether
newly allocated, or previously allocated).
If `slotnum` is supplied, the number contained in it is used to
allocate the new slot, instead of allocating a new number. No checks
will be made to ensure that the slot number doesn't collide with
existing (or later allocated) numbers: the main purpose of this
parameter is to share allocations - ie, to collide deliberately.
"""
try:
return self._slots[(fieldname, purpose)]
except KeyError:
pass
if slotnum is None:
self._slots[(fieldname, purpose)] = self._slotcount
self._slotcount += 1
return self._slotcount - 1
else:
self._slots[(fieldname, purpose)] = slotnum
return slotnum
def serialise(self):
"""Serialise the field mappings to a string.
This can be unserialised by passing the result of this method to the
constructor of a new FieldMappings object.
"""
return _cPickle.dumps((self._prefixes,
self._prefixcount,
self._slots,
self._slotcount,
), 2)
xappy-0.5/xappy/fieldmappings_doctest1.txt 0000644 0001750 0001750 00000000273 10653377546 020705 0 ustar richard richard
Test basic workings of the FieldMappings.
>>> maps = FieldMappings()
>>> maps.get_fieldname_from_prefix('XA')
>>> maps.add_prefix('foo')
>>> maps.get_fieldname_from_prefix('XA')
'foo'
xappy-0.5/xappy/highlight.py 0000644 0001750 0001750 00000024105 10725764413 016026 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""highlight.py: Highlight and summarise text.
"""
__docformat__ = "restructuredtext en"
import re
import xapian
class Highlighter(object):
"""Class for highlighting text and creating contextual summaries.
>>> hl = Highlighter("en")
>>> hl.makeSample('Hello world.', ['world'])
'Hello world.'
>>> hl.highlight('Hello world', ['world'], ('<', '>'))
'Hello '
"""
# split string into words, spaces, punctuation and markup tags
_split_re = re.compile(r'<\w+[^>]*>|\w+>|[\w\']+|\s+|[^\w\'\s<>/]+')
def __init__(self, language_code='en', stemmer=None):
"""Create a new highlighter for the specified language.
"""
if stemmer is not None:
self.stem = stemmer
else:
self.stem = xapian.Stem(language_code)
def _split_text(self, text, strip_tags=False):
"""Split some text into words and non-words.
- `text` is the text to process. It may be a unicode object or a utf-8
encoded simple string.
- `strip_tags` is a flag - False to keep tags, True to strip all tags
from the output.
Returns a list of utf-8 encoded simple strings.
"""
if isinstance(text, unicode):
text = text.encode('utf-8')
words = self._split_re.findall(text)
if strip_tags:
return [w for w in words if w[0] != '<']
else:
return words
def _strip_prefix(self, term):
"""Strip the prefix off a term.
Prefixes are any initial capital letters, with the exception that R always
ends a prefix, even if followed by capital letters.
>>> hl = Highlighter("en")
>>> print hl._strip_prefix('hello')
hello
>>> print hl._strip_prefix('Rhello')
hello
>>> print hl._strip_prefix('XARHello')
Hello
>>> print hl._strip_prefix('XAhello')
hello
>>> print hl._strip_prefix('XAh')
h
>>> print hl._strip_prefix('XA')
"""
for p in xrange(len(term)):
if term[p].islower():
return term[p:]
elif term[p] == 'R':
return term[p+1:]
return ''
def _query_to_stemmed_words(self, query):
"""Convert a query to a list of stemmed words.
- `query` is the query to parse: it may be xapian.Query object, or a
sequence of terms.
"""
if isinstance(query, xapian.Query):
return [self._strip_prefix(t) for t in query]
else:
return [self.stem(q.lower()) for q in query]
def makeSample(self, text, query, maxlen=600, hl=None):
"""Make a contextual summary from the supplied text.
This basically works by splitting the text into phrases, counting the query
terms in each, and keeping those with the most.
Any markup tags in the text will be stripped.
`text` is the source text to summarise.
`query` is either a Xapian query object or a list of (unstemmed) term strings.
`maxlen` is the maximum length of the generated summary.
`hl` is a pair of strings to insert around highlighted terms, e.g. ('', ' ')
"""
# coerce maxlen into an int, otherwise truncation doesn't happen
maxlen = int(maxlen)
words = self._split_text(text, True)
terms = self._query_to_stemmed_words(query)
# build blocks delimited by puncuation, and count matching words in each block
# blocks[n] is a block [firstword, endword, charcount, termcount, selected]
blocks = []
start = end = count = blockchars = 0
while end < len(words):
blockchars += len(words[end])
if words[end].isalnum():
if self.stem(words[end].lower()) in terms:
count += 1
end += 1
elif words[end] in ',.;:?!\n':
end += 1
blocks.append([start, end, blockchars, count, False])
start = end
blockchars = 0
count = 0
else:
end += 1
if start != end:
blocks.append([start, end, blockchars, count, False])
if len(blocks) == 0:
return ''
# select high-scoring blocks first, down to zero-scoring
chars = 0
for count in xrange(3, -1, -1):
for b in blocks:
if b[3] >= count:
b[4] = True
chars += b[2]
if chars >= maxlen: break
if chars >= maxlen: break
# assemble summary
words2 = []
lastblock = -1
for i, b in enumerate(blocks):
if b[4]:
if i != lastblock + 1:
words2.append('..')
words2.extend(words[b[0]:b[1]])
lastblock = i
if not blocks[-1][4]:
words2.append('..')
# trim down to maxlen
l = 0
for i in xrange (len (words2)):
l += len (words2[i])
if l >= maxlen:
words2[i:] = ['..']
break
if hl is None:
return ''.join(words2)
else:
return self._hl(words2, terms, hl)
def highlight(self, text, query, hl, strip_tags=False):
"""Add highlights (string prefix/postfix) to a string.
`text` is the source to highlight.
`query` is either a Xapian query object or a list of (unstemmed) term strings.
`hl` is a pair of highlight strings, e.g. ('', ' ')
`strip_tags` strips HTML markout iff True
>>> hl = Highlighter()
>>> qp = xapian.QueryParser()
>>> q = qp.parse_query('cat dog')
>>> tags = ('[[', ']]')
>>> hl.highlight('The cat went Dogging; but was dog tired .', q, tags)
'The [[cat]] went [[Dogging]]; but was [[dog]] tired .'
"""
words = self._split_text(text, strip_tags)
terms = self._query_to_stemmed_words(query)
return self._hl(words, terms, hl)
def _hl(self, words, terms, hl):
"""Add highlights to a list of words.
`words` is the list of words and non-words to be highlighted..
`terms` is the list of stemmed words to look for.
"""
for i, w in enumerate(words):
# HACK - more forgiving about stemmed terms
wl = w.lower()
if wl in terms or self.stem (wl) in terms:
words[i] = ''.join((hl[0], w, hl[1]))
return ''.join(words)
__test__ = {
'no_punc': r'''
Test the highlighter's behaviour when there is no punctuation in the sample
text (regression test - used to return no output):
>>> hl = Highlighter("en")
>>> hl.makeSample('Hello world', ['world'])
'Hello world'
''',
'stem_levels': r'''
Test highlighting of words, and how it works with stemming:
>>> hl = Highlighter("en")
# "word" and "wording" stem to "word", so the following 4 calls all return
# the same thing
>>> hl.makeSample('Hello. word. wording. wordinging.', ['word'], hl='<>')
'Hello. . . wordinging.'
>>> hl.highlight('Hello. word. wording. wordinging.', ['word'], '<>')
'Hello. . . wordinging.'
>>> hl.makeSample('Hello. word. wording. wordinging.', ['wording'], hl='<>')
'Hello. . . wordinging.'
>>> hl.highlight('Hello. word. wording. wordinging.', ['wording'], '<>')
'Hello. . . wordinging.'
# "wordinging" stems to "wording", so only the last two words are
# highlighted for this one.
>>> hl.makeSample('Hello. word. wording. wordinging.', ['wordinging'], hl='<>')
'Hello. word. . .'
>>> hl.highlight('Hello. word. wording. wordinging.', ['wordinging'], '<>')
'Hello. word. . .'
''',
'supplied_stemmer': r'''
Test behaviour if we pass in our own stemmer:
>>> stem = xapian.Stem('en')
>>> hl = Highlighter(stemmer=stem)
>>> hl.highlight('Hello. word. wording. wordinging.', ['word'], '<>')
'Hello. . . wordinging.'
''',
'unicode': r'''
Test behaviour if we pass in unicode input:
>>> hl = Highlighter('en')
>>> hl.highlight(u'Hello\xf3. word. wording. wordinging.', ['word'], '<>')
'Hello\xc3\xb3. . . wordinging.'
''',
'no_sample': r'''
Test behaviour if we pass in unicode input:
>>> hl = Highlighter('en')
>>> hl.makeSample(u'', ['word'])
''
''',
'short_samples': r'''
>>> hl = Highlighter('en')
>>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['hello'], 20, ('<', '>'))
'.. world ..'
>>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['hello'], 40, ('<', '>'))
'A boring start. world indeed...'
>>> hl.makeSample("A boring start. Hello world indeed. A boring end.", ['boring'], 40, ('<', '>'))
'A start... A end.'
''',
'apostrophes': r'''
>>> hl = Highlighter('en')
>>> hl.makeSample("A boring start. Hello world's indeed. A boring end.", ['world'], 40, ('<', '>'))
"A boring start. Hello indeed..."
''',
}
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/highlight_doctest1.txt 0000644 0001750 0001750 00000021246 10725765213 020025 0 ustar richard richard >>> teststr = r''''Python Tutorial Previous: 9. Classes Up: Python Tutorial Next: 11. Brief Tour of Subsections 10.1 Operating System Interface 10.2 File Wildcards 10.3 Command Line Arguments 10.4 Error Output Redirection and Program Termination 10.5 String Pattern Matching 10.6 Mathematics 10.7 Internet Access 10.8 Dates and Times 10.9 Data Compression 10.10 Performance Measurement 10.11 Quality Control 10.12 Batteries Included 10. Brief Tour of the Standard Library 10.1 Operating System Interface The os module provides dozens of functions for interacting with the operating system: >>> import os >>> os.system(\'time 0:02\') 0 >>> os.getcwd() # Return the current working directory \'C:\\\\Python25\' >>> os.chdir(\'/server/accesslogs\') Be sure to use the "import os" style instead of "from os import *". This will keep os.open() from shadowing the builtin open() function which operates much differently. The builtin dir() and help() functions are useful as interactive aids for working with large modules like os: >>> import os >>> dir(os) >>> help(os) For daily file and directory management tasks, the shutil module provides a higher level interface that is easier to use: >>> import shutil >>> shutil.copyfile(\'data.db\', \'archive.db\') >>> shutil.move(\'/build/executables\', \'installdir\') 10.2 File Wildcards The glob module provides a function for making file lists from directory wildcard searches: >>> import glob >>> glob.glob(\'*.py\') [\'primes.py\', \'random.py\', \'quote.py\'] 10.3 Command Line Arguments Common utility scripts often need to process command line arguments. These arguments are stored in the sys module\'s argv attribute as a list. For instance the following output results from running "python demo.py one two three" at the command line: >>> import sys >>> print sys.argv [\'demo.py\', \'one\', \'two\', \'three\'] The getopt module processes sys.argv using the conventions of the Unix getopt() function. More powerful and flexible command line processing is provided by the optparse module. 10.4 Error Output Redirection and Program Termination The sys module also has attributes for stdin, stdout, and stderr. The latter is useful for emitting warnings and error messages to make them visible even when stdout has been redirected: >>> sys.stderr.write(\'Warning, log file not found starting a new one\\n\') Warning, log file not found starting a new one The most direct way to terminate a script is to use "sys.exit()". 10.5 String Pattern Matching The re module provides regular expression tools for advanced string processing. For complex matching and manipulation, regular expressions offer succinct, optimized solutions: >>> import re >>> re.findall(r\'\\bf[a-z]*\', \'which foot or hand fell fastest\') [\'foot\', \'fell\', \'fastest\'] >>> re.sub(r\'(\\b[a-z]+) \\1\', r\'\\1\', \'cat in the the hat\') \'cat in the hat\' When only simple capabilities are needed, string methods are preferred because they are easier to read and debug: >>> \'tea for too\'.replace(\'too\', \'two\') \'tea for two\' 10.6 Mathematics The math module gives access to the underlying C library functions for floating point math: >>> import math >>> math.cos(math.pi / 4.0) 0.70710678118654757 >>> math.log(1024, 2) 10.0 The random module provides tools for making random selections: >>> import random >>> random.choice([\'apple\', \'pear\', \'banana\']) \'apple\' >>> random.sample(xrange(100), 10) # sampling without replacement [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] >>> random.random() # random float 0.17970987693706186 >>> random.randrange(6) # random integer chosen from range(6) 4 10.7 Internet Access There are a number of modules for accessing the internet and processing internet protocols. Two of the simplest are urllib2 for retrieving data from urls and smtplib for sending mail: >>> import urllib2 >>> for line in urllib2.urlopen(\'http://tycho.usno.navy.mil/cgi-bin/timer.pl\'): ... if \'EST\' in line or \'EDT\' in line: # look for Eastern Time ... print line Nov. 25, 09:43:32 PM EST >>> import smtplib >>> server = smtplib.SMTP(\'localhost\') >>> server.sendmail(\'soothsayer@example.org\', \'jcaesar@example.org\', """To: jcaesar@example.org From: soothsayer@example.org Beware the Ides of March. """) >>> server.quit() 10.8 Dates and Times The datetime module supplies classes for manipulating dates and times in both simple and complex ways. While date and time arithmetic is supported, the focus of the implementation is on efficient member extraction for output formatting and manipulation. The module also supports objects that are timezone aware. # dates are easily constructed and formatted >>> from datetime import date >>> now = date.today() >>> now datetime.date(2003, 12, 2) >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") \'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.\' # dates support calendar arithmetic >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days 14368 10.9 Data Compression Common data archiving and compression formats are directly supported by modules including: zlib, gzip, bz2, zipfile, and tarfile. >>> import zlib >>> s = \'witch which has which witches wrist watch\' >>> len(s) 41 >>> t = zlib.compress(s) >>> len(t) 37 >>> zlib.decompress(t) \'witch which has which witches wrist watch\' >>> zlib.crc32(s) 226805979 10.10 Performance Measurement Some Python users develop a deep interest in knowing the relative performance of different approaches to the same problem. Python provides a measurement tool that answers those questions immediately. For example, it may be tempting to use the tuple packing and unpacking feature instead of the traditional approach to swapping arguments. The timeit module quickly demonstrates a modest performance advantage: >>> from timeit import Timer >>> Timer(\'t=a; a=b; b=t\', \'a=1; b=2\').timeit() 0.57535828626024577 >>> Timer(\'a,b = b,a\', \'a=1; b=2\').timeit() 0.54962537085770791 In contrast to timeit\'s fine level of granularity, the profile and pstats modules provide tools for identifying time critical sections in larger blocks of code. 10.11 Quality Control One approach for developing high quality software is to write tests for each function as it is developed and to run those tests frequently during the development process. The doctest module provides a tool for scanning a module and validating tests embedded in a program\'s docstrings. Test construction is as simple as cutting-and-pasting a typical call along with its results into the docstring. This improves the documentation by providing the user with an example and it allows the doctest module to make sure the code remains true to the documentation: def average(values): """Computes the arithmetic mean of a list of numbers. >>> print average([20, 30, 70]) 40.0 """ return sum(values, 0.0) / len(values) import doctest doctest.testmod() # automatically validate the embedded tests The unittest module is not as effortless as the doctest module, but it allows a more comprehensive set of tests to be maintained in a separate file: import unittest class TestStatisticalFunctions(unittest.TestCase): def test_average(self): self.assertEqual(average([20, 30, 70]), 40.0) self.assertEqual(round(average([1, 5, 7]), 1), 4.3) self.assertRaises(ZeroDivisionError, average, []) self.assertRaises(TypeError, average, 20, 30, 70) unittest.main() # Calling from the command line invokes all tests 10.12 Batteries Included Python has a ``batteries included\'\' philosophy. This is best seen through the sophisticated and robust capabilities of its larger packages. For example: The xmlrpclib and SimpleXMLRPCServer modules make implementing remote procedure calls into an almost trivial task. Despite the modules names, no direct knowledge or handling of XML is needed. The email package is a library for managing email messages, including MIME and other RFC 2822-based message documents. Unlike smtplib and poplib which actually send and receive messages, the email package has a complete toolset for building or decoding complex message structures (including attachments) and for implementing internet encoding and header protocols. The xml.dom and xml.sax packages provide robust support for parsing this popular data interchange format. Likewise, the csv module supports direct reads and writes in a common database format. Together, these modules and packages greatly simplify data interchange between python applications and other tools. Internationalization is supported by a number of modules including gettext, locale, and the codecs package. Python Tutorial Previous: 9. Classes Up: Python Tutorial Next: 11. Br'''
>>> hl = Highlighter()
>>> out = hl.highlight(teststr, ('print',), ('', ' '))
xappy-0.5/xappy/indexerconnection.py 0000644 0001750 0001750 00000076070 11005453337 017575 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""indexerconnection.py: A connection to the search engine for indexing.
"""
__docformat__ = "restructuredtext en"
import _checkxapian
import cPickle
import xapian
from datastructures import *
import errors
from fieldactions import *
import fieldmappings
import memutils
from replaylog import log
class IndexerConnection(object):
"""A connection to the search engine for indexing.
"""
def __init__(self, indexpath):
"""Create a new connection to the index.
There may only be one indexer connection for a particular database open
at a given time. Therefore, if a connection to the database is already
open, this will raise a xapian.DatabaseLockError.
If the database doesn't already exist, it will be created.
"""
self._index = log(xapian.WritableDatabase, indexpath, xapian.DB_CREATE_OR_OPEN)
self._indexpath = indexpath
# Read existing actions.
self._field_actions = {}
self._field_mappings = fieldmappings.FieldMappings()
self._facet_hierarchy = {}
self._facet_query_table = {}
self._next_docid = 0
self._config_modified = False
self._load_config()
# Set management of the memory used.
# This can be removed once Xapian implements this itself.
self._mem_buffered = 0
self.set_max_mem_use()
def set_max_mem_use(self, max_mem=None, max_mem_proportion=None):
"""Set the maximum memory to use.
This call allows the amount of memory to use to buffer changes to be
set. This will affect the speed of indexing, but should not result in
other changes to the indexing.
Note: this is an approximate measure - the actual amount of memory used
max exceed the specified amount. Also, note that future versions of
xapian are likely to implement this differently, so this setting may be
entirely ignored.
The absolute amount of memory to use (in bytes) may be set by setting
max_mem. Alternatively, the proportion of the available memory may be
set by setting max_mem_proportion (this should be a value between 0 and
1).
Setting too low a value will result in excessive flushing, and very
slow indexing. Setting too high a value will result in excessive
buffering, leading to swapping, and very slow indexing.
A reasonable default for max_mem_proportion for a system which is
dedicated to indexing is probably 0.5: if other tasks are also being
performed on the system, the value should be lowered.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if max_mem is not None and max_mem_proportion is not None:
raise errors.IndexerError("Only one of max_mem and "
"max_mem_proportion may be specified")
if max_mem is None and max_mem_proportion is None:
self._max_mem = None
if max_mem_proportion is not None:
physmem = memutils.get_physical_memory()
if physmem is not None:
max_mem = int(physmem * max_mem_proportion)
self._max_mem = max_mem
def _store_config(self):
"""Store the configuration for the database.
Currently, this stores the configuration in a file in the database
directory, so changes to it are not protected by transactions. When
support is available in xapian for storing metadata associated with
databases. this will be used instead of a file.
"""
assert self._index is not None
config_str = cPickle.dumps((
self._field_actions,
self._field_mappings.serialise(),
self._facet_hierarchy,
self._facet_query_table,
self._next_docid,
), 2)
log(self._index.set_metadata, '_xappy_config', config_str)
self._config_modified = False
def _load_config(self):
"""Load the configuration for the database.
"""
assert self._index is not None
config_str = log(self._index.get_metadata, '_xappy_config')
if len(config_str) == 0:
return
try:
(self._field_actions, mappings, self._facet_hierarchy, self._facet_query_table, self._next_docid) = cPickle.loads(config_str)
except ValueError:
# Backwards compatibility - configuration used to lack _facet_hierarchy and _facet_query_table
(self._field_actions, mappings, self._next_docid) = cPickle.loads(config_str)
self._facet_hierarchy = {}
self._facet_query_table = {}
self._field_mappings = fieldmappings.FieldMappings(mappings)
self._config_modified = False
def _allocate_id(self):
"""Allocate a new ID.
"""
while True:
idstr = "%x" % self._next_docid
self._next_docid += 1
if not self._index.term_exists('Q' + idstr):
break
self._config_modified = True
return idstr
def add_field_action(self, fieldname, fieldtype, **kwargs):
"""Add an action to be performed on a field.
Note that this change to the configuration will not be preserved on
disk until the next call to flush().
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if fieldname in self._field_actions:
actions = self._field_actions[fieldname]
else:
actions = FieldActions(fieldname)
self._field_actions[fieldname] = actions
actions.add(self._field_mappings, fieldtype, **kwargs)
self._config_modified = True
def clear_field_actions(self, fieldname):
"""Clear all actions for the specified field.
This does not report an error if there are already no actions for the
specified field.
Note that this change to the configuration will not be preserved on
disk until the next call to flush().
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if fieldname in self._field_actions:
del self._field_actions[fieldname]
self._config_modified = True
def get_fields_with_actions(self):
"""Get a list of field names which have actions defined.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
return self._field_actions.keys()
def process(self, document):
"""Process an UnprocessedDocument with the settings in this database.
The resulting ProcessedDocument is returned.
Note that this processing will be automatically performed if an
UnprocessedDocument is supplied to the add() or replace() methods of
IndexerConnection. This method is exposed to allow the processing to
be performed separately, which may be desirable if you wish to manually
modify the processed document before adding it to the database, or if
you want to split processing of documents from adding documents to the
database for performance reasons.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
result = ProcessedDocument(self._field_mappings)
result.id = document.id
context = ActionContext(self._index)
for field in document.fields:
try:
actions = self._field_actions[field.name]
except KeyError:
# If no actions are defined, just ignore the field.
continue
actions.perform(result, field.value, context)
return result
def _get_bytes_used_by_doc_terms(self, xapdoc):
"""Get an estimate of the bytes used by the terms in a document.
(This is a very rough estimate.)
"""
count = 0
for item in xapdoc.termlist():
# The term may also be stored in the spelling correction table, so
# double the amount used.
count += len(item.term) * 2
# Add a few more bytes for holding the wdf, and other bits and
# pieces.
count += 8
# Empirical observations indicate that about 5 times as much memory as
# the above calculation predicts is used for buffering in practice.
return count * 5
def add(self, document):
"""Add a new document to the search engine index.
If the document has a id set, and the id already exists in
the database, an exception will be raised. Use the replace() method
instead if you wish to overwrite documents.
Returns the id of the newly added document (making up a new
unique ID if no id was set).
The supplied document may be an instance of UnprocessedDocument, or an
instance of ProcessedDocument.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if not hasattr(document, '_doc'):
# It's not a processed document.
document = self.process(document)
# Ensure that we have a id
orig_id = document.id
if orig_id is None:
id = self._allocate_id()
document.id = id
else:
id = orig_id
if self._index.term_exists('Q' + id):
raise errors.IndexerError("Document ID of document supplied to add() is not unique.")
# Add the document.
xapdoc = document.prepare()
self._index.add_document(xapdoc)
if self._max_mem is not None:
self._mem_buffered += self._get_bytes_used_by_doc_terms(xapdoc)
if self._mem_buffered > self._max_mem:
self.flush()
if id is not orig_id:
document.id = orig_id
return id
def replace(self, document):
"""Replace a document in the search engine index.
If the document does not have a id set, an exception will be
raised.
If the document has a id set, and the id does not already
exist in the database, this method will have the same effect as add().
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if not hasattr(document, '_doc'):
# It's not a processed document.
document = self.process(document)
# Ensure that we have a id
id = document.id
if id is None:
raise errors.IndexerError("No document ID set for document supplied to replace().")
xapdoc = document.prepare()
self._index.replace_document('Q' + id, xapdoc)
if self._max_mem is not None:
self._mem_buffered += self._get_bytes_used_by_doc_terms(xapdoc)
if self._mem_buffered > self._max_mem:
self.flush()
def _make_synonym_key(self, original, field):
"""Make a synonym key (ie, the term or group of terms to store in
xapian).
"""
if field is not None:
prefix = self._field_mappings.get_prefix(field)
else:
prefix = ''
original = original.lower()
# Add the prefix to the start of each word.
return ' '.join((prefix + word for word in original.split(' ')))
def add_synonym(self, original, synonym, field=None,
original_field=None, synonym_field=None):
"""Add a synonym to the index.
- `original` is the word or words which will be synonym expanded in
searches (if multiple words are specified, each word should be
separated by a single space).
- `synonym` is a synonym for `original`.
- `field` is the field which the synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if original_field is None:
original_field = field
if synonym_field is None:
synonym_field = field
key = self._make_synonym_key(original, original_field)
# FIXME - this only works for exact fields which have no upper case
# characters, or single words
value = self._make_synonym_key(synonym, synonym_field)
self._index.add_synonym(key, value)
def remove_synonym(self, original, synonym, field=None):
"""Remove a synonym from the index.
- `original` is the word or words which will be synonym expanded in
searches (if multiple words are specified, each word should be
separated by a single space).
- `synonym` is a synonym for `original`.
- `field` is the field which this synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
key = self._make_synonym_key(original, field)
self._index.remove_synonym(key, synonym.lower())
def clear_synonyms(self, original, field=None):
"""Remove all synonyms for a word (or phrase).
- `field` is the field which this synonym is specific to. If no field
is specified, the synonym will be used for searches which are not
specific to any particular field.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
key = self._make_synonym_key(original, field)
self._index.clear_synonyms(key)
def _assert_facet(self, facet):
"""Raise an error if facet is not a declared facet field.
"""
for action in self._field_actions[facet]._actions:
if action == FieldActions.FACET:
return
raise errors.IndexerError("Field %r is not indexed as a facet" % facet)
def add_subfacet(self, subfacet, facet):
"""Add a subfacet-facet relationship to the facet hierarchy.
Any existing relationship for that subfacet is replaced.
Raises a KeyError if either facet or subfacet is not a field,
and an IndexerError if either facet or subfacet is not a facet field.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
self._assert_facet(facet)
self._assert_facet(subfacet)
self._facet_hierarchy[subfacet] = facet
self._config_modified = True
def remove_subfacet(self, subfacet):
"""Remove any existing facet hierarchy relationship for a subfacet.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if subfacet in self._facet_hierarchy:
del self._facet_hierarchy[subfacet]
self._config_modified = True
def get_subfacets(self, facet):
"""Get a list of subfacets of a facet.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
return [k for k, v in self._facet_hierarchy.iteritems() if v == facet]
FacetQueryType_Preferred = 1;
FacetQueryType_Never = 2;
def set_facet_for_query_type(self, query_type, facet, association):
"""Set the association between a query type and a facet.
The value of `association` must be one of
IndexerConnection.FacetQueryType_Preferred,
IndexerConnection.FacetQueryType_Never or None. A value of None removes
any previously set association.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if query_type is None:
raise errors.IndexerError("Cannot set query type information for None")
self._assert_facet(facet)
if query_type not in self._facet_query_table:
self._facet_query_table[query_type] = {}
if association is None:
if facet in self._facet_query_table[query_type]:
del self._facet_query_table[query_type][facet]
else:
self._facet_query_table[query_type][facet] = association;
if self._facet_query_table[query_type] == {}:
del self._facet_query_table[query_type]
self._config_modified = True
def get_facets_for_query_type(self, query_type, association):
"""Get the set of facets associated with a query type.
Only those facets associated with the query type in the specified
manner are returned; `association` must be one of
IndexerConnection.FacetQueryType_Preferred or
IndexerConnection.FacetQueryType_Never.
If the query type has no facets associated with it, None is returned.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if query_type not in self._facet_query_table:
return None
facet_dict = self._facet_query_table[query_type]
return set([facet for facet, assoc in facet_dict.iteritems() if assoc == association])
def set_metadata(self, key, value):
"""Set an item of metadata stored in the connection.
The value supplied will be returned by subsequent calls to
get_metadata() which use the same key.
Keys with a leading underscore are reserved for internal use - you
should not use such keys unless you really know what you are doing.
This will store the value supplied in the database. It will not be
visible to readers (ie, search connections) until after the next flush.
The key is limited to about 200 characters (the same length as a term
is limited to). The value can be several megabytes in size.
To remove an item of metadata, simply call this with a `value`
parameter containing an empty string.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if not hasattr(self._index, 'set_metadata'):
raise errors.IndexerError("Version of xapian in use does not support metadata")
log(self._index.set_metadata, key, value)
def get_metadata(self, key):
"""Get an item of metadata stored in the connection.
This returns a value stored by a previous call to set_metadata.
If the value is not found, this will return the empty string.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if not hasattr(self._index, 'get_metadata'):
raise errors.IndexerError("Version of xapian in use does not support metadata")
return log(self._index.get_metadata, key)
def delete(self, id):
"""Delete a document from the search engine index.
If the id does not already exist in the database, this method
will have no effect (and will not report an error).
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
self._index.delete_document('Q' + id)
def flush(self):
"""Apply recent changes to the database.
If an exception occurs, any changes since the last call to flush() may
be lost.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if self._config_modified:
self._store_config()
self._index.flush()
self._mem_buffered = 0
def close(self):
"""Close the connection to the database.
It is important to call this method before allowing the class to be
garbage collected, because it will ensure that any un-flushed changes
will be flushed. It also ensures that the connection is cleaned up
promptly.
No other methods may be called on the connection after this has been
called. (It is permissible to call close() multiple times, but
only the first call will have any effect.)
If an exception occurs, the database will be closed, but changes since
the last call to flush may be lost.
"""
if self._index is None:
return
try:
self.flush()
finally:
# There is currently no "close()" method for xapian databases, so
# we have to rely on the garbage collector. Since we never copy
# the _index property out of this class, there should be no cycles,
# so the standard python implementation should garbage collect
# _index straight away. A close() method is planned to be added to
# xapian at some point - when it is, we should call it here to make
# the code more robust.
self._index = None
self._indexpath = None
self._field_actions = None
self._config_modified = False
def get_doccount(self):
"""Count the number of documents in the database.
This count will include documents which have been added or removed but
not yet flushed().
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
return self._index.get_doccount()
def iterids(self):
"""Get an iterator which returns all the ids in the database.
The unqiue_ids are currently returned in binary lexicographical sort
order, but this should not be relied on.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
return PrefixedTermIter('Q', self._index.allterms())
def get_document(self, id):
"""Get the document with the specified unique ID.
Raises a KeyError if there is no such document. Otherwise, it returns
a ProcessedDocument.
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
postlist = self._index.postlist('Q' + id)
try:
plitem = postlist.next()
except StopIteration:
# Unique ID not found
raise KeyError('Unique ID %r not found' % id)
try:
postlist.next()
raise errors.IndexerError("Multiple documents " #pragma: no cover
"found with same unique ID")
except StopIteration:
# Only one instance of the unique ID found, as it should be.
pass
result = ProcessedDocument(self._field_mappings)
result.id = id
result._doc = self._index.get_document(plitem.docid)
return result
def iter_synonyms(self, prefix=""):
"""Get an iterator over the synonyms.
- `prefix`: if specified, only synonym keys with this prefix will be
returned.
The iterator returns 2-tuples, in which the first item is the key (ie,
a 2-tuple holding the term or terms which will be synonym expanded,
followed by the fieldname specified (or None if no fieldname)), and the
second item is a tuple of strings holding the synonyms for the first
item.
These return values are suitable for the dict() builtin, so you can
write things like:
>>> conn = IndexerConnection('foo')
>>> conn.add_synonym('foo', 'bar')
>>> conn.add_synonym('foo bar', 'baz')
>>> conn.add_synonym('foo bar', 'foo baz')
>>> dict(conn.iter_synonyms())
{('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
return SynonymIter(self._index, self._field_mappings, prefix)
def iter_subfacets(self):
"""Get an iterator over the facet hierarchy.
The iterator returns 2-tuples, in which the first item is the
subfacet and the second item is its parent facet.
The return values are suitable for the dict() builtin, for example:
>>> conn = IndexerConnection('db')
>>> conn.add_field_action('foo', FieldActions.FACET)
>>> conn.add_field_action('bar', FieldActions.FACET)
>>> conn.add_field_action('baz', FieldActions.FACET)
>>> conn.add_subfacet('foo', 'bar')
>>> conn.add_subfacet('baz', 'bar')
>>> dict(conn.iter_subfacets())
{'foo': 'bar', 'baz': 'bar'}
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if 'facets' in _checkxapian.missing_features:
raise errors.IndexerError("Facets unsupported with this release of xapian")
return self._facet_hierarchy.iteritems()
def iter_facet_query_types(self, association):
"""Get an iterator over query types and their associated facets.
Only facets associated with the query types in the specified manner
are returned; `association` must be one of IndexerConnection.FacetQueryType_Preferred
or IndexerConnection.FacetQueryType_Never.
The iterator returns 2-tuples, in which the first item is the query
type and the second item is the associated set of facets.
The return values are suitable for the dict() builtin, for example:
>>> conn = IndexerConnection('db')
>>> conn.add_field_action('foo', FieldActions.FACET)
>>> conn.add_field_action('bar', FieldActions.FACET)
>>> conn.add_field_action('baz', FieldActions.FACET)
>>> conn.set_facet_for_query_type('type1', 'foo', conn.FacetQueryType_Preferred)
>>> conn.set_facet_for_query_type('type1', 'bar', conn.FacetQueryType_Never)
>>> conn.set_facet_for_query_type('type1', 'baz', conn.FacetQueryType_Never)
>>> conn.set_facet_for_query_type('type2', 'bar', conn.FacetQueryType_Preferred)
>>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Preferred))
{'type1': set(['foo']), 'type2': set(['bar'])}
>>> dict(conn.iter_facet_query_types(conn.FacetQueryType_Never))
{'type1': set(['bar', 'baz'])}
"""
if self._index is None:
raise errors.IndexerError("IndexerConnection has been closed")
if 'facets' in _checkxapian.missing_features:
raise errors.IndexerError("Facets unsupported with this release of xapian")
return FacetQueryTypeIter(self._facet_query_table, association)
class PrefixedTermIter(object):
"""Iterate through all the terms with a given prefix.
"""
def __init__(self, prefix, termiter):
"""Initialise the prefixed term iterator.
- `prefix` is the prefix to return terms for.
- `termiter` is a xapian TermIterator, which should be at its start.
"""
# The algorithm used in next() currently only works for single
# character prefixes, so assert that the prefix is single character.
# To deal with multicharacter prefixes, we need to check for terms
# which have a starting prefix equal to that given, but then have a
# following uppercase alphabetic character, indicating that the actual
# prefix is longer than the target prefix. We then need to skip over
# these. Not too hard to implement, but we don't need it yet.
assert(len(prefix) == 1)
self._started = False
self._prefix = prefix
self._prefixlen = len(prefix)
self._termiter = termiter
def __iter__(self):
return self
def next(self):
"""Get the next term with the specified prefix.
"""
if not self._started:
term = self._termiter.skip_to(self._prefix).term
self._started = True
else:
term = self._termiter.next().term
if len(term) < self._prefixlen or term[:self._prefixlen] != self._prefix:
raise StopIteration
return term[self._prefixlen:]
class SynonymIter(object):
"""Iterate through a list of synonyms.
"""
def __init__(self, index, field_mappings, prefix):
"""Initialise the synonym iterator.
- `index` is the index to get the synonyms from.
- `field_mappings` is the FieldMappings object for the iterator.
- `prefix` is the prefix to restrict the returned synonyms to.
"""
self._index = index
self._field_mappings = field_mappings
self._syniter = self._index.synonym_keys(prefix)
def __iter__(self):
return self
def next(self):
"""Get the next synonym.
"""
synkey = self._syniter.next()
pos = 0
for char in synkey:
if char.isupper(): pos += 1
else: break
if pos == 0:
fieldname = None
terms = synkey
else:
prefix = synkey[:pos]
fieldname = self._field_mappings.get_fieldname_from_prefix(prefix)
terms = ' '.join((term[pos:] for term in synkey.split(' ')))
synval = tuple(self._index.synonyms(synkey))
return ((terms, fieldname), synval)
class FacetQueryTypeIter(object):
"""Iterate through all the query types and their associated facets.
"""
def __init__(self, facet_query_table, association):
"""Initialise the query type facet iterator.
Only facets associated with each query type in the specified
manner are returned (`association` must be one of
IndexerConnection.FacetQueryType_Preferred or
IndexerConnection.FacetQueryType_Never).
"""
self._table_iter = facet_query_table.iteritems()
self._association = association
def __iter__(self):
return self
def next(self):
"""Get the next (query type, facet set) 2-tuple.
"""
query_type, facet_dict = self._table_iter.next()
facet_list = [facet for facet, association in facet_dict.iteritems() if association == self._association]
if len(facet_list) == 0:
return self.next()
return (query_type, set(facet_list))
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/indexerconnection_doctest1.txt 0000644 0001750 0001750 00000016054 10722552030 021561 0 ustar richard richard
>>> from datastructures import *
>>> from fieldactions import *
Open a connection for indexing:
>>> conn = IndexerConnection('foo')
There can only be one IndexerConnection in existence for a given path at a
time:
>>> conn = IndexerConnection('foo') #doctest:+ELLIPSIS
Traceback (most recent call last):
...
DatabaseLockError: Unable to acquire database write lock on foo...
We should have no documents in the database yet:
>>> conn.get_doccount()
0
Add some field actions to the database:
>>> conn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> conn.add_field_action('author', FieldActions.INDEX_EXACT)
>>> conn.add_field_action('title', FieldActions.INDEX_FREETEXT)
We can't index as both EXACT and FREETEXT:
>>> conn.add_field_action('author', FieldActions.INDEX_FREETEXT, weight=5, language='en')
Traceback (most recent call last):
...
IndexerError: Field 'author' is already marked for indexing as exact text: cannot mark for indexing as free text as well
>>> conn.add_field_action('title', FieldActions.INDEX_EXACT)
Traceback (most recent call last):
...
IndexerError: Field 'title' is already marked for indexing as free text: cannot mark for indexing as exact text as well
We can add multiple STORE_CONTENT actions though (subsequent ones have no
further effect).
>>> conn.add_field_action('author', FieldActions.STORE_CONTENT)
Field actions are checked for basic validity:
>>> conn.add_field_action('author', None)
Traceback (most recent call last):
...
IndexerError: Unknown field action: None
>>> conn.add_field_action('author', FieldActions.STORE_CONTENT, foo=1)
Traceback (most recent call last):
...
IndexerError: Unknown parameter name for action 'STORE_CONTENT': 'foo'
We can ensure there are no actions for a given field by using
clear_field_actions():
>>> conn.clear_field_actions('title')
This doesn't complain even if we've never mentioned the field before:
>>> conn.clear_field_actions('foo')
Then we can add a field action back again:
>>> conn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=10, language='en')
We have to wipe out any old actions on the field to change the actions:
>>> conn.clear_field_actions('author')
>>> conn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> conn.add_field_action('author', FieldActions.INDEX_FREETEXT, weight=5, language='en')
>>> conn.clear_field_actions('title')
>>> conn.add_field_action('title', FieldActions.INDEX_EXACT)
We should have no documents in the database yet:
>>> conn.get_doccount()
0
Build up a document:
>>> doc = UnprocessedDocument()
We can add field instances. Multiple instances of a field are valid.
>>> doc.fields.append(Field('author', 'Richard Boulton'))
>>> doc.fields.append(Field('author', 'Charlie Hull'))
>>> doc.fields.append(Field('title', 'Test document'))
We can get a vaguely pretty display of the contents of an
UnprocessedDocument():
>>> print doc
UnprocessedDocument(None, [Field('author', 'Richard Boulton'), Field('author', 'Charlie Hull'), Field('title', 'Test document')])
We can process a document explicitly, if we want to.
>>> pdoc = conn.process(doc)
Only the "author" field appears in the output, because only it was given the
action STORE_CONTENT.
>>> pdoc.data
{'author': ['Richard Boulton', 'Charlie Hull']}
We can access the xapian document representation of the processed document:
>>> xdoc = pdoc.prepare()
>>> import cPickle
>>> cPickle.loads(xdoc.get_data())
{'author': ['Richard Boulton', 'Charlie Hull']}
>>> [(term.term, term.wdf, [pos for pos in term.positer]) for term in xdoc.termlist()]
[('XAboulton', 5, [2]), ('XAcharlie', 5, [13]), ('XAhull', 5, [14]), ('XArichard', 5, [1]), ('XB:Test document', 0, []), ('ZXAboulton', 5, []), ('ZXAcharli', 5, []), ('ZXAhull', 5, []), ('ZXArichard', 5, []), ('Zboulton', 5, []), ('Zcharli', 5, []), ('Zhull', 5, []), ('Zrichard', 5, []), ('boulton', 5, [2]), ('charlie', 5, [13]), ('hull', 5, [14]), ('richard', 5, [1])]
Adding the same document multiple times is fine if it doesn't have an id
assigned to it: a new ID will be allocated for each addition:
>>> conn.add(doc)
'0'
>>> conn.add(doc)
'1'
>>> conn.add(doc)
'2'
>>> conn.get_doccount()
3
We can set the unique ID ourselves, if we want:
>>> print repr(doc.id)
None
>>> doc.id = '4'
>>> print repr(doc.id)
'4'
>>> conn.add(doc)
'4'
>>> conn.get_doccount()
4
If we try adding a document with a unique ID which already exists we get an
error:
>>> doc.id = '1'
>>> print repr(doc.id)
'1'
>>> conn.add(doc)
Traceback (most recent call last):
...
IndexerError: Document ID of document supplied to add() is not unique.
>>> conn.get_doccount()
4
If we remove the id, it works again:
>>> doc.id = None
>>> print repr(doc.id)
None
>>> conn.add(doc)
'3'
>>> conn.get_doccount()
5
But it skips ID 4 because we manually added a document with that ID.
>>> conn.add(doc)
'5'
>>> conn.get_doccount()
6
Unique IDs don't have to be numbers: we can set them to anything we like.
>>> doc.id = 'SuperFoo'
>>> print repr(doc.id)
'SuperFoo'
>>> conn.add(doc)
'SuperFoo'
>>> conn.get_doccount()
7
We can delete documents by specifying the unique ID.
>>> conn.delete('5')
>>> conn.get_doccount()
6
Finally, we have to flush to apply the changes:
>>> conn.flush()
We can add more documents after the flush:
>>> doc.id = None
>>> conn.add(doc)
'6'
>>> conn.get_doccount()
7
We can add fields which don't have any configuration. These will be ignored.
>>> doc.fields.append(Field('text', 'Some boring text'))
>>> conn.add(doc)
'7'
>>> conn.get_doccount()
8
We can also supply fields as an iterator instead of a list:
>>> fieldlist = [Field('author', 'Richard Boulton')]
>>> doc.fields = iter(fieldlist)
>>> conn.add(doc)
'8'
>>> conn.get_doccount()
9
Calling close() will automatically call flush(), too:
>>> conn.close()
After calling close(), no other methods are valid:
>>> conn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=10, language='en')
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.clear_field_actions('author')
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.process(doc)
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.add(doc)
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.replace(doc)
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.delete('1')
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.flush()
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.get_doccount()
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.iterids()
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
>>> conn.get_document('1')
Traceback (most recent call last):
...
IndexerError: IndexerConnection has been closed
But calling close() multiple times is okay:
>>> conn.close()
Now that we've closed the connection, we can open a new one:
>>> conn = IndexerConnection('foo')
>>> conn.get_doccount()
9
xappy-0.5/xappy/indexerconnection_doctest2.txt 0000644 0001750 0001750 00000037057 10725037616 021603 0 ustar richard richard
>>> from datastructures import *
>>> from fieldactions import *
>>> from searchconnection import *
Open a connection for indexing:
>>> iconn = IndexerConnection('foo')
We should have no documents in the database yet:
>>> iconn.get_doccount()
0
We have to wipe out any old actions on the field to change the actions:
>>> iconn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=5, language='en')
>>> iconn.add_field_action('category', FieldActions.INDEX_EXACT)
>>> iconn.add_field_action('category', FieldActions.SORTABLE)
>>> iconn.add_field_action('category', FieldActions.COLLAPSE)
>>> iconn.add_field_action('text', FieldActions.INDEX_FREETEXT, language='en')
>>> iconn.add_field_action('other', FieldActions.INDEX_FREETEXT)
Build up a document:
>>> doc = UnprocessedDocument()
We can add field instances. Multiple instances of a field are valid.
>>> doc.fields.append(Field('author', 'Richard Boulton'))
>>> doc.fields.append(Field('category', 'Test document'))
>>> doc.fields.append(Field('title', 'Test document 1'))
>>> doc.fields.append(Field('text', 'This document is a basic test document.'))
We can process a document explicitly, if we want to.
>>> pdoc = iconn.process(doc)
>>> pdoc.data
{'title': ['Test document 1'], 'author': ['Richard Boulton']}
We can access the Xapian document representation of the processed document to
double check that this document has been indexed as we wanted:
>>> xdoc = pdoc.prepare()
>>> import cPickle
>>> cPickle.loads(xdoc.get_data()) == pdoc.data
True
>>> [(term.term, term.wdf, [pos for pos in term.positer]) for term in xdoc.termlist()]
[('1', 5, [3]), ('XA1', 5, [3]), ('XAdocument', 5, [2]), ('XAtest', 5, [1]), ('XB:Test document', 0, []), ('XCa', 1, [17]), ('XCbasic', 1, [18]), ('XCdocument', 2, [15, 20]), ('XCis', 1, [16]), ('XCtest', 1, [19]), ('XCthis', 1, [14]), ('ZXAdocument', 5, []), ('ZXAtest', 5, []), ('ZXCa', 1, []), ('ZXCbasic', 1, []), ('ZXCdocument', 2, []), ('ZXCis', 1, []), ('ZXCtest', 1, []), ('ZXCthis', 1, []), ('Za', 1, []), ('Zbasic', 1, []), ('Zdocument', 7, []), ('Zis', 1, []), ('Ztest', 6, []), ('Zthis', 1, []), ('a', 1, [17]), ('basic', 1, [18]), ('document', 7, [2, 15, 20]), ('is', 1, [16]), ('test', 6, [1, 19]), ('this', 1, [14])]
>>> [(value.num, value.value) for value in xdoc.values()]
[(0, 'Test document')]
>>> ','.join(iconn.iterids())
''
>>> iconn.add(pdoc)
'0'
>>> sconn1 = SearchConnection('foo')
>>> ','.join(iconn.iterids())
'0'
Regression test: if we called add with a ProcessedDocument which didn't have a
unique ID, the generated ID used to get assigned to the ProcessedDocument.
This shouldn't happen.
>>> print pdoc.id
None
>>> iconn.add(pdoc)
'1'
>>> pdoc.id = 'B'
>>> iconn.add(pdoc)
'B'
>>> iconn.get_doccount()
3
Add some more documents:
>>> doc = UnprocessedDocument(fields=(Field('author', 'Charlie Hull'),
... Field('category', 'Silly Document'),
... Field('text', 'Charlie is a juggler'),
... Field('other', 'Some other content.'),
... ))
>>> iconn.add(doc)
'2'
>>> doc = UnprocessedDocument(fields=(Field('author', 'Charlie Hull'),
... Field('category', 'Juggling'),
... Field('text', '5 clubs is quite hard.'),
... ))
>>> iconn.add(doc)
'3'
>>> doc = UnprocessedDocument(fields=(Field('author', 'Charlie Hull'),
... Field('category', 'Juggling'),
... Field('text', 'Good toilets are important at juggling festivals'),
... ))
>>> iconn.add(doc)
'4'
>>> iconn.get_doccount()
6
Now, try searching it:
There's nothing in the database, because the changes haven't been flushed.
>>> sconn1.get_doccount()
0
The iconn can access the same documents before and after a flush:
>>> ','.join(iconn.iterids())
'0,1,2,3,4,B'
>>> iconn.flush()
>>> ','.join(iconn.iterids())
'0,1,2,3,4,B'
The open connection still accesses the same revision, so there are still no
documents visible:
>>> sconn1.get_doccount()
0
A new connection can see the documents, though:
>>> sconn2 = SearchConnection('foo')
>>> sconn2.get_doccount()
6
>>> doc = UnprocessedDocument(fields=(Field('author', 'Richard Boulton'),
... Field('category', 'Gardening'),
... Field('text', 'Clematis grows very fast, and may smother other plants'),
... ))
>>> iconn.add(doc)
'5'
>>> iconn.get_doccount()
7
The current search connection can't see the new document:
>>> sconn2.get_doccount()
6
After a flush, the old connections still can't see the new document:
>>> iconn.flush()
>>> sconn1.get_doccount()
0
>>> sconn2.get_doccount()
6
A new connection can see the new document:
>>> sconn3 = SearchConnection('foo')
>>> sconn3.get_doccount()
7
Let's try deleting a document:
>>> iconn.delete('5')
>>> iconn.get_doccount()
6
After a flush, a new connection can see the change:
>>> iconn.flush()
>>> sconn4 = SearchConnection('foo')
>>> sconn1.get_doccount()
0
>>> sconn2.get_doccount()
6
>>> sconn3.get_doccount()
7
>>> sconn4.get_doccount()
6
If we reopen the connection, we can see the latest changes:
>>> sconn1.reopen()
>>> sconn1.get_doccount()
6
We can parse some
>>> str(sconn4.query_parse('test'))
'Xapian::Query((Ztest:(pos=1) AND_MAYBE test:(pos=1)))'
>>> str(sconn4.query_parse('title:test'))
'Xapian::Query((ZXAtest:(pos=1) AND_MAYBE XAtest:(pos=1)))'
>>> str(sconn4.query_parse('title:Test'))
'Xapian::Query((XAtest:(pos=1) AND_MAYBE XAtest:(pos=1)))'
Xapian needs a patch to support exact prefixes. When this is applied, the
following test will pass.
>> str(sconn4.query_parse('title:Test category:Te/st'))
'Xapian::Query((XAtest:(pos=1) AND XB:Te/st:(pos=2)))'
For now, the output is approximately right, and good enough to be going on
with:
>>> str(sconn4.query_parse('title:Test category:Te/st'))
'Xapian::Query(((XAtest:(pos=1) AND (XBte:(pos=2) PHRASE 2 XBst:(pos=3))) AND_MAYBE (XAtest:(pos=1) AND (XBte:(pos=2) PHRASE 2 XBst:(pos=3)))))'
>>> q1 = sconn4.query_parse('text:(clematis)')
>>> q2 = sconn4.query_parse('title:Test')
>>> str(sconn4.query_filter(q1, q2))
'Xapian::Query(((ZXCclemati:(pos=1) AND_MAYBE XCclematis:(pos=1)) FILTER (XAtest:(pos=1) AND_MAYBE XAtest:(pos=1))))'
>>> str(sconn4.query_filter(q1, "filter"))
Traceback (most recent call last):
...
SearchError: Filter must be a Xapian Query object
If we only allow a limited set of fields, other field specifications will be
considered as plain text:
>>> str(sconn4.query_parse("text:clematis title:Test"))
'Xapian::Query(((ZXCclemati:(pos=1) AND XAtest:(pos=2)) AND_MAYBE (XCclematis:(pos=1) AND XAtest:(pos=2))))'
>>> str(sconn4.query_parse("text:clematis title:Test", allow=("text",)))
'Xapian::Query(((ZXCclemati:(pos=1) AND (title:(pos=2) PHRASE 2 test:(pos=3))) AND_MAYBE (XCclematis:(pos=1) AND (title:(pos=2) PHRASE 2 test:(pos=3)))))'
>>> str(sconn4.query_parse("text:clematis title:Test", deny=("title",)))
'Xapian::Query(((ZXCclemati:(pos=1) AND (title:(pos=2) PHRASE 2 test:(pos=3))) AND_MAYBE (XCclematis:(pos=1) AND (title:(pos=2) PHRASE 2 test:(pos=3)))))'
>>> str(sconn4.query_parse("text:clematis title:Test", allow=("text",), deny=("title",)))
Traceback (most recent call last):
...
SearchError: Cannot specify both `allow` and `deny` (got ('text',) and ('title',))
We can parse queries which don't specify a field explicitly, too:
>>> str(sconn4.query_parse("clematis Test"))
'Xapian::Query(((Zclemati:(pos=1) AND test:(pos=2)) AND_MAYBE (clematis:(pos=1) AND test:(pos=2))))'
We can generate a query for an individual field:
>>> str(sconn4.query_field('text', "clematis Test"))
'Xapian::Query(((ZXCclemati:(pos=1) AND XCtest:(pos=2)) AND_MAYBE (XCclematis:(pos=1) AND XCtest:(pos=2))))'
If we generate a query for a field with no language set, it won't be stemmed:
>>> str(sconn4.query_field('other', "clematis Test"))
'Xapian::Query(((XDclematis:(pos=1) AND XDtest:(pos=2)) AND_MAYBE (XDclematis:(pos=1) AND XDtest:(pos=2))))'
If the field is an exact text field, the query will contain a single term:
>>> str(sconn4.query_field('category', "Clematis Test"))
'Xapian::Query(XB:Clematis Test)'
If the field isn't known, we get an empty query:
>>> q2 = sconn4.query_field('unknown', "clematis Test")
>>> str(q2)
'Xapian::Query()'
If we filter a query with an empty query, we get another empty query:
>>> str(sconn4.query_filter(q1, q2))
'Xapian::Query()'
>>> q = sconn4.query_parse('title:Test')
>>> str(q)
'Xapian::Query((XAtest:(pos=1) AND_MAYBE XAtest:(pos=1)))'
>>> res = sconn4.search(q, 0, 10)
>>> res.matches_lower_bound
3
>>> res.matches_upper_bound
3
>>> res.matches_estimated
3
>>> res.estimate_is_exact
True
>>> res.more_matches
False
>>> str(res)
''
If we ask for fewer results, we get them:
>>> res = sconn4.search(q, 0, 2)
>>> str(res)
''
>>> res = sconn4.search(q, 0, 3)
>>> str(res)
''
Multiword queries use AND to combine terms, by default:
>>> q1 = sconn4.query_parse('text:(important plants)')
>>> str(q1)
'Xapian::Query(((ZXCimport:(pos=1) AND ZXCplant:(pos=2)) AND_MAYBE (XCimportant:(pos=1) AND XCplants:(pos=2))))'
But we can set the default operator to OR if we want:
>>> q1 = sconn4.query_parse('text:(important plants)', default_op=sconn4.OP_OR)
>>> str(q1)
'Xapian::Query(((ZXCimport:(pos=1) OR ZXCplant:(pos=2)) AND_MAYBE (XCimportant:(pos=1) OR XCplants:(pos=2))))'
We can combine queries:
>>> q2 = sconn4.query_parse('title:test')
>>> q = sconn4.query_composite(sconn4.OP_OR, (q1, q2))
>>> str(q)
'Xapian::Query((((ZXCimport:(pos=1) OR ZXCplant:(pos=2)) AND_MAYBE (XCimportant:(pos=1) OR XCplants:(pos=2))) OR (ZXAtest:(pos=1) AND_MAYBE XAtest:(pos=1))))'
>>> doc = UnprocessedDocument(fields=(Field('author', 'Richard Boulton'),
... Field('category', 'Gardening'),
... Field('text', 'Clematis grows very fast, and may smother other plants'),
... ))
>>> for i in xrange(100):
... id = iconn.add(doc)
>>> iconn.flush()
>>> sconn1.reopen()
>>> sconn2.reopen()
>>> sconn1.search(q, 0, 3)
We can perform the same search again after more modifications have been made,
and we get the same result:
>>> for i in xrange(100):
... id = iconn.add(doc)
>>> iconn.flush()
>>> results1 = sconn1.search(q, 0, 3)
>>> results1
But if further modifications have been made, the searcher has to be reopened,
so a different result set is returned.
>>> for i in xrange(100):
... id = iconn.add(doc)
>>> iconn.flush()
>>> results2 = sconn1.search(q, 0, 50)
>>> results2
We can get the details of the hit at a given rank:
>>> hit = results1.get_hit(2)
>>> hit.rank
2
>>> hit.id
'B'
>>> hit.data
{'title': ['Test document 1'], 'author': ['Richard Boulton']}
>>> str(hit)
""
>>> str(results2.get_hit(2))
""
>>> str(results2.get_hit(49))
""
We can change a document in the index, and the old result is still available:
>>> newdoc = UnprocessedDocument(fields=(Field('author', 'Fred Bloggs'),
... Field('category', 'Sleeping'),
... Field('text', 'This is different text to before'),),
... id=results2.get_hit(49).id)
>>> iconn.replace(newdoc)
(If we don't set an ID, we get an error.
>>> newdoc = UnprocessedDocument(fields=(Field('author', 'Freda Bloggs'),
... Field('category', 'Sleeping'),
... Field('text', 'This is different text to before'),))
>>> iconn.replace(newdoc)
Traceback (most recent call last):
...
IndexerError: No document ID set for document supplied to replace().
>>> iconn.flush()
>>> str(results2.get_hit(49))
""
But on a newly reopened connection, the result is gone (note the different id):
>>> sconn2.reopen()
>>> results3 = sconn2.search(q, 0, 50)
>>> str(results3.get_hit(49))
""
We can get a list of the current document IDs
>>> print [id for id in iconn.iterids()][:10]
['0', '1', '10', '100', '101', '102', '103', '104', '105', '106']
>>> pdoc = iconn.get_document('0')
>>> print pdoc.data
{'title': ['Test document 1'], 'author': ['Richard Boulton']}
If we perform major changes on the database, the results of a search might
become unavailable:
>>> sconn1.reopen()
>>> results4 = sconn1.search(q, 0, 100)
>>> for id in iconn.iterids():
... iconn.delete(id)
>>> iconn.get_doccount()
0
>>> iconn.flush()
>>> iconn.get_doccount()
0
>>> for i in xrange(100):
... id = iconn.add(doc)
>>> iconn.flush()
>>> for i in xrange(100):
... id = iconn.add(doc)
>>> iconn.flush()
>>> for hit in results4: pass
Traceback (most recent call last):
...
DatabaseModifiedError: The revision being read has been discarded - you should call Xapian::Database::reopen() and retry the operation
When we're finished with the connection, we can close it to release the
resources:
>>> sconn1.close()
Repeated closing is okay:
>>> sconn1.close()
After closing, no other methods should be called:
>>> sconn1.reopen()
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.get_doccount()
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_composite(sconn1.OP_AND, 'foo')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_filter(q, q)
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_range('date', '19991212', '20000101')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_parse('hello')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_field('author', 'richard')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.query_facet('author', 'richard')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.search(q, 0, 10)
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
>>> sconn1.get_document('1')
Traceback (most recent call last):
...
SearchError: SearchConnection has been closed
But calling close() multiple times is okay:
>>> sconn1.close()
xappy-0.5/xappy/indexerconnection_doctest3.txt 0000644 0001750 0001750 00000011627 10667526666 021614 0 ustar richard richard
>>> from datastructures import *
>>> from fieldactions import *
>>> from searchconnection import *
Open a connection for indexing:
>>> iconn = IndexerConnection('foo')
We have to wipe out any old actions on the field to change the actions:
>>> iconn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=5, language='en', nopos=True)
>>> iconn.add_field_action('category', FieldActions.INDEX_EXACT)
>>> iconn.add_field_action('category', FieldActions.SORTABLE)
>>> iconn.add_field_action('category', FieldActions.COLLAPSE)
>>> iconn.add_field_action('text', FieldActions.INDEX_FREETEXT, language='en')
>>> iconn.add_field_action('other', FieldActions.INDEX_FREETEXT)
>>> iconn.add_field_action('date', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('date', FieldActions.SORTABLE, type='date')
>>> iconn.add_field_action('date', FieldActions.COLLAPSE)
>>> iconn.add_field_action('price', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('price', FieldActions.SORTABLE, type='float')
>>> iconn.add_field_action('price', FieldActions.COLLAPSE)
Build up a document:
>>> doc = UnprocessedDocument()
>>> doc.fields.append(Field('author', 'Richard Boulton'))
>>> doc.fields.append(Field('category', 'Test document'))
>>> doc.fields.append(Field('title', 'Test document 1'))
>>> doc.fields.append(Field('text', 'This document is a basic test document.'))
Process it:
>>> pdoc = iconn.process(doc)
>>> pdoc.data
{'title': ['Test document 1'], 'author': ['Richard Boulton']}
If we add a field which is specified as a SORTABLE date which doesn't contain
a valid date, an error will be raised when we try to process the date:
>>> doc.fields.append(Field('date', 'An invalid date - this will generate an error when processed.'))
>>> iconn.process(doc)
Traceback (most recent call last):
...
IndexerError: Value supplied to field 'date' must be a valid date: was 'An invalid date - this will generate an error when processed.': error is 'Unrecognised date format'
If we add a field which is specified as a SORTABLE float which doesn't contain
a valid floating point number, an error will be raised when we try to process
the number:
>>> doc.fields[-1] = Field('price', 'An invalid float - this will generate an error when processed.')
>>> iconn.process(doc)
Traceback (most recent call last):
...
IndexerError: Value supplied to field 'price' must be a valid floating point number: was 'An invalid float - this will generate an error when processed.'
We can access the Xapian document representation of the processed document to
double check that this document has been indexed as we wanted:
>>> xdoc = pdoc.prepare()
>>> import cPickle
>>> cPickle.loads(xdoc.get_data()) == pdoc.data
True
>>> [(term.term, term.wdf, [pos for pos in term.positer]) for term in xdoc.termlist()]
[('1', 5, []), ('XA1', 5, []), ('XAdocument', 5, []), ('XAtest', 5, []), ('XB:Test document', 0, []), ('XCa', 1, [14]), ('XCbasic', 1, [15]), ('XCdocument', 2, [12, 17]), ('XCis', 1, [13]), ('XCtest', 1, [16]), ('XCthis', 1, [11]), ('ZXAdocument', 5, []), ('ZXAtest', 5, []), ('ZXCa', 1, []), ('ZXCbasic', 1, []), ('ZXCdocument', 2, []), ('ZXCis', 1, []), ('ZXCtest', 1, []), ('ZXCthis', 1, []), ('Za', 1, []), ('Zbasic', 1, []), ('Zdocument', 7, []), ('Zis', 1, []), ('Ztest', 6, []), ('Zthis', 1, []), ('a', 1, [14]), ('basic', 1, [15]), ('document', 7, [12, 17]), ('is', 1, [13]), ('test', 6, [16]), ('this', 1, [11])]
>>> [(value.num, value.value) for value in xdoc.values()]
[(0, 'Test document')]
We can add terms directly to the processed document, specifying the wdf and position:
>>> pdoc.add_term('text', 'newterm1', wdfinc=17, positions=200)
>>> pdoc.add_term('text', 'newterm2', wdfinc=17, positions=(201, 202))
>>> [(term.term, term.wdf, [pos for pos in term.positer]) for term in xdoc.termlist()]
[('1', 5, []), ('XA1', 5, []), ('XAdocument', 5, []), ('XAtest', 5, []), ('XB:Test document', 0, []), ('XCa', 1, [14]), ('XCbasic', 1, [15]), ('XCdocument', 2, [12, 17]), ('XCis', 1, [13]), ('XCnewterm1', 17, [200]), ('XCnewterm2', 17, [201, 202]), ('XCtest', 1, [16]), ('XCthis', 1, [11]), ('ZXAdocument', 5, []), ('ZXAtest', 5, []), ('ZXCa', 1, []), ('ZXCbasic', 1, []), ('ZXCdocument', 2, []), ('ZXCis', 1, []), ('ZXCtest', 1, []), ('ZXCthis', 1, []), ('Za', 1, []), ('Zbasic', 1, []), ('Zdocument', 7, []), ('Zis', 1, []), ('Ztest', 6, []), ('Zthis', 1, []), ('a', 1, [14]), ('basic', 1, [15]), ('document', 7, [12, 17]), ('is', 1, [13]), ('test', 6, [16]), ('this', 1, [11])]
We can set the data directly too, as long as we set it to a dictionary:
>>> pdoc.data = {'Empty': 'nothing'}
>>> pdoc.data
{'Empty': 'nothing'}
>>> pdoc.data = None
Traceback (most recent call last):
...
TypeError: Cannot set data to any type other than a dict
We can also get a representation of a processed document (though it only tells us the ID number):
>>> pdoc
xappy-0.5/xappy/marshall.py 0000644 0001750 0001750 00000002375 10720056673 015664 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""marshall.py: Marshal values into strings
"""
__docformat__ = "restructuredtext en"
import math
import xapian
from replaylog import log as _log
def float_to_string(value):
"""Marshall a floating point number to a string which sorts in the
appropriate manner.
"""
return _log(xapian.sortable_serialise, value)
def date_to_string(date):
"""Marshall a date to a string which sorts in the appropriate manner.
"""
return '%04d%02d%02d' % (date.year, date.month, date.day)
xappy-0.5/xappy/marshall_doctest1.txt 0000644 0001750 0001750 00000002053 10667526666 017670 0 ustar richard richard
>>> float_to_string(0)
'\x80'
>>> float_to_string(-0)
'\x80'
>>> float_to_string(2 ** -1023)
'\x8f\xe4'
>>> float_to_string(2 ** -1024)
'\x8f\xe0'
>>> float_to_string(2 ** -1074)
'\x8f\x18'
>>> float_to_string(2 ** -1075)
'\x80'
>>> float_to_string(-(2 ** -1024))
'p\x1e'
>>> float_to_string(-(2 ** -1023))
'p\x1a'
>>> float_to_string(-(2 ** -1074))
'p\xe6'
>>> float_to_string(-(2 ** -1075))
'\x80'
Check that the values in test_vals sort in the right order. And then test with their negations.
>>> pos_test_vals = (0, 2 ** -1075, 2 ** -1074, 2 ** -1023, 0.000001, 0.000002, 0.000005, 0.1, 0.2, 0.5, 1, 1.1, 1.8, 2, 1024.5, 2 ** 1022)
>>> test_vals = [-val for val in pos_test_vals]
>>> test_vals.reverse()
>>> test_vals.extend(pos_test_vals)
>>> prev_val = test_vals[0]
>>> for val in test_vals:
... m_prev_val = float_to_string(prev_val)
... m_val = float_to_string(val)
... if val == prev_val:
... assert(m_val == m_prev_val)
... else:
... assert(val > prev_val)
... assert(m_val > m_prev_val)
... prev_val = val
xappy-0.5/xappy/marshall_doctest2.txt 0000644 0001750 0001750 00000001124 10667526666 017667 0 ustar richard richard
>>> import datetime, parsedate
>>> date_to_string(datetime.date(1999, 12, 13))
'19991213'
>>> test_date_inputs=['1066.11.05', '19700211', '19991213', '20070513']
>>> test_dates = []
>>> for date in test_date_inputs:
... test_dates.append(parsedate.date_from_string(date))
>>> prev_val = test_dates[0]
>>> for val in test_dates:
... m_prev_val = date_to_string(prev_val)
... m_val = date_to_string(val)
... if val == prev_val:
... assert(m_val == m_prev_val)
... else:
... assert(val > prev_val)
... assert(m_val > m_prev_val)
... prev_val = val
xappy-0.5/xappy/memutils.py 0000644 0001750 0001750 00000005216 10711360156 015707 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""memutils.py: Memory handling utilities.
"""
__docformat__ = "restructuredtext en"
import os
def _get_physical_mem_sysconf():
"""Try getting a value for the physical memory using os.sysconf().
Returns None if no value can be obtained - otherwise, returns a value in
bytes.
"""
if getattr(os, 'sysconf', None) is None:
return None
try:
pagesize = os.sysconf('SC_PAGESIZE')
except ValueError:
try:
pagesize = os.sysconf('SC_PAGE_SIZE')
except ValueError:
return None
try:
pagecount = os.sysconf('SC_PHYS_PAGES')
except ValueError:
return None
return pagesize * pagecount
def _get_physical_mem_win32():
"""Try getting a value for the physical memory using GlobalMemoryStatus.
This is a windows specific method. Returns None if no value can be
obtained (eg, not running on windows) - otherwise, returns a value in
bytes.
"""
try:
import ctypes
import ctypes.wintypes as wintypes
except ValueError:
return None
class MEMORYSTATUS(wintypes.Structure):
_fields_ = [
('dwLength', wintypes.DWORD),
('dwMemoryLoad', wintypes.DWORD),
('dwTotalPhys', wintypes.DWORD),
('dwAvailPhys', wintypes.DWORD),
('dwTotalPageFile', wintypes.DWORD),
('dwAvailPageFile', wintypes.DWORD),
('dwTotalVirtual', wintypes.DWORD),
('dwAvailVirtual', wintypes.DWORD),
]
m = MEMORYSTATUS()
wintypes.windll.kernel32.GlobalMemoryStatus(wintypes.byref(m))
return m.dwTotalPhys
def get_physical_memory():
"""Get the amount of physical memory in the system, in bytes.
If this can't be obtained, returns None.
"""
result = _get_physical_mem_sysconf()
if result is not None:
return result
return _get_physical_mem_win32()
xappy-0.5/xappy/parsedate.py 0000644 0001750 0001750 00000003415 10667526666 016043 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""parsedate.py: Parse date strings.
"""
__docformat__ = "restructuredtext en"
import datetime
import re
yyyymmdd_re = re.compile(r'(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{2})$')
yyyy_mm_dd_re = re.compile(r'(?P[0-9]{4})([-/.])(?P[0-9]{2})\2(?P[0-9]{2})$')
def date_from_string(value):
"""Parse a string into a date.
If the value supplied is already a date-like object (ie, has 'year',
'month' and 'day' attributes), it is returned without processing.
Supported date formats are:
- YYYYMMDD
- YYYY-MM-DD
- YYYY/MM/DD
- YYYY.MM.DD
"""
if (hasattr(value, 'year')
and hasattr(value, 'month')
and hasattr(value, 'day')):
return value
mg = yyyymmdd_re.match(value)
if mg is None:
mg = yyyy_mm_dd_re.match(value)
if mg is not None:
year, month, day = (int(i) for i in mg.group('year', 'month', 'day'))
return datetime.date(year, month, day)
raise ValueError('Unrecognised date format')
xappy-0.5/xappy/parsedate_doctest1.txt 0000644 0001750 0001750 00000002232 10667526666 020034 0 ustar richard richard General tests of the datetime module.
Dates may be supplied as YYYYMMDD:
>>> date_from_string('19990201')
datetime.date(1999, 2, 1)
>>> date_from_string('19690201')
datetime.date(1969, 2, 1)
>>> date_from_string('20000228')
datetime.date(2000, 2, 28)
>>> date_from_string('20000229')
datetime.date(2000, 2, 29)
Dates may also be supplied as YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD:
>>> date_from_string('1999-02-01')
datetime.date(1999, 2, 1)
>>> date_from_string('1999/02/01')
datetime.date(1999, 2, 1)
>>> date_from_string('1999.02.01')
datetime.date(1999, 2, 1)
Out of range dates cause a ValueError:
>>> date_from_string('19000229')
Traceback (most recent call last):
...
ValueError: day is out of range for month
>>> date_from_string('20000001')
Traceback (most recent call last):
...
ValueError: month must be in 1..12
If we pass a datetime.date object (or something which looks similar) it is
returned unchanged:
>>> date_from_string(datetime.date(2001, 7, 11))
datetime.date(2001, 7, 11)
If we pass something unrecognisible, we get a ValueError:
>>> date_from_string('hello world')
Traceback (most recent call last):
...
ValueError: Unrecognised date format
xappy-0.5/xappy/replaylog.py 0000644 0001750 0001750 00000031216 10720056673 016053 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""replaylog.py: Log all xapian calls to a file, so that they can be replayed.
"""
__docformat__ = "restructuredtext en"
import datetime
import sys
import thread
import threading
import time
import traceback
import types
import weakref
import xapian
from pprint import pprint
# The logger in use.
_replay_log = None
# True if a replay log has ever been in use since import time.
_had_replay_log = False
class NotifyingDeleteObject(object):
"""An wrapping for an object which calls a callback when its deleted.
Note that the callback will be called from a __del__ method, so shouldn't
raise any exceptions, and probably shouldn't make new references to the
object supplied to it.
"""
def __init__(self, obj, callback):
self.obj = obj
self.callback = callback
def __del__(self):
self.callback(self.obj)
class ReplayLog(object):
"""Log of xapian calls, to be replayed.
"""
def __init__(self, logpath):
"""Create a new replay log.
"""
# Mutex used to protect all access to _fd
self._fd_mutex = threading.Lock()
self._fd = file(logpath, 'wb')
# Mutex used to protect all access to members other than _fd
self._mutex = threading.Lock()
self._next_call = 1
self._next_thread = 0
self._thread_ids = {}
self._objs = weakref.WeakKeyDictionary()
self._next_num = 1
self._xapian_classes = {}
self._xapian_functions = {}
self._xapian_methods = {}
for name in dir(xapian):
item = getattr(xapian, name)
has_members = False
for membername in dir(item):
member = getattr(item, membername)
if isinstance(member, types.MethodType):
self._xapian_methods[member.im_func] = (name, membername)
has_members = True
if has_members:
self._xapian_classes[item] = name
if isinstance(item, types.BuiltinFunctionType):
self._xapian_functions[item] = name
def _get_obj_num(self, obj, maybe_new):
"""Get the number associated with an object.
If maybe_new is False, a value of 0 will be supplied if the object
hasn't already been seen. Otherwise, a new (and previously unused)
value will be allocated to the object.
The mutex should be held when this is called.
"""
try:
num = self._objs[obj]
return num.obj
except KeyError:
pass
if not maybe_new:
return 0
self._objs[obj] = NotifyingDeleteObject(self._next_num, self._obj_gone)
self._next_num += 1
return self._next_num - 1
def _is_xap_obj(self, obj):
"""Return True iff an object is an instance of a xapian object.
(Also returns true if the object is an instance of a subclass of a
xapian object.)
The mutex should be held when this is called.
"""
# Check for xapian classes.
classname = self._xapian_classes.get(type(obj), None)
if classname is not None:
return True
# Check for subclasses of xapian classes.
for classobj, classname in self._xapian_classes.iteritems():
if isinstance(obj, classobj):
return True
# Not a xapian class or subclass.
return False
def _get_xap_name(self, obj, maybe_new=False):
"""Get the name of a xapian class or method.
The mutex should be held when this is called.
"""
# Check if it's a xapian class, or subclass.
if isinstance(obj, types.TypeType):
classname = self._xapian_classes.get(obj, None)
if classname is not None:
return classname
for classobj, classname in self._xapian_classes.iteritems():
if issubclass(obj, classobj):
return "subclassof_%s" % (classname, )
return None
# Check if it's a xapian function.
if isinstance(obj, types.BuiltinFunctionType):
funcname = self._xapian_functions.get(obj, None)
if funcname is not None:
return funcname
# Check if it's a proxied object.
if isinstance(obj, LoggedProxy):
classname = self._xapian_classes.get(obj.__class__, None)
if classname is not None:
objnum = self._get_obj_num(obj, maybe_new=maybe_new)
return "%s#%d" % (classname, objnum)
# Check if it's a proxied method.
if isinstance(obj, LoggedProxyMethod):
classname, methodname = self._xapian_methods[obj.real.im_func]
objnum = self._get_obj_num(obj.proxyobj, maybe_new=maybe_new)
return "%s#%d.%s" % (classname, objnum, methodname)
# Check if it's a subclass of a xapian class. Note: this will only
# pick up subclasses, because the original classes are filtered out
# higher up.
for classobj, classname in self._xapian_classes.iteritems():
if isinstance(obj, classobj):
objnum = self._get_obj_num(obj, maybe_new=maybe_new)
return "subclassof_%s#%d" % (classname, objnum)
return None
def _log(self, msg):
self._fd_mutex.acquire()
try:
# msg = '%s,%s' % (
# datetime.datetime.fromtimestamp(time.time()).isoformat(),
# msg,
# )
self._fd.write(msg)
self._fd.flush()
finally:
self._fd_mutex.release()
def _repr_arg(self, arg):
"""Return a representation of an argument.
The mutex should be held when this is called.
"""
xapargname = self._get_xap_name(arg)
if xapargname is not None:
return xapargname
if isinstance(arg, basestring):
if isinstance(arg, unicode):
arg = arg.encode('utf-8')
return 'str(%d,%s)' % (len(arg), arg)
if isinstance(arg, long):
try:
arg = int(arg)
except OverFlowError:
pass
if isinstance(arg, long):
return 'long(%d)' % arg
if isinstance(arg, int):
return 'int(%d)' % arg
if isinstance(arg, float):
return 'float(%f)' % arg
if arg is None:
return 'None'
if hasattr(arg, '__iter__'):
seq = []
for item in arg:
seq.append(self._repr_arg(item))
return 'list(%s)' % ','.join(seq)
return 'UNKNOWN:' + str(arg)
def _repr_args(self, args):
"""Return a representation of a list of arguments.
The mutex should be held when this is called.
"""
logargs = []
for arg in args:
logargs.append(self._repr_arg(arg))
return ','.join(logargs)
def _get_call_id(self):
"""Get an ID string for a call.
The mutex should be held when this is called.
"""
call_num = self._next_call
self._next_call += 1
thread_id = thread.get_ident()
try:
thread_num = self._thread_ids[thread_id]
except KeyError:
thread_num = self._next_thread
self._thread_ids[thread_id] = thread_num
self._next_thread += 1
if thread_num is 0:
return "%s" % call_num
return "%dT%d" % (call_num, thread_num)
def log_call(self, call, *args):
"""Add a log message about a call.
Returns a number for the call, so it can be tied to a particular
result.
"""
self._mutex.acquire()
try:
logargs = self._repr_args(args)
xapobjname = self._get_xap_name(call)
call_id = self._get_call_id()
finally:
self._mutex.release()
if xapobjname is not None:
self._log("CALL%s:%s(%s)\n" % (call_id, xapobjname, logargs))
else:
self._log("CALL%s:UNKNOWN:%r(%s)\n" % (call_id, call, logargs))
return call_id
def log_except(self, (etype, value, tb), call_id):
"""Log an exception which has occurred.
"""
# No access to an members, so no need to acquire mutex.
exc = traceback.format_exception_only(etype, value)
self._log("EXCEPT%s:%s\n" % (call_id, ''.join(exc).strip()))
def log_retval(self, ret, call_id):
"""Log a return value.
"""
if ret is None:
self._log("RET%s:None\n" % call_id)
return
self._mutex.acquire()
try:
# If it's a xapian object, return a proxy for it.
if self._is_xap_obj(ret):
ret = LoggedProxy(ret)
xapobjname = self._get_xap_name(ret, maybe_new=True)
msg = "RET%s:%s\n" % (call_id, self._repr_arg(ret))
finally:
self._mutex.release()
# Not a xapian object - just return it.
self._log(msg)
return ret
def _obj_gone(self, num):
"""Log that an object has been deleted.
"""
self._log('DEL:#%d\n' % num)
class LoggedProxy(object):
"""A proxy for a xapian object, which logs all calls made on the object.
"""
def __init__(self, obj):
self.__obj = obj
def __getattribute__(self, name):
obj = object.__getattribute__(self, '_LoggedProxy__obj')
if name == '__obj':
return obj
real = getattr(obj, name)
if not isinstance(real, types.MethodType):
return real
return LoggedProxyMethod(real, self)
def __iter__(self):
obj = object.__getattribute__(self, '_LoggedProxy__obj')
return obj.__iter__()
def __len__(self):
obj = object.__getattribute__(self, '_LoggedProxy__obj')
return obj.__len__()
def __repr__(self):
obj = object.__getattribute__(self, '_LoggedProxy__obj')
return '' % obj.__repr__()
def __str__(self):
obj = object.__getattribute__(self, '_LoggedProxy__obj')
return obj.__str__()
class LoggedProxyMethod(object):
"""A proxy for a xapian method, which logs all calls made on the method.
"""
def __init__(self, real, proxyobj):
"""Make a proxy for the method.
"""
self.real = real
self.proxyobj = proxyobj
def __call__(self, *args):
"""Call the proxied method, logging the call.
"""
return log(self, *args)
def set_replay_path(logpath):
"""Set the path for the replay log.
"""
global _replay_log
global _had_replay_log
if logpath is None:
_replay_log = None
else:
_had_replay_log = True
_replay_log = ReplayLog(logpath)
def _unproxy_call_and_args(call, args):
"""Convert a call and list of arguments to unproxied form.
"""
if isinstance(call, LoggedProxyMethod):
realcall = call.real
else:
realcall = call
realargs = []
for arg in args:
if isinstance(arg, LoggedProxy):
arg = arg.__obj
realargs.append(arg)
return realcall, realargs
def log(call, *args):
"""Make a call to xapian, and log it.
"""
# If we've never had a replay log in force, no need to unproxy objects.
global _had_replay_log
if not _had_replay_log:
return call(*args)
# Get unproxied versions of the call and arguments.
realcall, realargs = _unproxy_call_and_args(call, args)
# If we have no replay log currently, just do the call.
global _replay_log
replay_log = _replay_log
if replay_log is None:
return realcall(*realargs)
# We have a replay log: do a logged version of the call.
call_id = replay_log.log_call(call, *args)
try:
ret = realcall(*realargs)
except:
replay_log.log_except(sys.exc_info(), call_id)
raise
return replay_log.log_retval(ret, call_id)
#set_replay_path('replay.log')
xappy-0.5/xappy/schema.py 0000644 0001750 0001750 00000002151 10772230325 015304 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2008 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""schema.py: xdefinitions and implementations of field actions.
"""
__docformat__ = "restructuredtext en"
import errors as _errors
from replaylog import log as _log
import parsedate as _parsedate
class Schema(object):
def __init__(self):
pass
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/searchconnection.py 0000644 0001750 0001750 00000227407 11005457603 017406 0 ustar richard richard #!/usr/bin/env python
#
# Copyright (C) 2007 Lemur Consulting Ltd
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
r"""searchconnection.py: A connection to the search engine for searching.
"""
__docformat__ = "restructuredtext en"
import _checkxapian
import os as _os
import cPickle as _cPickle
import math
import xapian as _xapian
from datastructures import *
from fieldactions import *
import fieldmappings as _fieldmappings
import highlight as _highlight
import errors as _errors
import indexerconnection as _indexerconnection
import re as _re
from replaylog import log as _log
class SearchResult(ProcessedDocument):
"""A result from a search.
As well as being a ProcessedDocument representing the document in the
database, the result has several members which may be used to get
information about how well the document matches the search:
- `rank`: The rank of the document in the search results, starting at 0
(ie, 0 is the "top" result, 1 is the second result, etc).
- `weight`: A floating point number indicating the weight of the result
document. The value is only meaningful relative to other results for a
given search - a different search, or the same search with a different
database, may give an entirely different scale to the weights. This
should not usually be displayed to users, but may be useful if trying to
perform advanced reweighting operations on search results.
- `percent`: A percentage value for the weight of a document. This is
just a rescaled form of the `weight` member. It doesn't represent any
kind of probability value; the only real meaning of the numbers is that,
within a single set of results, a document with a higher percentage
corresponds to a better match. Because the percentage doesn't really
represent a probability, or a confidence value, it is probably unhelpful
to display it to most users, since they tend to place an over emphasis
on its meaning. However, it is included because it may be useful
occasionally.
"""
def __init__(self, msetitem, results):
ProcessedDocument.__init__(self, results._fieldmappings, msetitem.document)
self.rank = msetitem.rank
self.weight = msetitem.weight
self.percent = msetitem.percent
self._results = results
def _get_language(self, field):
"""Get the language that should be used for a given field.
Raises a KeyError if the field is not known.
"""
actions = self._results._conn._field_actions[field]._actions
for action, kwargslist in actions.iteritems():
if action == FieldActions.INDEX_FREETEXT:
for kwargs in kwargslist:
try:
return kwargs['language']
except KeyError:
pass
return 'none'
def summarise(self, field, maxlen=600, hl=('', ' '), query=None):
"""Return a summarised version of the field specified.
This will return a summary of the contents of the field stored in the
search result, with words which match the query highlighted.
The maximum length of the summary (in characters) may be set using the
maxlen parameter.
The return value will be a string holding the summary, with
highlighting applied. If there are multiple instances of the field in
the document, the instances will be joined with a newline character.
To turn off highlighting, set hl to None. Each highlight will consist
of the first entry in the `hl` list being placed before the word, and
the second entry in the `hl` list being placed after the word.
Any XML or HTML style markup tags in the field will be stripped before
the summarisation algorithm is applied.
If `query` is supplied, it should contain a Query object, as returned
from SearchConnection.query_parse() or related methods, which will be
used as the basis of the summarisation and highlighting rather than the
query which was used for the search.
Raises KeyError if the field is not known.
"""
highlighter = _highlight.Highlighter(language_code=self._get_language(field))
field = self.data[field]
results = []
text = '\n'.join(field)
if query is None:
query = self._results._query
return highlighter.makeSample(text, query, maxlen, hl)
def highlight(self, field, hl=('', ' '), strip_tags=False, query=None):
"""Return a highlighted version of the field specified.
This will return all the contents of the field stored in the search
result, with words which match the query highlighted.
The return value will be a list of strings (corresponding to the list
of strings which is the raw field data).
Each highlight will consist of the first entry in the `hl` list being
placed before the word, and the second entry in the `hl` list being
placed after the word.
If `strip_tags` is True, any XML or HTML style markup tags in the field
will be stripped before highlighting is applied.
If `query` is supplied, it should contain a Query object, as returned
from SearchConnection.query_parse() or related methods, which will be
used as the basis of the summarisation and highlighting rather than the
query which was used for the search.
Raises KeyError if the field is not known.
"""
highlighter = _highlight.Highlighter(language_code=self._get_language(field))
field = self.data[field]
results = []
if query is None:
query = self._results._query
for text in field:
results.append(highlighter.highlight(text, query, hl, strip_tags))
return results
def __repr__(self):
return ('' %
(self.rank, self.id, self.data))
class SearchResultIter(object):
"""An iterator over a set of results from a search.
"""
def __init__(self, results, order):
self._results = results
self._order = order
if self._order is None:
self._iter = iter(results._mset)
else:
self._iter = iter(self._order)
def next(self):
if self._order is None:
msetitem = self._iter.next()
else:
index = self._iter.next()
msetitem = self._results._mset.get_hit(index)
return SearchResult(msetitem, self._results)
def _get_significant_digits(value, lower, upper):
"""Get the significant digits of value which are constrained by the
(inclusive) lower and upper bounds.
If there are no significant digits which are definitely within the
bounds, exactly one significant digit will be returned in the result.
>>> _get_significant_digits(15,15,15)
15
>>> _get_significant_digits(15,15,17)
20
>>> _get_significant_digits(4777,208,6000)
5000
>>> _get_significant_digits(4777,4755,4790)
4800
>>> _get_significant_digits(4707,4695,4710)
4700
>>> _get_significant_digits(4719,4717,4727)
4720
>>> _get_significant_digits(0,0,0)
0
>>> _get_significant_digits(9,9,10)
9
>>> _get_significant_digits(9,9,100)
9
"""
assert(lower <= value)
assert(value <= upper)
diff = upper - lower
# Get the first power of 10 greater than the difference.
# This corresponds to the magnitude of the smallest significant digit.
if diff == 0:
pos_pow_10 = 1
else:
pos_pow_10 = int(10 ** math.ceil(math.log10(diff)))
# Special case for situation where we don't have any significant digits:
# get the magnitude of the most significant digit in value.
if pos_pow_10 > value:
if value == 0:
pos_pow_10 = 1
else:
pos_pow_10 = int(10 ** math.floor(math.log10(value)))
# Return the value, rounded to the nearest multiple of pos_pow_10
return ((value + pos_pow_10 // 2) // pos_pow_10) * pos_pow_10
class SearchResults(object):
"""A set of results of a search.
"""
def __init__(self, conn, enq, query, mset, fieldmappings, tagspy,
tagfields, facetspy, facetfields, facethierarchy,
facetassocs):
self._conn = conn
self._enq = enq
self._query = query
self._mset = mset
self._mset_order = None
self._fieldmappings = fieldmappings
self._tagspy = tagspy
if tagfields is None:
self._tagfields = None
else:
self._tagfields = set(tagfields)
self._facetspy = facetspy
self._facetfields = facetfields
self._facethierarchy = facethierarchy
self._facetassocs = facetassocs
self._numeric_ranges_built = {}
def _cluster(self, num_clusters, maxdocs, fields=None):
"""Cluster results based on similarity.
Note: this method is experimental, and will probably disappear or
change in the future.
The number of clusters is specified by num_clusters: unless there are
too few results, there will be exaclty this number of clusters in the
result.
"""
clusterer = _xapian.ClusterSingleLink()
xapclusters = _xapian.ClusterAssignments()
docsim = _xapian.DocSimCosine()
source = _xapian.MSetDocumentSource(self._mset, maxdocs)
if fields is None:
clusterer.cluster(self._conn._index, xapclusters, docsim, source, num_clusters)
else:
decider = self._make_expand_decider(fields)
clusterer.cluster(self._conn._index, xapclusters, docsim, source, decider, num_clusters)
newid = 0
idmap = {}
clusters = {}
for item in self._mset:
docid = item.docid
clusterid = xapclusters.cluster(docid)
if clusterid not in idmap:
idmap[clusterid] = newid
newid += 1
clusterid = idmap[clusterid]
if clusterid not in clusters:
clusters[clusterid] = []
clusters[clusterid].append(item.rank)
return clusters
def _reorder_by_clusters(self, clusters):
"""Reorder the mset based on some clusters.
"""
if self.startrank != 0:
raise _errors.SearchError("startrank must be zero to reorder by clusters")
reordered = False
tophits = []
nottophits = []
clusterstarts = dict(((c[0], None) for c in clusters.itervalues()))
for i in xrange(self.endrank):
if i in clusterstarts:
tophits.append(i)
else:
nottophits.append(i)
self._mset_order = tophits
self._mset_order.extend(nottophits)
def _make_expand_decider(self, fields):
"""Make an expand decider which accepts only terms in the specified
field.
"""
prefixes = {}
if isinstance(fields, basestring):
fields = [fields]
for field in fields:
try:
actions = self._conn._field_actions[field]._actions
except KeyError:
continue
for action, kwargslist in actions.iteritems():
if action == FieldActions.INDEX_FREETEXT:
prefix = self._conn._field_mappings.get_prefix(field)
prefixes[prefix] = None
prefixes['Z' + prefix] = None
if action in (FieldActions.INDEX_EXACT,
FieldActions.TAG,
FieldActions.FACET,):
prefix = self._conn._field_mappings.get_prefix(field)
prefixes[prefix] = None
prefix_re = _re.compile('|'.join([_re.escape(x) + '[^A-Z]' for x in prefixes.keys()]))
class decider(_xapian.ExpandDecider):
def __call__(self, term):
return prefix_re.match(term) is not None
return decider()
def _reorder_by_similarity(self, count, maxcount, max_similarity,
fields=None):
"""Reorder results based on similarity.
The top `count` documents will be chosen such that they are relatively
dissimilar. `maxcount` documents will be considered for moving around,
and `max_similarity` is a value between 0 and 1 indicating the maximum
similarity to the previous document before a document is moved down the
result set.
Note: this method is experimental, and will probably disappear or
change in the future.
"""
if self.startrank != 0:
raise _errors.SearchError("startrank must be zero to reorder by similiarity")
ds = _xapian.DocSimCosine()
ds.set_termfreqsource(_xapian.DatabaseTermFreqSource(self._conn._index))
if fields is not None:
ds.set_expand_decider(self._make_expand_decider(fields))
tophits = []
nottophits = []
full = False
reordered = False
sim_count = 0
new_order = []
end = min(self.endrank, maxcount)
for i in xrange(end):
if full:
new_order.append(i)
continue
hit = self._mset.get_hit(i)
if len(tophits) == 0:
tophits.append(hit)
continue
# Compare each incoming hit to tophits
maxsim = 0.0
for tophit in tophits[-1:]:
sim_count += 1
sim = ds.similarity(hit.document, tophit.document)
if sim > maxsim:
maxsim = sim
# If it's not similar to an existing hit, add to tophits.
if maxsim < max_similarity:
tophits.append(hit)
else:
nottophits.append(hit)
reordered = True
# If we're full of hits, append to the end.
if len(tophits) >= count:
for hit in tophits:
new_order.append(hit.rank)
for hit in nottophits:
new_order.append(hit.rank)
full = True
if not full:
for hit in tophits:
new_order.append(hit.rank)
for hit in nottophits:
new_order.append(hit.rank)
if end != self.endrank:
new_order.extend(range(end, self.endrank))
assert len(new_order) == self.endrank
if reordered:
self._mset_order = new_order
else:
assert new_order == range(self.endrank)
def __repr__(self):
return ("" %
(
self.startrank,
self.endrank,
self.more_matches,
self.matches_lower_bound,
self.matches_upper_bound,
self.matches_estimated,
self.estimate_is_exact,
))
def _get_more_matches(self):
# This check relies on us having asked for at least one more result
# than retrieved to be checked.
return (self.matches_lower_bound > self.endrank)
more_matches = property(_get_more_matches, doc=
"""Check whether there are further matches after those in this result set.
""")
def _get_startrank(self):
return self._mset.get_firstitem()
startrank = property(_get_startrank, doc=
"""Get the rank of the first item in the search results.
This corresponds to the "startrank" parameter passed to the search() method.
""")
def _get_endrank(self):
return self._mset.get_firstitem() + len(self._mset)
endrank = property(_get_endrank, doc=
"""Get the rank of the item after the end of the search results.
If there are sufficient results in the index, this corresponds to the
"endrank" parameter passed to the search() method.
""")
def _get_lower_bound(self):
return self._mset.get_matches_lower_bound()
matches_lower_bound = property(_get_lower_bound, doc=
"""Get a lower bound on the total number of matching documents.
""")
def _get_upper_bound(self):
return self._mset.get_matches_upper_bound()
matches_upper_bound = property(_get_upper_bound, doc=
"""Get an upper bound on the total number of matching documents.
""")
def _get_human_readable_estimate(self):
lower = self._mset.get_matches_lower_bound()
upper = self._mset.get_matches_upper_bound()
est = self._mset.get_matches_estimated()
return _get_significant_digits(est, lower, upper)
matches_human_readable_estimate = property(_get_human_readable_estimate,
doc=
"""Get a human readable estimate of the number of matching documents.
This consists of the value returned by the "matches_estimated" property,
rounded to an appropriate number of significant digits (as determined by
the values of the "matches_lower_bound" and "matches_upper_bound"
properties).
""")
def _get_estimated(self):
return self._mset.get_matches_estimated()
matches_estimated = property(_get_estimated, doc=
"""Get an estimate for the total number of matching documents.
""")
def _estimate_is_exact(self):
return self._mset.get_matches_lower_bound() == \
self._mset.get_matches_upper_bound()
estimate_is_exact = property(_estimate_is_exact, doc=
"""Check whether the estimated number of matching documents is exact.
If this returns true, the estimate given by the `matches_estimated`
property is guaranteed to be correct.
If this returns false, it is possible that the actual number of matching
documents is different from the number given by the `matches_estimated`
property.
""")
def get_hit(self, index):
"""Get the hit with a given index.
"""
if self._mset_order is None:
msetitem = self._mset.get_hit(index)
else:
msetitem = self._mset.get_hit(self._mset_order[index])
return SearchResult(msetitem, self)
__getitem__ = get_hit
def __iter__(self):
"""Get an iterator over the hits in the search result.
The iterator returns the results in increasing order of rank.
"""
return SearchResultIter(self, self._mset_order)
def __len__(self):
"""Get the number of hits in the search result.
Note that this is not (usually) the number of matching documents for
the search. If startrank is non-zero, it's not even the rank of the
last document in the search result. It's simply the number of hits
stored in the search result.
It is, however, the number of items returned by the iterator produced
by calling iter() on this SearchResults object.
"""
return len(self._mset)
def get_top_tags(self, field, maxtags):
"""Get the most frequent tags in a given field.
- `field` - the field to get tags for. This must have been specified
in the "gettags" argument of the search() call.
- `maxtags` - the maximum number of tags to return.
Returns a sequence of 2-item tuples, in which the first item in the
tuple is the tag, and the second is the frequency of the tag in the
matches seen (as an integer).
"""
if 'tags' in _checkxapian.missing_features:
raise errors.SearchError("Tags unsupported with this release of xapian")
if self._tagspy is None or field not in self._tagfields:
raise _errors.SearchError("Field %r was not specified for getting tags" % field)
prefix = self._conn._field_mappings.get_prefix(field)
return self._tagspy.get_top_terms(prefix, maxtags)
def get_suggested_facets(self, maxfacets=5, desired_num_of_categories=7,
required_facets=None):
"""Get a suggested set of facets, to present to the user.
This returns a list, in descending order of the usefulness of the
facet, in which each item is a tuple holding:
- fieldname of facet.
- sequence of 2-tuples holding the suggested values or ranges for that
field:
For facets of type 'string', the first item in the 2-tuple will
simply be the string supplied when the facet value was added to its
document. For facets of type 'float', it will be a 2-tuple, holding
floats giving the start and end of the suggested value range.
The second item in the 2-tuple will be the frequency of the facet
value or range in the result set.
If required_facets is not None, it must be a field name, or a sequence
of field names. Any field names mentioned in required_facets will be
returned if there are any facet values at all in the search results for
that field. The facet will only be omitted if there are no facet
values at all for the field.
The value of maxfacets will be respected as far as possible; the
exception is that if there are too many fields listed in
required_facets with at least one value in the search results, extra
facets will be returned (ie, obeying the required_facets parameter is
considered more important than the maxfacets parameter).
If facet_hierarchy was indicated when search() was called, and the
query included facets, then only subfacets of those query facets and
top-level facets will be included in the returned list. Furthermore
top-level facets will only be returned if there are remaining places
in the list after it has been filled with subfacets. Note that
required_facets is still respected regardless of the facet hierarchy.
If a query type was specified when search() was called, and the query
included facets, then facets with an association of Never to the
query type are never returned, even if mentioned in required_facets.
Facets with an association of Preferred are listed before others in
the returned list.
"""
if 'facets' in _checkxapian.missing_features:
raise errors.SearchError("Facets unsupported with this release of xapian")
if self._facetspy is None:
raise _errors.SearchError("Facet selection wasn't enabled when the search was run")
if isinstance(required_facets, basestring):
required_facets = [required_facets]
scores = []
facettypes = {}
for field, slot, kwargslist in self._facetfields:
type = None
for kwargs in kwargslist:
type = kwargs.get('type', None)
if type is not None: break
if type is None: type = 'string'
if type == 'float':
if field not in self._numeric_ranges_built:
self._facetspy.build_numeric_ranges(slot, desired_num_of_categories)
self._numeric_ranges_built[field] = None
facettypes[field] = type
score = self._facetspy.score_categorisation(slot, desired_num_of_categories)
scores.append((score, field, slot))
# Sort on whether facet is top-level ahead of score (use subfacets first),
# and on whether facet is preferred for the query type ahead of anything else
if self._facethierarchy:
# Note, tuple[-2] is the value of 'field' in a scores tuple
scores = [(tuple[-2] not in self._facethierarchy,) + tuple for tuple in scores]
if self._facetassocs:
preferred = _indexerconnection.IndexerConnection.FacetQueryType_Preferred
scores = [(self._facetassocs.get(tuple[-2]) != preferred,) + tuple for tuple in scores]
scores.sort()
if self._facethierarchy:
index = 1
else:
index = 0
if self._facetassocs:
index += 1
if index > 0:
scores = [tuple[index:] for tuple in scores]
results = []
required_results = []
for score, field, slot in scores:
# Check if the facet is required
required = False
if required_facets is not None:
required = field in required_facets
# If we've got enough facets, and the field isn't required, skip it
if not required and len(results) + len(required_results) >= maxfacets:
continue
# Get the values
values = self._facetspy.get_values_as_dict(slot)
if field in self._numeric_ranges_built:
if '' in values:
del values['']
# Required facets must occur at least once, other facets must occur
# at least twice.
if required:
if len(values) < 1:
continue
else:
if len(values) <= 1:
continue
newvalues = []
if facettypes[field] == 'float':
# Convert numbers to python numbers, and number ranges to a
# python tuple of two numbers.
for value, frequency in values.iteritems():
if len(value) <= 9:
value1 = _log(_xapian.sortable_unserialise, value)
value2 = value1
else:
value1 = _log(_xapian.sortable_unserialise, value[:9])
value2 = _log(_xapian.sortable_unserialise, value[9:])
newvalues.append(((value1, value2), frequency))
else:
for value, frequency in values.iteritems():
newvalues.append((value, frequency))
newvalues.sort()
if required:
required_results.append((score, field, newvalues))
else:
results.append((score, field, newvalues))
# Throw away any excess results if we have more required_results to
# insert.
maxfacets = maxfacets - len(required_results)
if maxfacets <= 0:
results = required_results
else:
results = results[:maxfacets]
results.extend(required_results)
results.sort()
# Throw away the scores because they're not meaningful outside this
# algorithm.
results = [(field, newvalues) for (score, field, newvalues) in results]
return results
class SearchConnection(object):
"""A connection to the search engine for searching.
The connection will access a view of the database.
"""
_qp_flags_base = _xapian.QueryParser.FLAG_LOVEHATE
_qp_flags_phrase = _xapian.QueryParser.FLAG_PHRASE
_qp_flags_synonym = (_xapian.QueryParser.FLAG_AUTO_SYNONYMS |
_xapian.QueryParser.FLAG_AUTO_MULTIWORD_SYNONYMS)
_qp_flags_bool = _xapian.QueryParser.FLAG_BOOLEAN
_index = None
def __init__(self, indexpath):
"""Create a new connection to the index for searching.
There may only an arbitrary number of search connections for a
particular database open at a given time (regardless of whether there
is a connection for indexing open as well).
If the database doesn't exist, an exception will be raised.
"""
self._index = _log(_xapian.Database, indexpath)
self._indexpath = indexpath
# Read the actions.
self._load_config()
self._close_handlers = []
def __del__(self):
self.close()
def append_close_handler(self, handler, userdata=None):
"""Append a callback to the list of close handlers.
These will be called when the SearchConnection is closed. This happens
when the close() method is called, or when the SearchConnection object
is deleted. The callback will be passed two arguments: the path to the
SearchConnection object, and the userdata supplied to this method.
The handlers will be called in the order in which they were added.
The handlers will be called after the connection has been closed, so
cannot prevent it closing: their return value will be ignored. In
addition, they should not raise any exceptions.
"""
self._close_handlers.append((handler, userdata))
def _get_sort_type(self, field):
"""Get the sort type that should be used for a given field.
"""
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
for action, kwargslist in actions.iteritems():
if action == FieldActions.SORT_AND_COLLAPSE:
for kwargs in kwargslist:
return kwargs['type']
def _load_config(self):
"""Load the configuration for the database.
"""
# Note: this code is basically duplicated in the IndexerConnection
# class. Move it to a shared location.
assert self._index is not None
config_str = _log(self._index.get_metadata, '_xappy_config')
if len(config_str) == 0:
self._field_actions = {}
self._field_mappings = _fieldmappings.FieldMappings()
self._facet_hierarchy = {}
self._facet_query_table = {}
return
try:
(self._field_actions, mappings, self._facet_hierarchy, self._facet_query_table, self._next_docid) = _cPickle.loads(config_str)
except ValueError:
# Backwards compatibility - configuration used to lack _facet_hierarchy and _facet_query_table
(self._field_actions, mappings, self._next_docid) = _cPickle.loads(config_str)
self._facet_hierarchy = {}
self._facet_query_table = {}
self._field_mappings = _fieldmappings.FieldMappings(mappings)
def reopen(self):
"""Reopen the connection.
This updates the revision of the index which the connection references
to the latest flushed revision.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
self._index.reopen()
# Re-read the actions.
self._load_config()
def close(self):
"""Close the connection to the database.
It is important to call this method before allowing the class to be
garbage collected to ensure that the connection is cleaned up promptly.
No other methods may be called on the connection after this has been
called. (It is permissible to call close() multiple times, but
only the first call will have any effect.)
If an exception occurs, the database will be closed, but changes since
the last call to flush may be lost.
"""
if self._index is None:
return
# Remember the index path
indexpath = self._indexpath
# There is currently no "close()" method for xapian databases, so
# we have to rely on the garbage collector. Since we never copy
# the _index property out of this class, there should be no cycles,
# so the standard python implementation should garbage collect
# _index straight away. A close() method is planned to be added to
# xapian at some point - when it is, we should call it here to make
# the code more robust.
self._index = None
self._indexpath = None
self._field_actions = None
self._field_mappings = None
# Call the close handlers.
for handler, userdata in self._close_handlers:
try:
handler(indexpath, userdata)
except Exception, e:
import sys, traceback
print >>sys.stderr, "WARNING: unhandled exception in handler called by SearchConnection.close(): %s" % traceback.format_exception_only(type(e), e)
def get_doccount(self):
"""Count the number of documents in the database.
This count will include documents which have been added or removed but
not yet flushed().
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
return self._index.get_doccount()
OP_AND = _xapian.Query.OP_AND
OP_OR = _xapian.Query.OP_OR
def query_composite(self, operator, queries):
"""Build a composite query from a list of queries.
The queries are combined with the supplied operator, which is either
SearchConnection.OP_AND or SearchConnection.OP_OR.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
return _log(_xapian.Query, operator, list(queries))
def query_multweight(self, query, multiplier):
"""Build a query which modifies the weights of a subquery.
This produces a query which returns the same documents as the subquery,
and in the same order, but with the weights assigned to each document
multiplied by the value of "multiplier". "multiplier" may be any floating
point value, but negative values will be clipped to 0, since Xapian
doesn't support negative weights.
This can be useful when producing queries to be combined with
query_composite, because it allows the relative importance of parts of
the query to be adjusted.
"""
return _log(_xapian.Query, _xapian.Query.OP_SCALE_WEIGHT, query, multiplier)
def query_filter(self, query, filter, exclude=False):
"""Filter a query with another query.
If exclude is False (or not specified), documents will only match the
resulting query if they match the both the first and second query: the
results of the first query are "filtered" to only include those which
also match the second query.
If exclude is True, documents will only match the resulting query if
they match the first query, but not the second query: the results of
the first query are "filtered" to only include those which do not match
the second query.
Documents will always be weighted according to only the first query.
- `query`: The query to filter.
- `filter`: The filter to apply to the query.
- `exclude`: If True, the sense of the filter is reversed - only
documents which do not match the second query will be returned.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if not isinstance(filter, _xapian.Query):
raise _errors.SearchError("Filter must be a Xapian Query object")
if exclude:
return _log(_xapian.Query, _xapian.Query.OP_AND_NOT, query, filter)
else:
return _log(_xapian.Query, _xapian.Query.OP_FILTER, query, filter)
def query_adjust(self, primary, secondary):
"""Adjust the weights of one query with a secondary query.
Documents will be returned from the resulting query if and only if they
match the primary query (specified by the "primary" parameter).
However, the weights (and hence, the relevance rankings) of the
documents will be adjusted by adding weights from the secondary query
(specified by the "secondary" parameter).
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
return _log(_xapian.Query, _xapian.Query.OP_AND_MAYBE, primary, secondary)
def query_range(self, field, begin, end):
"""Create a query for a range search.
This creates a query which matches only those documents which have a
field value in the specified range.
Begin and end must be appropriate values for the field, according to
the 'type' parameter supplied to the SORTABLE action for the field.
The begin and end values are both inclusive - any documents with a
value equal to begin or end will be returned (unless end is less than
begin, in which case no documents will be returned).
Begin or end may be set to None in order to create an open-ended
range. (They may also both be set to None, which will generate a query
which matches all documents containing any value for the field.)
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if begin is None and end is None:
# Return a "match everything" query
return _log(_xapian.Query, '')
try:
slot = self._field_mappings.get_slot(field, 'collsort')
except KeyError:
# Return a "match nothing" query
return _log(_xapian.Query)
sorttype = self._get_sort_type(field)
marshaller = SortableMarshaller(False)
fn = marshaller.get_marshall_function(field, sorttype)
if begin is not None:
begin = fn(field, begin)
if end is not None:
end = fn(field, end)
if begin is None:
return _log(_xapian.Query, _xapian.Query.OP_VALUE_LE, slot, end)
if end is None:
return _log(_xapian.Query, _xapian.Query.OP_VALUE_GE, slot, begin)
return _log(_xapian.Query, _xapian.Query.OP_VALUE_RANGE, slot, begin, end)
def query_facet(self, field, val):
"""Create a query for a facet value.
This creates a query which matches only those documents which have a
facet value in the specified range.
For a numeric range facet, val should be a tuple holding the start and
end of the range, or a comma separated string holding two floating
point values. For other facets, val should be the value to look
for.
The start and end values are both inclusive - any documents with a
value equal to start or end will be returned (unless end is less than
start, in which case no documents will be returned).
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if 'facets' in _checkxapian.missing_features:
raise errors.SearchError("Facets unsupported with this release of xapian")
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
facettype = None
for action, kwargslist in actions.iteritems():
if action == FieldActions.FACET:
for kwargs in kwargslist:
facettype = kwargs.get('type', None)
if facettype is not None:
break
if facettype is not None:
break
if facettype == 'float':
if isinstance(val, basestring):
val = [float(v) for v in val.split(',', 2)]
assert(len(val) == 2)
try:
slot = self._field_mappings.get_slot(field, 'facet')
except KeyError:
return _log(_xapian.Query)
# FIXME - check that sorttype == self._get_sort_type(field)
sorttype = 'float'
marshaller = SortableMarshaller(False)
fn = marshaller.get_marshall_function(field, sorttype)
begin = fn(field, val[0])
end = fn(field, val[1])
return _log(_xapian.Query, _xapian.Query.OP_VALUE_RANGE, slot, begin, end)
else:
assert(facettype == 'string' or facettype is None)
prefix = self._field_mappings.get_prefix(field)
return _log(_xapian.Query, prefix + val.lower())
def _prepare_queryparser(self, allow, deny, default_op, default_allow,
default_deny):
"""Prepare (and return) a query parser using the specified fields and
operator.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if isinstance(allow, basestring):
allow = (allow, )
if isinstance(deny, basestring):
deny = (deny, )
if allow is not None and len(allow) == 0:
allow = None
if deny is not None and len(deny) == 0:
deny = None
if allow is not None and deny is not None:
raise _errors.SearchError("Cannot specify both `allow` and `deny` "
"(got %r and %r)" % (allow, deny))
if isinstance(default_allow, basestring):
default_allow = (default_allow, )
if isinstance(default_deny, basestring):
default_deny = (default_deny, )
if default_allow is not None and len(default_allow) == 0:
default_allow = None
if default_deny is not None and len(default_deny) == 0:
default_deny = None
if default_allow is not None and default_deny is not None:
raise _errors.SearchError("Cannot specify both `default_allow` and `default_deny` "
"(got %r and %r)" % (default_allow, default_deny))
qp = _log(_xapian.QueryParser)
qp.set_database(self._index)
qp.set_default_op(default_op)
if allow is None:
allow = [key for key in self._field_actions]
if deny is not None:
allow = [key for key in allow if key not in deny]
for field in allow:
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
for action, kwargslist in actions.iteritems():
if action == FieldActions.INDEX_EXACT:
# FIXME - need patched version of xapian to add exact prefixes
#qp.add_exact_prefix(field, self._field_mappings.get_prefix(field))
qp.add_prefix(field, self._field_mappings.get_prefix(field))
if action == FieldActions.INDEX_FREETEXT:
allow_field_specific = True
for kwargs in kwargslist:
allow_field_specific = allow_field_specific or kwargs.get('allow_field_specific', True)
if not allow_field_specific:
continue
qp.add_prefix(field, self._field_mappings.get_prefix(field))
for kwargs in kwargslist:
try:
lang = kwargs['language']
my_stemmer = _log(_xapian.Stem, lang)
qp.my_stemmer = my_stemmer
qp.set_stemmer(my_stemmer)
qp.set_stemming_strategy(qp.STEM_SOME)
except KeyError:
pass
if default_allow is not None or default_deny is not None:
if default_allow is None:
default_allow = [key for key in self._field_actions]
if default_deny is not None:
default_allow = [key for key in default_allow if key not in default_deny]
for field in default_allow:
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
for action, kwargslist in actions.iteritems():
if action == FieldActions.INDEX_FREETEXT:
qp.add_prefix('', self._field_mappings.get_prefix(field))
# FIXME - set stemming options for the default prefix
return qp
def _query_parse_with_prefix(self, qp, string, flags, prefix):
"""Parse a query, with an optional prefix.
"""
if prefix is None:
return qp.parse_query(string, flags)
else:
return qp.parse_query(string, flags, prefix)
def _query_parse_with_fallback(self, qp, string, prefix=None):
"""Parse a query with various flags.
If the initial boolean pass fails, fall back to not using boolean
operators.
"""
try:
q1 = self._query_parse_with_prefix(qp, string,
self._qp_flags_base |
self._qp_flags_phrase |
self._qp_flags_synonym |
self._qp_flags_bool,
prefix)
except _xapian.QueryParserError, e:
# If we got a parse error, retry without boolean operators (since
# these are the usual cause of the parse error).
q1 = self._query_parse_with_prefix(qp, string,
self._qp_flags_base |
self._qp_flags_phrase |
self._qp_flags_synonym,
prefix)
qp.set_stemming_strategy(qp.STEM_NONE)
try:
q2 = self._query_parse_with_prefix(qp, string,
self._qp_flags_base |
self._qp_flags_bool,
prefix)
except _xapian.QueryParserError, e:
# If we got a parse error, retry without boolean operators (since
# these are the usual cause of the parse error).
q2 = self._query_parse_with_prefix(qp, string,
self._qp_flags_base,
prefix)
return _log(_xapian.Query, _xapian.Query.OP_AND_MAYBE, q1, q2)
def query_parse(self, string, allow=None, deny=None, default_op=OP_AND,
default_allow=None, default_deny=None):
"""Parse a query string.
This is intended for parsing queries entered by a user. If you wish to
combine structured queries, it is generally better to use the other
query building methods, such as `query_composite` (though you may wish
to create parts of the query to combine with such methods with this
method).
The string passed to this method can have various operators in it. In
particular, it may contain field specifiers (ie, field names, followed
by a colon, followed by some text to search for in that field). For
example, if "author" is a field in the database, the search string
could contain "author:richard", and this would be interpreted as
"search for richard in the author field". By default, any fields in
the database which are indexed with INDEX_EXACT or INDEX_FREETEXT will
be available for field specific searching in this way - however, this
can be modified using the "allow" or "deny" parameters, and also by the
allow_field_specific tag on INDEX_FREETEXT fields.
Any text which isn't prefixed by a field specifier is used to search
the "default set" of fields. By default, this is the full set of
fields in the database which are indexed with INDEX_FREETEXT and for
which the search_by_default flag set (ie, if the text is found in any
of those fields, the query will match). However, this may be modified
with the "default_allow" and "default_deny" parameters. (Note that
fields which are indexed with INDEX_EXACT aren't allowed to be used in
the default list of fields.)
- `string`: The string to parse.
- `allow`: A list of fields to allow in the query.
- `deny`: A list of fields not to allow in the query.
- `default_op`: The default operator to combine query terms with.
- `default_allow`: A list of fields to search for by default.
- `default_deny`: A list of fields not to search for by default.
Only one of `allow` and `deny` may be specified.
Only one of `default_allow` and `default_deny` may be specified.
If any of the entries in `allow` are not present in the configuration
for the database, or are not specified for indexing (either as
INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
entries in `deny` are not present in the configuration for the
database, they will be ignored.
Returns a Query object, which may be passed to the search() method, or
combined with other queries.
"""
qp = self._prepare_queryparser(allow, deny, default_op, default_allow,
default_deny)
return self._query_parse_with_fallback(qp, string)
def query_field(self, field, value, default_op=OP_AND):
"""A query for a single field.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
# need to check on field type, and stem / split as appropriate
for action, kwargslist in actions.iteritems():
if action in (FieldActions.INDEX_EXACT,
FieldActions.TAG,
FieldActions.FACET,):
prefix = self._field_mappings.get_prefix(field)
if len(value) > 0:
chval = ord(value[0])
if chval >= ord('A') and chval <= ord('Z'):
prefix = prefix + ':'
return _log(_xapian.Query, prefix + value)
if action == FieldActions.INDEX_FREETEXT:
qp = _log(_xapian.QueryParser)
qp.set_default_op(default_op)
prefix = self._field_mappings.get_prefix(field)
for kwargs in kwargslist:
try:
lang = kwargs['language']
qp.set_stemmer(_log(_xapian.Stem, lang))
qp.set_stemming_strategy(qp.STEM_SOME)
except KeyError:
pass
return self._query_parse_with_fallback(qp, value, prefix)
return _log(_xapian.Query)
def query_similar(self, ids, allow=None, deny=None, simterms=10):
"""Get a query which returns documents which are similar to others.
The list of document IDs to base the similarity search on is given in
`ids`. This should be an iterable, holding a list of strings. If
any of the supplied IDs cannot be found in the database, they will be
ignored. (If no IDs can be found in the database, the resulting query
will not match any documents.)
By default, all fields which have been indexed for freetext searching
will be used for the similarity calculation. The list of fields used
for this can be customised using the `allow` and `deny` parameters
(only one of which may be specified):
- `allow`: A list of fields to base the similarity calculation on.
- `deny`: A list of fields not to base the similarity calculation on.
- `simterms`: Number of terms to use for the similarity calculation.
For convenience, any of `ids`, `allow`, or `deny` may be strings, which
will be treated the same as a list of length 1.
Regardless of the setting of `allow` and `deny`, only fields which have
been indexed for freetext searching will be used for the similarity
measure - all other fields will always be ignored for this purpose.
"""
eterms, prefixes = self._get_eterms(ids, allow, deny, simterms)
# Use the "elite set" operator, which chooses the terms with the
# highest query weight to use.
q = _log(_xapian.Query, _xapian.Query.OP_ELITE_SET, eterms, simterms)
return q
def significant_terms(self, ids, maxterms=10, allow=None, deny=None):
"""Get a set of "significant" terms for a document, or documents.
This has a similar interface to query_similar(): it takes a list of
ids, and an optional specification of a set of fields to consider.
Instead of returning a query, it returns a list of terms from the
document (or documents), which appear "significant". Roughly,
in this situation significant means that the terms occur more
frequently in the specified document than in the rest of the corpus.
The list is in decreasing order of "significance".
By default, all terms related to fields which have been indexed for
freetext searching will be considered for the list of significant
terms. The list of fields used for this can be customised using the
`allow` and `deny` parameters (only one of which may be specified):
- `allow`: A list of fields to consider.
- `deny`: A list of fields not to consider.
For convenience, any of `ids`, `allow`, or `deny` may be strings, which
will be treated the same as a list of length 1.
Regardless of the setting of `allow` and `deny`, only fields which have
been indexed for freetext searching will be considered - all other
fields will always be ignored for this purpose.
The maximum number of terms to return may be specified by the maxterms
parameter.
"""
eterms, prefixes = self._get_eterms(ids, allow, deny, maxterms)
terms = []
for term in eterms:
pos = 0
for char in term:
if not char.isupper():
break
pos += 1
field = prefixes[term[:pos]]
value = term[pos:]
terms.append((field, value))
return terms
def _get_eterms(self, ids, allow, deny, simterms):
"""Get a set of terms for an expand
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if allow is not None and deny is not None:
raise _errors.SearchError("Cannot specify both `allow` and `deny`")
if isinstance(ids, basestring):
ids = (ids, )
if isinstance(allow, basestring):
allow = (allow, )
if isinstance(deny, basestring):
deny = (deny, )
# Set "allow" to contain a list of all the fields to use.
if allow is None:
allow = [key for key in self._field_actions]
if deny is not None:
allow = [key for key in allow if key not in deny]
# Set "prefixes" to contain a list of all the prefixes to use.
prefixes = {}
for field in allow:
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
for action, kwargslist in actions.iteritems():
if action == FieldActions.INDEX_FREETEXT:
prefixes[self._field_mappings.get_prefix(field)] = field
# Repeat the expand until we don't get a DatabaseModifiedError
while True:
try:
eterms = self._perform_expand(ids, prefixes, simterms)
break;
except _xapian.DatabaseModifiedError, e:
self.reopen()
return eterms, prefixes
class ExpandDecider(_xapian.ExpandDecider):
def __init__(self, prefixes):
_xapian.ExpandDecider.__init__(self)
self._prefixes = prefixes
def __call__(self, term):
pos = 0
for char in term:
if not char.isupper():
break
pos += 1
if term[:pos] in self._prefixes:
return True
return False
def _perform_expand(self, ids, prefixes, simterms):
"""Perform an expand operation to get the terms for a similarity
search, given a set of ids (and a set of prefixes to restrict the
similarity operation to).
"""
# Set idquery to be a query which returns the documents listed in
# "ids".
idquery = _log(_xapian.Query, _xapian.Query.OP_OR, ['Q' + id for id in ids])
enq = _log(_xapian.Enquire, self._index)
enq.set_query(idquery)
rset = _log(_xapian.RSet)
for id in ids:
pl = self._index.postlist('Q' + id)
try:
xapid = pl.next()
rset.add_document(xapid.docid)
except StopIteration:
pass
expanddecider = _log(self.ExpandDecider, prefixes)
eset = enq.get_eset(simterms, rset, 0, 1.0, expanddecider)
return [term.term for term in eset]
def query_all(self):
"""A query which matches all the documents in the database.
"""
return _log(_xapian.Query, '')
def query_none(self):
"""A query which matches no documents in the database.
This may be useful as a placeholder in various situations.
"""
return _log(_xapian.Query)
def spell_correct(self, querystr, allow=None, deny=None, default_op=OP_AND,
default_allow=None, default_deny=None):
"""Correct a query spelling.
This returns a version of the query string with any misspelt words
corrected.
- `allow`: A list of fields to allow in the query.
- `deny`: A list of fields not to allow in the query.
- `default_op`: The default operator to combine query terms with.
- `default_allow`: A list of fields to search for by default.
- `default_deny`: A list of fields not to search for by default.
Only one of `allow` and `deny` may be specified.
Only one of `default_allow` and `default_deny` may be specified.
If any of the entries in `allow` are not present in the configuration
for the database, or are not specified for indexing (either as
INDEX_EXACT or INDEX_FREETEXT), they will be ignored. If any of the
entries in `deny` are not present in the configuration for the
database, they will be ignored.
Note that it is possible that the resulting spell-corrected query will
still match no documents - the user should usually check that some
documents are matched by the corrected query before suggesting it to
users.
"""
qp = self._prepare_queryparser(allow, deny, default_op, default_allow,
default_deny)
try:
qp.parse_query(querystr,
self._qp_flags_base |
self._qp_flags_phrase |
self._qp_flags_synonym |
self._qp_flags_bool |
qp.FLAG_SPELLING_CORRECTION)
except _xapian.QueryParserError:
qp.parse_query(querystr,
self._qp_flags_base |
self._qp_flags_phrase |
self._qp_flags_synonym |
qp.FLAG_SPELLING_CORRECTION)
corrected = qp.get_corrected_query_string()
if len(corrected) == 0:
if isinstance(querystr, unicode):
# Encode as UTF-8 for consistency - this happens automatically
# to values passed to Xapian.
return querystr.encode('utf-8')
return querystr
return corrected
def can_collapse_on(self, field):
"""Check if this database supports collapsing on a specified field.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
try:
self._field_mappings.get_slot(field, 'collsort')
except KeyError:
return False
return True
def can_sort_on(self, field):
"""Check if this database supports sorting on a specified field.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
try:
self._field_mappings.get_slot(field, 'collsort')
except KeyError:
return False
return True
def _get_prefix_from_term(self, term):
"""Get the prefix of a term.
Prefixes are any initial capital letters, with the exception that R always
ends a prefix, even if followed by capital letters.
"""
for p in xrange(len(term)):
if term[p].islower():
return term[:p]
elif term[p] == 'R':
return term[:p+1]
return term
def _facet_query_never(self, facet, query_type):
"""Check if a facet must never be returned by a particular query type.
Returns True if the facet must never be returned.
Returns False if the facet may be returned - either becuase there is no
entry for the query type, or because the entry is not
FacetQueryType_Never.
"""
if query_type is None:
return False
if query_type not in self._facet_query_table:
return False
if facet not in self._facet_query_table[query_type]:
return False
return self._facet_query_table[query_type][facet] == _indexerconnection.IndexerConnection.FacetQueryType_Never
def search(self, query, startrank, endrank,
checkatleast=0, sortby=None, collapse=None,
gettags=None,
getfacets=None, allowfacets=None, denyfacets=None, usesubfacets=None,
percentcutoff=None, weightcutoff=None,
query_type=None):
"""Perform a search, for documents matching a query.
- `query` is the query to perform.
- `startrank` is the rank of the start of the range of matching
documents to return (ie, the result with this rank will be returned).
ranks start at 0, which represents the "best" matching document.
- `endrank` is the rank at the end of the range of matching documents
to return. This is exclusive, so the result with this rank will not
be returned.
- `checkatleast` is the minimum number of results to check for: the
estimate of the total number of matches will always be exact if
the number of matches is less than `checkatleast`. A value of ``-1``
can be specified for the checkatleast parameter - this has the
special meaning of "check all matches", and is equivalent to passing
the result of get_doccount().
- `sortby` is the name of a field to sort by. It may be preceded by a
'+' or a '-' to indicate ascending or descending order
(respectively). If the first character is neither '+' or '-', the
sort will be in ascending order.
- `collapse` is the name of a field to collapse the result documents
on. If this is specified, there will be at most one result in the
result set for each value of the field.
- `gettags` is the name of a field to count tag occurrences in, or a
list of fields to do so.
- `getfacets` is a boolean - if True, the matching documents will be
examined to build up a list of the facet values contained in them.
- `allowfacets` is a list of the fieldnames of facets to consider.
- `denyfacets` is a list of fieldnames of facets which will not be
considered.
- `usesubfacets` is a boolean - if True, only top-level facets and
subfacets of facets appearing in the query are considered (taking
precedence over `allowfacets` and `denyfacets`).
- `percentcutoff` is the minimum percentage a result must have to be
returned.
- `weightcutoff` is the minimum weight a result must have to be
returned.
- `query_type` is a value indicating the type of query being
performed. If not None, the value is used to influence which facets
are be returned by the get_suggested_facets() function. If the
value of `getfacets` is False, it has no effect.
If neither 'allowfacets' or 'denyfacets' is specified, all fields
holding facets will be considered (but see 'usesubfacets').
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
if 'facets' in _checkxapian.missing_features:
if getfacets is not None or \
allowfacets is not None or \
denyfacets is not None or \
usesubfacets is not None or \
query_type is not None:
raise errors.SearchError("Facets unsupported with this release of xapian")
if 'tags' in _checkxapian.missing_features:
if gettags is not None:
raise errors.SearchError("Tags unsupported with this release of xapian")
if checkatleast == -1:
checkatleast = self._index.get_doccount()
enq = _log(_xapian.Enquire, self._index)
enq.set_query(query)
if sortby is not None:
asc = True
if sortby[0] == '-':
asc = False
sortby = sortby[1:]
elif sortby[0] == '+':
sortby = sortby[1:]
try:
slotnum = self._field_mappings.get_slot(sortby, 'collsort')
except KeyError:
raise _errors.SearchError("Field %r was not indexed for sorting" % sortby)
# Note: we invert the "asc" parameter, because xapian treats
# "ascending" as meaning "higher values are better"; in other
# words, it considers "ascending" to mean return results in
# descending order.
enq.set_sort_by_value_then_relevance(slotnum, not asc)
if collapse is not None:
try:
slotnum = self._field_mappings.get_slot(collapse, 'collsort')
except KeyError:
raise _errors.SearchError("Field %r was not indexed for collapsing" % collapse)
enq.set_collapse_key(slotnum)
maxitems = max(endrank - startrank, 0)
# Always check for at least one more result, so we can report whether
# there are more matches.
checkatleast = max(checkatleast, endrank + 1)
# Build the matchspy.
matchspies = []
# First, add a matchspy for any gettags fields
if isinstance(gettags, basestring):
if len(gettags) != 0:
gettags = [gettags]
tagspy = None
if gettags is not None and len(gettags) != 0:
tagspy = _log(_xapian.TermCountMatchSpy)
for field in gettags:
try:
prefix = self._field_mappings.get_prefix(field)
tagspy.add_prefix(prefix)
except KeyError:
raise _errors.SearchError("Field %r was not indexed for tagging" % field)
matchspies.append(tagspy)
# add a matchspy for facet selection here.
facetspy = None
facetfields = []
if getfacets:
if allowfacets is not None and denyfacets is not None:
raise _errors.SearchError("Cannot specify both `allowfacets` and `denyfacets`")
if allowfacets is None:
allowfacets = [key for key in self._field_actions]
if denyfacets is not None:
allowfacets = [key for key in allowfacets if key not in denyfacets]
# include None in queryfacets so a top-level facet will
# satisfy self._facet_hierarchy.get(field) in queryfacets
# (i.e. always include top-level facets)
queryfacets = set([None])
if usesubfacets:
# add facets used in the query to queryfacets
termsiter = query.get_terms_begin()
termsend = query.get_terms_end()
while termsiter != termsend:
prefix = self._get_prefix_from_term(termsiter.get_term())
field = self._field_mappings.get_fieldname_from_prefix(prefix)
if field and FieldActions.FACET in self._field_actions[field]._actions:
queryfacets.add(field)
termsiter.next()
for field in allowfacets:
try:
actions = self._field_actions[field]._actions
except KeyError:
actions = {}
for action, kwargslist in actions.iteritems():
if action == FieldActions.FACET:
# filter out non-top-level facets that aren't subfacets
# of a facet in the query
if usesubfacets and self._facet_hierarchy.get(field) not in queryfacets:
continue
# filter out facets that should never be returned for the query type
if self._facet_query_never(field, query_type):
continue
slot = self._field_mappings.get_slot(field, 'facet')
if facetspy is None:
facetspy = _log(_xapian.CategorySelectMatchSpy)
facettype = None
for kwargs in kwargslist:
facettype = kwargs.get('type', None)
if facettype is not None:
break
if facettype is None or facettype == 'string':
facetspy.add_slot(slot, True)
else:
facetspy.add_slot(slot)
facetfields.append((field, slot, kwargslist))
if facetspy is None:
# Set facetspy to False, to distinguish from no facet
# calculation being performed. (This will prevent an
# error being thrown when the list of suggested facets is
# requested - instead, an empty list will be returned.)
facetspy = False
else:
matchspies.append(facetspy)
# Finally, build a single matchspy to pass to get_mset().
if len(matchspies) == 0:
matchspy = None
elif len(matchspies) == 1:
matchspy = matchspies[0]
else:
matchspy = _log(_xapian.MultipleMatchDecider)
for spy in matchspies:
matchspy.append(spy)
enq.set_docid_order(enq.DONT_CARE)
# Set percentage and weight cutoffs
if percentcutoff is not None or weightcutoff is not None:
if percentcutoff is None:
percentcutoff = 0
if weightcutoff is None:
weightcutoff = 0
enq.set_cutoff(percentcutoff, weightcutoff)
# Repeat the search until we don't get a DatabaseModifiedError
while True:
try:
if matchspy is None:
mset = enq.get_mset(startrank, maxitems, checkatleast)
else:
mset = enq.get_mset(startrank, maxitems, checkatleast,
None, None, matchspy)
break
except _xapian.DatabaseModifiedError, e:
self.reopen()
facet_hierarchy = None
if usesubfacets:
facet_hierarchy = self._facet_hierarchy
return SearchResults(self, enq, query, mset, self._field_mappings,
tagspy, gettags, facetspy, facetfields,
facet_hierarchy,
self._facet_query_table.get(query_type))
def iterids(self):
"""Get an iterator which returns all the ids in the database.
The unqiue_ids are currently returned in binary lexicographical sort
order, but this should not be relied on.
Note that the iterator returned by this method may raise a
xapian.DatabaseModifiedError exception if modifications are committed
to the database while the iteration is in progress. If this happens,
the search connection must be reopened (by calling reopen) and the
iteration restarted.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
return _indexerconnection.PrefixedTermIter('Q', self._index.allterms())
def get_document(self, id):
"""Get the document with the specified unique ID.
Raises a KeyError if there is no such document. Otherwise, it returns
a ProcessedDocument.
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
while True:
try:
postlist = self._index.postlist('Q' + id)
try:
plitem = postlist.next()
except StopIteration:
# Unique ID not found
raise KeyError('Unique ID %r not found' % id)
try:
postlist.next()
raise _errors.IndexerError("Multiple documents " #pragma: no cover
"found with same unique ID")
except StopIteration:
# Only one instance of the unique ID found, as it should be.
pass
result = ProcessedDocument(self._field_mappings)
result.id = id
result._doc = self._index.get_document(plitem.docid)
return result
except _xapian.DatabaseModifiedError, e:
self.reopen()
def iter_synonyms(self, prefix=""):
"""Get an iterator over the synonyms.
- `prefix`: if specified, only synonym keys with this prefix will be
returned.
The iterator returns 2-tuples, in which the first item is the key (ie,
a 2-tuple holding the term or terms which will be synonym expanded,
followed by the fieldname specified (or None if no fieldname)), and the
second item is a tuple of strings holding the synonyms for the first
item.
These return values are suitable for the dict() builtin, so you can
write things like:
>>> conn = _indexerconnection.IndexerConnection('foo')
>>> conn.add_synonym('foo', 'bar')
>>> conn.add_synonym('foo bar', 'baz')
>>> conn.add_synonym('foo bar', 'foo baz')
>>> conn.flush()
>>> conn = SearchConnection('foo')
>>> dict(conn.iter_synonyms())
{('foo', None): ('bar',), ('foo bar', None): ('baz', 'foo baz')}
"""
if self._index is None:
raise _errors.SearchError("SearchConnection has been closed")
return _indexerconnection.SynonymIter(self._index, self._field_mappings, prefix)
def get_metadata(self, key):
"""Get an item of metadata stored in the connection.
This returns a value stored by a previous call to
IndexerConnection.set_metadata.
If the value is not found, this will return the empty string.
"""
if self._index is None:
raise _errors.IndexerError("SearchConnection has been closed")
if not hasattr(self._index, 'get_metadata'):
raise _errors.IndexerError("Version of xapian in use does not support metadata")
return _log(self._index.get_metadata, key)
if __name__ == '__main__':
import doctest, sys
doctest.testmod (sys.modules[__name__])
xappy-0.5/xappy/searchconnection_doctest1.txt 0000644 0001750 0001750 00000014035 10736164666 021410 0 ustar richard richard
>>> from datastructures import *
>>> from fieldactions import *
>>> from indexerconnection import *
Open a connection for indexing:
>>> iconn = IndexerConnection('foo')
>>> iconn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('category', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('text', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('author', FieldActions.INDEX_FREETEXT, weight=2)
>>> iconn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=5)
>>> iconn.add_field_action('category', FieldActions.INDEX_EXACT)
>>> iconn.add_field_action('category', FieldActions.SORTABLE)
>>> iconn.add_field_action('category', FieldActions.COLLAPSE)
>>> iconn.add_field_action('text', FieldActions.INDEX_FREETEXT, language='en')
Add a set of documents:
>>> for i in xrange(200):
... doc = UnprocessedDocument()
... doc.fields.append(Field('author', 'Richard Boulton'))
... doc.fields.append(Field('category', 'Cat %d' % ((i + 5) % 20)))
... doc.fields.append(Field('text', 'This document is a basic test document.'))
... doc.fields.append(Field('title', 'Test document %d' % i))
... doc.fields.append(Field('text', 'More test text about this document.'))
... id = iconn.add(doc)
We can get a document from the indexer connection, even before flushing, by
using the get_document method. If the id specified is not found, an error is
raised.
>>> iconn.get_document('1').data['category']
['Cat 6']
>>> print iconn.get_document('1000').data['category']
Traceback (most recent call last):
...
KeyError: "Unique ID '1000' not found"
If we open a search connection for a database which doesn't exist, we get an
exception:
>>> sconn = SearchConnection('notpresent')
Traceback (most recent call last):
...
DatabaseOpeningError: Couldn't detect type of database
If we open a search connection before flushing, we can't see the recent
modifications:
>>> sconn = SearchConnection('foo')
>>> sconn.get_document('1').data['category']
Traceback (most recent call last):
...
KeyError: "Unique ID '1' not found"
Finally, we get round to flushing the indexer:
>>> iconn.flush()
We still can't see the document from the search connection.
>>> sconn.get_document('1').data['category']
Traceback (most recent call last):
...
KeyError: "Unique ID '1' not found"
Now, open a new search connection - we can see the document:
>>> sconn = SearchConnection('foo')
>>> sconn.get_document('1').data['category']
['Cat 6']
>>> q = sconn.query_parse('document')
>>> results = sconn.search(q, 0, 30)
>>> len(results)
30
>>> [result.id for result in results]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d']
>>> result = results.get_hit(0)
>>> result.data['text']
['This document is a basic test document.', 'More test text about this document.']
>>> result.highlight('text')
['This document is a basic test document .', 'More test text about this document .']
>>> result.summarise('text')
'This document is a basic test document .\nMore test text about this document .'
>>> result.summarise('text', maxlen=20)
'This document is a ..'
>>> result.summarise('title', maxlen=20)
'Test document 0'
If we collapse on categories, we just get the top result in each category:
>>> [result.id for result in sconn.search(q, 0, 30, collapse='category')]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '10', '11', '12', '13']
We can't collapse on categories which we're indexed for it:
>>> [result.id for result in sconn.search(q, 0, 30, collapse='author')]
Traceback (most recent call last):
...
SearchError: Field 'author' was not indexed for collapsing
If we sort by category, we get a different order of results:
>>> [':'.join((result.id, result.data['category'][0])) for result in sconn.search(q, 0, 30, sortby='-category')]
['4:Cat 9', '18:Cat 9', '2c:Cat 9', '40:Cat 9', '54:Cat 9', '68:Cat 9', '7c:Cat 9', '90:Cat 9', 'a4:Cat 9', 'b8:Cat 9', '3:Cat 8', '17:Cat 8', '2b:Cat 8', '3f:Cat 8', '53:Cat 8', '67:Cat 8', '7b:Cat 8', '8f:Cat 8', 'a3:Cat 8', 'b7:Cat 8', '2:Cat 7', '16:Cat 7', '2a:Cat 7', '3e:Cat 7', '52:Cat 7', '66:Cat 7', '7a:Cat 7', '8e:Cat 7', 'a2:Cat 7', 'b6:Cat 7']
We can sort in ascending order instead:
>>> [':'.join((result.id, result.data['category'][0])) for result in sconn.search(q, 0, 30, sortby='+category')]
['f:Cat 0', '23:Cat 0', '37:Cat 0', '4b:Cat 0', '5f:Cat 0', '73:Cat 0', '87:Cat 0', '9b:Cat 0', 'af:Cat 0', 'c3:Cat 0', '10:Cat 1', '24:Cat 1', '38:Cat 1', '4c:Cat 1', '60:Cat 1', '74:Cat 1', '88:Cat 1', '9c:Cat 1', 'b0:Cat 1', 'c4:Cat 1', '5:Cat 10', '19:Cat 10', '2d:Cat 10', '41:Cat 10', '55:Cat 10', '69:Cat 10', '7d:Cat 10', '91:Cat 10', 'a5:Cat 10', 'b9:Cat 10']
Ascending order is the default, so we don't actually need the '+':
>>> [':'.join((result.id, result.data['category'][0])) for result in sconn.search(q, 0, 30, sortby='category')]
['f:Cat 0', '23:Cat 0', '37:Cat 0', '4b:Cat 0', '5f:Cat 0', '73:Cat 0', '87:Cat 0', '9b:Cat 0', 'af:Cat 0', 'c3:Cat 0', '10:Cat 1', '24:Cat 1', '38:Cat 1', '4c:Cat 1', '60:Cat 1', '74:Cat 1', '88:Cat 1', '9c:Cat 1', 'b0:Cat 1', 'c4:Cat 1', '5:Cat 10', '19:Cat 10', '2d:Cat 10', '41:Cat 10', '55:Cat 10', '69:Cat 10', '7d:Cat 10', '91:Cat 10', 'a5:Cat 10', 'b9:Cat 10']
We can't collapse on categories which we're indexed for it:
>>> [result.id for result in sconn.search(q, 0, 30, sortby='author')]
Traceback (most recent call last):
...
SearchError: Field 'author' was not indexed for sorting
We can collapse and sort in a single search:
>>> [':'.join((result.id, result.data['category'][0])) for result in sconn.search(q, 0, 30, collapse="category", sortby='-category')]
['4:Cat 9', '3:Cat 8', '2:Cat 7', '1:Cat 6', '0:Cat 5', '13:Cat 4', '12:Cat 3', '11:Cat 2', 'e:Cat 19', 'd:Cat 18', 'c:Cat 17', 'b:Cat 16', 'a:Cat 15', '9:Cat 14', '8:Cat 13', '7:Cat 12', '6:Cat 11', '5:Cat 10', '10:Cat 1', 'f:Cat 0']
Tidy up after ourselves:
>>> sconn.close()
xappy-0.5/xappy/searchconnection_doctest2.txt 0000644 0001750 0001750 00000052142 11005445111 021363 0 ustar richard richard
>>> from datastructures import *
>>> from fieldactions import *
>>> from indexerconnection import *
Open a connection for indexing:
>>> iconn = IndexerConnection('foo')
>>> iconn.add_field_action('author', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('title', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('category', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('text', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('author', FieldActions.INDEX_FREETEXT, weight=2)
>>> iconn.add_field_action('title', FieldActions.INDEX_FREETEXT, weight=5)
>>> iconn.add_field_action('category', FieldActions.INDEX_EXACT)
>>> iconn.add_field_action('category', FieldActions.SORTABLE)
>>> iconn.add_field_action('category', FieldActions.COLLAPSE)
>>> iconn.add_field_action('category', FieldActions.FACET)
>>> iconn.add_field_action('text', FieldActions.INDEX_FREETEXT, language='en',
... spell=True, stop=('basic',))
>>> iconn.add_field_action('date', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('date', FieldActions.COLLAPSE)
>>> iconn.add_field_action('date', FieldActions.SORTABLE, type='date')
>>> iconn.add_field_action('date', FieldActions.COLLAPSE)
>>> iconn.add_field_action('price', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('price', FieldActions.SORTABLE, type='float')
>>> iconn.add_field_action('price', FieldActions.COLLAPSE)
>>> iconn.add_field_action('price', FieldActions.FACET, type='float')
>>> iconn.add_field_action('price3', FieldActions.SORTABLE, type='float')
>>> iconn.add_field_action('price3', FieldActions.FACET, type='float')
>>> iconn.add_field_action('price3', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('facet1', FieldActions.FACET)
>>> iconn.add_field_action('facet2', FieldActions.FACET)
>>> iconn.add_field_action('facet3', FieldActions.FACET)
>>> iconn.add_field_action('facet4', FieldActions.FACET, type='float')
>>> iconn.add_field_action('facet5', FieldActions.FACET)
>>> iconn.add_field_action('facet6', FieldActions.FACET)
>>> iconn.add_field_action('facet7', FieldActions.FACET)
>>> iconn.add_field_action('facet8', FieldActions.FACET, type='float')
>>> iconn.add_field_action('tag', FieldActions.TAG)
# Add this, for a regression test.
>>> iconn.add_field_action('facet9', FieldActions.FACET, type='float')
>>> iconn.add_field_action('facet9', FieldActions.SORTABLE)
A field can only be sorted according to one type:
>>> iconn.add_field_action('date', FieldActions.SORTABLE, type='float')
Traceback (most recent call last):
...
IndexerError: Field 'date' is already marked for sorting, with a different sort type
If we set the sort type to an unknown value, we get errors when it is used:
>>> iconn.add_field_action('price2', FieldActions.SORTABLE, type='unknown')
>>> doc = UnprocessedDocument()
>>> doc.fields.append(Field('price2', '1.0'))
>>> iconn.process(doc)
Traceback (most recent call last):
...
IndexerError: Unknown sort type 'unknown' for field 'price2'
Make another database which doesn't have any facet fields::
>>> iconn2 = IndexerConnection('foo2')
>>> iconn2.add_field_action('author', FieldActions.STORE_CONTENT)
Add a set of documents, which dates and prices, to test sorting:
>>> for i in xrange(200):
... doc = UnprocessedDocument()
... doc.fields.append(Field('author', 'Richard Boulton'))
... doc.fields.append(Field('category', 'Cat %d' % ((i + 5) % 20)))
... doc.fields.append(Field('text', 'This document is a basic test document.'))
... doc.fields.append(Field('title', 'Test document %d' % i))
... doc.fields.append(Field('text', 'More test text about this document.'))
... doc.fields.append(Field('date', '2007%02d%02d' % (i % 12 + 1, i // 12 + 1)))
... doc.fields.append(Field('price', '%f' % ((float(i) / 7) % 10)))
... doc.fields.append(Field('price3', '%f' % ((float(i) * 6.7))))
... doc.fields.append(Field('facet1', '%d' % (i // 40)))
... doc.fields.append(Field('facet2', '%d' % (i // 20)))
... doc.fields.append(Field('facet3', '%d' % (i // 12)))
... doc.fields.append(Field('facet4', '%d' % (i // 8)))
... doc.fields.append(Field('facet5', '%d' % (i // 5)))
... doc.fields.append(Field('facet6', '0'))
... doc.fields.append(Field('facet7', '2000'))
... doc.fields.append(Field('facet7', '2001'))
... doc.fields.append(Field('facet7', '%d' % (i % 2)))
... doc.fields.append(Field('facet8', '2000'))
... doc.fields.append(Field('facet8', '2001'))
... doc.fields.append(Field('facet8', '%d' % (i % 2)))
... doc.fields.append(Field('facet9', '%d' % (i // 5)))
... doc.fields.append(Field('tag', '%d' % (i % 5)))
... doc.fields.append(Field('tag', '%d' % (i % 9)))
... doc.fields.append(Field('tag', '%d' % (i // 5)))
... id = iconn.add(doc)
... id = iconn2.add(doc)
Add some synonyms:
>>> iconn.add_synonym('document', 'record')
>>> iconn.add_synonym('basic test', 'exam', original_field='text')
>>> iconn.add_synonym('document', 'notrecord')
>>> iconn.add_synonym('documents', 'notrecord')
>>> iconn.remove_synonym('document', 'notrecord')
>>> iconn.clear_synonyms('documents')
>>> iconn.flush()
>>> dict(iconn.iter_synonyms())
{('document', None): ('record',), ('basic test', 'text'): ('exam',)}
>>> dict(iconn.iter_synonyms('doc'))
{('document', None): ('record',)}
>>> dict(iconn.iter_synonyms('toc'))
{}
Now, open a search connection:
>>> sconn = SearchConnection('foo')
>>> sconn2 = SearchConnection('foo2')
We can append a close handler to notify us when the connection is closed.
>>> def closehandler(path, userdata):
... print "Closing connection at path %s: %s" % (path, userdata)
>>> sconn.append_close_handler(closehandler, "Conn1")
>>> sconn2.append_close_handler(closehandler, "Conn2")
First, check the fallback handling for queries with invalid boolean
operations:
>>> q = sconn.query_parse('AND document')
>>> str(q)
'Xapian::Query(((and:(pos=1) AND (Zdocument:(pos=2) SYNONYM record:(pos=2))) AND_MAYBE (and:(pos=1) AND document:(pos=2))))'
Check that spelling correction works:
>>> sconn.spell_correct('docment')
'document'
>>> sconn.spell_correct('document')
'document'
>>> sconn.spell_correct(u'docment')
'document'
>>> sconn.spell_correct(u'document')
'document'
Check that stopwording worked:
>>> q = sconn.query_parse('basic')
>>> results = sconn.search(q, 0, 30)
>>> [result.id for result in results]
[]
Check that synonyms work:
>>> dict(sconn.iter_synonyms())
{('document', None): ('record',), ('basic test', 'text'): ('exam',)}
>>> q = sconn.query_parse('document')
>>> str(q)
'Xapian::Query(((Zdocument:(pos=1) SYNONYM record:(pos=1)) AND_MAYBE document:(pos=1)))'
Remove the synonyms for the remaining tests:
>>> iconn.clear_synonyms('document')
>>> iconn.clear_synonyms('basic test', field='text')
>>> iconn.flush()
>>> sconn.reopen()
>>> dict(sconn.iter_synonyms())
{}
Now, parse a simple query.
>>> q = sconn.query_parse('document')
>>> str(q)
'Xapian::Query((Zdocument:(pos=1) AND_MAYBE document:(pos=1)))'
>>> results = sconn.search(q, 0, 30)
>>> [result.id for result in results]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d']
>>> results = sconn.search(q, 0, 30, sortby="price")
>>> prev_price = results[0].data['price']
>>> for price in (result.data['price'] for result in results):
... assert(price >= prev_price)
... prev_price = price
>>> [int(result.id, 16) for result in results]
[0, 70, 140, 1, 71, 141, 2, 72, 142, 3, 73, 143, 4, 74, 144, 5, 75, 145, 6, 76, 146, 7, 77, 147, 8, 78, 148, 9, 79, 149]
>>> [result.data['price'] for result in results]
[['0.000000'], ['0.000000'], ['0.000000'], ['0.142857'], ['0.142857'], ['0.142857'], ['0.285714'], ['0.285714'], ['0.285714'], ['0.428571'], ['0.428571'], ['0.428571'], ['0.571429'], ['0.571429'], ['0.571429'], ['0.714286'], ['0.714286'], ['0.714286'], ['0.857143'], ['0.857143'], ['0.857143'], ['1.000000'], ['1.000000'], ['1.000000'], ['1.142857'], ['1.142857'], ['1.142857'], ['1.285714'], ['1.285714'], ['1.285714']]
>>> results = sconn.search(q, 0, 30, sortby="-price")
>>> prev_price = results[0].data['price']
>>> for price in (result.data['price'] for result in results):
... assert(price <= prev_price)
... prev_price = price
>>> [int(result.id, 16) for result in results]
[69, 139, 68, 138, 67, 137, 66, 136, 65, 135, 64, 134, 63, 133, 62, 132, 61, 131, 60, 130, 59, 129, 199, 58, 128, 198, 57, 127, 197, 56]
>>> results = sconn.search(q, 0, 30, sortby="date")
>>> prev_date = results[0].data['date']
>>> for date in (result.data['date'] for result in results):
... assert(date >= prev_date)
... prev_date = date
>>> [int(result.id, 16) for result in results]
[0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 1, 13, 25, 37, 49, 61, 73, 85, 97, 109, 121, 133, 145]
>>> results = sconn.search(q, 0, 30, sortby="-date")
>>> prev_date = results[0].data['date']
>>> for date in (result.data['date'] for result in results):
... assert(date <= prev_date)
... prev_date = date
>>> [int(result.id, 16) for result in results]
[191, 179, 167, 155, 143, 131, 119, 107, 95, 83, 71, 59, 47, 35, 23, 11, 190, 178, 166, 154, 142, 130, 118, 106, 94, 82, 70, 58, 46, 34]
Get a list of the facets and tags relevant for the search
>>> results2 = sconn.search(sconn.query_all(), 0, 30, checkatleast=200,
... sortby="-date", gettags=('tag'), getfacets=True)
>>> [int(result.id, 16) for result in results2]
[191, 179, 167, 155, 143, 131, 119, 107, 95, 83, 71, 59, 47, 35, 23, 11, 190, 178, 166, 154, 142, 130, 118, 106, 94, 82, 70, 58, 46, 34]
>>> results2.get_top_tags('tag', 8)
[('0', 62), ('1', 62), ('3', 61), ('2', 60), ('4', 60), ('5', 27), ('7', 27), ('6', 26)]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=10)]
[('price3', 7), ('facet1', 5), ('facet4', 5), ('facet2', 10), ('facet9', 4), ('price', 4), ('facet8', 2), ('facet3', 17), ('category', 20), ('facet5', 40)]
>>> [(facet[0], facet[1]) for facet in results2.get_suggested_facets(maxfacets=5)]
[('price3', [((0.0, 194.30000000000001), 30), ((201.0, 395.30000000000001), 30), ((402.0, 596.29999999999995), 30), ((603.0, 797.29999999999995), 30), ((804.0, 998.29999999999995), 30), ((1005.0, 1199.3), 30), ((1206.0, 1333.3), 20)]), ('facet1', [('0', 40), ('1', 40), ('2', 40), ('3', 40), ('4', 40)]), ('facet4', [((0.0, 4.0), 40), ((5.0, 9.0), 40), ((10.0, 14.0), 40), ((15.0, 19.0), 40), ((20.0, 24.0), 40)]), ('facet2', [('0', 20), ('1', 20), ('2', 20), ('3', 20), ('4', 20), ('5', 20), ('6', 20), ('7', 20), ('8', 20), ('9', 20)]), ('facet9', [((0.0, 9.0), 50), ((10.0, 19.0), 50), ((20.0, 29.0), 50), ((30.0, 39.0), 50)])]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=5, required_facets='price3')]
[('price3', 7), ('facet1', 5), ('facet4', 5), ('facet2', 10), ('facet9', 4)]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=5, required_facets='facet8')]
[('price3', 7), ('facet1', 5), ('facet4', 5), ('facet2', 10), ('facet8', 2)]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=5, required_facets=('facet8', 'price', 'facet7'))]
[('price3', 7), ('facet1', 5), ('price', 4), ('facet8', 2), ('facet7', 4)]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=5, required_facets=('facet8', 'price', 'facet7', 'price3', 'facet1'))]
[('price3', 7), ('facet1', 5), ('price', 4), ('facet8', 2), ('facet7', 4)]
>>> [(facet[0], len(facet[1])) for facet in results2.get_suggested_facets(maxfacets=5, required_facets=('facet8', 'price', 'facet7', 'price3', 'facet1', 'facet4'))]
[('price3', 7), ('facet1', 5), ('facet4', 5), ('price', 4), ('facet8', 2), ('facet7', 4)]
We can use a facet to restrict the search results:
>>> results3 = sconn.search(sconn.query_facet('price3', (0.0, 200.0)), 0, 30,
... checkatleast=200, getfacets=True)
Check that the restriction was satisfied by all the results:
>>> False in [float(result.data['price3'][0]) <= 200 for result in results3]
False
Getting the list of facets when there is a facet restriction in place will
return a different selection (based on the documents satisfying the
restriction):
>>> [(facet[0], len(facet[1])) for facet in results3.get_suggested_facets(maxfacets=5)]
[('facet5', 6), ('facet9', 6), ('price', 5), ('price3', 4), ('facet4', 4)]
The suggestions for the facet we've already restricted by are for sub-values
within the range:
>>> results3.get_suggested_facets(maxfacets=5)[3]
('price3', [((0.0, 46.899999999999999), 8), ((53.600000000000001, 93.799999999999997), 7), ((100.5, 147.40000000000001), 8), ((154.09999999999999, 194.30000000000001), 7)])
Regression test: this used to give an error
>>> results3 = sconn.search(sconn.query_facet('facet9', (0.0, 5.0)), 0, 30,
... checkatleast=200, getfacets=True)
A facet which only contains one value in the matching documents will never be
returned as a suggestion::
>>> results3 = sconn.search(sconn.query_facet('facet5', '5'), 0, 30,
... checkatleast=200, getfacets=True,
... allowfacets=('facet5', 'facet6'))
>>> results3.matches_estimated
5
>>> results3.get_suggested_facets()
[]
Facet fields may contain multiple values in a single document, unless the type
is "float" (in which case, only the final value specified in a given document
will be stored). Therefore, we expect facet8 to _not_ include the 2000 and
2001 values, but facet7 should include them:
>>> results3 = sconn.search(sconn.query_all(), 0, 30,
... checkatleast=200, getfacets=True,
... allowfacets=('facet7', 'facet8'))
>>> results3.get_suggested_facets()
[('facet8', [((0.0, 0.0), 100), ((1.0, 1.0), 100)]), ('facet7', [('0', 100), ('1', 100), ('2000', 200), ('2001', 200)])]
Even if the database doesn't contain any facets, getting the list of suggested
facets should return an empty list (this is a regression test - this used to
raise an exception).
>>> results3 = sconn2.search(sconn2.query_all(), 0, 30,
... checkatleast=200, getfacets=True)
>>> results3.get_suggested_facets()
[]
We can also filter the results by a range of the sortable values - for
example, dates:
>>> fq = sconn.query_filter(q, sconn.query_range('date', '20070205', '20070207'))
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> [int(result.id, 16) for result in results]
[49, 61, 73]
>>> for result in results:
... print "%r,%r" % (result.data['date'], result.get_value('date', 'collsort'))
['20070205'],'20070205'
['20070206'],'20070206'
['20070207'],'20070207'
We can specify semi-infinite ranges by specifying None for one of the
endpoints:
>>> fq = sconn.query_filter(q, sconn.query_range('date', None, '20070104'))
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> for result in results:
... print "%r,%r" % (result.data['date'], result.get_value('date', 'collsort'))
['20070101'],'20070101'
['20070102'],'20070102'
['20070103'],'20070103'
['20070104'],'20070104'
>>> fq = sconn.query_filter(q, sconn.query_range('date', '20071214', None))
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> for result in results:
... print "%r,%r" % (result.data['date'], result.get_value('date', 'collsort'))
['20071214'],'20071214'
['20071215'],'20071215'
['20071216'],'20071216'
We can use a filter to exclude results which match a particular sub-query,
instead of to include only those which match.
>>> fq = sconn.query_filter(q, sconn.query_range('date', '20070105', '20071214'), exclude=True)
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> [int(result.id, 16) for result in results]
[0, 12, 24, 36, 179, 191]
>>> for result in results:
... print "%r,%r" % (result.data['date'], result.get_value('date', 'collsort'))
['20070101'],'20070101'
['20070102'],'20070102'
['20070103'],'20070103'
['20070104'],'20070104'
['20071215'],'20071215'
['20071216'],'20071216'
Or we can restrict by numerical range:
>>> fq = sconn.query_filter(q, sconn.query_range('price', '0.1428', '0.5'))
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> [int(result.id, 16) for result in results]
[72, 1, 73, 2, 3, 141, 142, 71, 143]
>>> [(result.data['price'][0]) for result in results]
['0.285714', '0.142857', '0.428571', '0.285714', '0.428571', '0.142857', '0.285714', '0.142857', '0.428571']
>>> fq = sconn.query_range('price', '0.1428', '0.5')
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> [int(result.id, 16) for result in results]
[72, 1, 73, 2, 3, 141, 142, 71, 143]
If the end of the range is lower than the start, no results can match
>>> fq = sconn.query_filter(q, sconn.query_range('price', '0.5', '0.1428'))
>>> results = sconn.search(fq, 0, 30, sortby="date")
>>> [int(result.id, 16) for result in results]
[]
We can also adjust the weights of one query using a second query:
>>> q = sconn.query_adjust(q, sconn.query_parse('cat'))
>>> str(q)
'Xapian::Query(((Zdocument:(pos=1) AND_MAYBE document:(pos=1)) AND_MAYBE (Zcat:(pos=1) AND_MAYBE cat:(pos=1))))'
If invalid values are supplied to query_range, a SearchError is raised
>>> sconn.query_range('date', '0.1428', '0.5')
Traceback (most recent call last):
...
SearchError: Value supplied to field 'date' must be a valid date: was '0.1428': error is 'Unrecognised date format'
Do a search which matches all documents:
>>> q = sconn.query_all()
>>> str(q)
'Xapian::Query()'
>>> results = sconn.search(q, 0, 30)
>>> len(results)
30
>>> results
Do a search which uses a restricted set of default fields:
>>> q = sconn.query_parse('richard', default_allow='author')
>>> str(q)
'Xapian::Query((ZXArichard:(pos=1) AND_MAYBE XArichard:(pos=1)))'
>>> q = sconn.query_parse('richard', default_deny='category')
>>> str(q)
'Xapian::Query(((ZXArichard:(pos=1) OR ZXBrichard:(pos=1) OR ZXDrichard:(pos=1)) AND_MAYBE (XArichard:(pos=1) OR XBrichard:(pos=1) OR XDrichard:(pos=1))))'
Do a search which multiplies the weights by 2:
>>> q = sconn.query_multweight(sconn.query_parse('richard', default_allow='author'), 2)
>>> str(q)
'Xapian::Query(2 * (ZXArichard:(pos=1) AND_MAYBE XArichard:(pos=1)))'
>>> q2 = sconn.query_parse('richard', default_deny='author')
>>> q = sconn.query_composite(sconn.OP_OR, (q, q2))
>>> str(q)
'Xapian::Query((2 * (ZXArichard:(pos=1) AND_MAYBE XArichard:(pos=1)) OR ((ZXBrichard:(pos=1) OR ZXDrichard:(pos=1)) AND_MAYBE (XBrichard:(pos=1) OR XDrichard:(pos=1)))))'
Do a similarity search
>>> q = sconn.query_parse('document (2 OR 5 OR 8)')
>>> results = sconn.search(q, 0, 5, sortby="date")
>>> len(results)
3
>>> ids = [result.id for result in results]
>>> len(ids)
3
>>> sconn.significant_terms(ids, maxterms=5)
[('title', '8'), ('title', '5'), ('title', '2'), ('title', 'test'), ('title', 'document')]
>>> q2 = sconn.query_similar(ids, simterms=5)
>>> str(q2)
'Xapian::Query((XB8 ELITE_SET 5 XB5 ELITE_SET 5 XB2 ELITE_SET 5 XBtest ELITE_SET 5 XBdocument))'
>>> q2 = sconn.query_similar(ids, simterms=5, allow='text')
>>> str(q2)
'Xapian::Query((XDdocument ELITE_SET 5 XDthis ELITE_SET 5 XDtest ELITE_SET 5 XDtext ELITE_SET 5 XDmore))'
Try a search with various weight cutoff restrictions:
>>> results = sconn.search(sconn.query_parse('richard OR 7 OR 7 OR 8'), 0, 5, sortby="date")
>>> [(result.id, result.percent, int(result.weight * 10)) for result in results]
[('7', 55, 326), ('8', 27, 163)]
>>> results = sconn.search(sconn.query_parse('richard OR 7 OR 7 OR 8'), 0, 5, sortby="date", percentcutoff=30)
>>> [(result.id, result.percent, int(result.weight * 10)) for result in results]
[('7', 55, 326)]
>>> results = sconn.search(sconn.query_parse('richard OR 7 OR 7 OR 8'), 0, 5, sortby="date", weightcutoff=20)
>>> [(result.id, result.percent, int(result.weight * 10)) for result in results]
[('7', 55, 326)]
>>> results = sconn.search(sconn.query_parse('richard OR 7 OR 7 OR 8'), 0, 5, sortby="date", percentcutoff=56)
>>> [(result.id, result.percent, int(result.weight * 10)) for result in results]
[]
>>> results = sconn.search(sconn.query_parse('richard OR 7 OR 7 OR 8'), 0, 5, sortby="date", weightcutoff=33)
>>> [(result.id, result.percent, int(result.weight * 10)) for result in results]
[]
Do a similarity search with an ID which isn't in the database:
>>> q2 = sconn.query_similar('foo', simterms=5)
>>> str(q2)
'Xapian::Query()'
Check the expand decider used by similarity reordering of queries.
>>> res = sconn.search(q2, 0, 5)
>>> ed = res._make_expand_decider('title')
>>> ed('foo')
False
>>> ed('XBA:foo')
False
>>> ed('XBAfoo')
False
>>> ed('XB:foo')
True
>>> ed('XBfoo')
True
>>> ed('ZXBfoo')
True
>>> ed('ZXBfoo')
True
Find the interesting terms in a set of documents:
>>> [(docid, sconn.significant_terms(docid, 3)) for docid in sconn.iterids()][:3]
[('0', [('title', '0'), ('title', 'test'), ('title', 'document')]), ('1', [('title', '1'), ('title', 'test'), ('title', 'document')]), ('10', [('title', '16'), ('title', 'test'), ('title', 'document')])]
Tidy up after ourselves:
>>> sconn.close()
Closing connection at path foo: Conn1
>>> del sconn
>>> del sconn2
>>> del result
>>> del results
>>> del results2
>>> del results3
Closing connection at path foo2: Conn2
xappy-0.5/xappy/searchconnection_doctest3.txt 0000644 0001750 0001750 00000006074 10752030064 021374 0 ustar richard richard
This file mainly contains tests for error handling conditions.
>>> from datastructures import *
>>> from fieldactions import *
>>> from indexerconnection import *
Open a connection for indexing:
>>> iconn = IndexerConnection('foo')
>>> iconn.add_field_action('title', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('text', FieldActions.STORE_CONTENT)
>>> iconn.add_field_action('text', FieldActions.INDEX_FREETEXT, language='en',
... spell=True, stop=('basic',))
>>> iconn.add_field_action('tag', FieldActions.TAG)
>>> iconn.add_field_action('tag2', FieldActions.TAG)
>>> for i in xrange(20):
... doc = UnprocessedDocument()
... doc.fields.append(Field('text', 'This is basic test document %d.' % i))
... doc.fields.append(Field('title', 'Test document %d' % i))
... id = iconn.add(doc)
Test getting and setting metadata:
>>> iconn.get_metadata('foo')
''
>>> iconn.set_metadata('foo', 'bar')
>>> iconn.get_metadata('foo')
'bar'
>>> iconn.flush()
Now, open a search connection:
>>> sconn = SearchConnection('foo')
Now, parse a simple query.
>>> q = sconn.query_parse('document')
>>> results = sconn.search(q, 0, 20)
>>> [result.id for result in results]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '10', '11', '12', '13']
>>> result = results.get_hit(0)
>>> result.summarise('text')
'This is basic test document 0.'
>>> result.summarise('title')
'Test document 0'
The maxlen (in characters) can be specified:
>>> result.summarise('text', 5)
'This..'
If it's specified as a string (eg, unconverted output from a webapp) it should
still work:
>>> result.summarise('text', '5')
'This..'
Asking for a summary of a field which isn't known will raise a KeyError.
>>> result.summarise('titl')
Traceback (most recent call last):
...
KeyError: 'titl'
Asking for a top tags of a field when no fields were specified for counting
tags will raise a SearchError.
>>> results.get_top_tags('title', 100)
Traceback (most recent call last):
...
SearchError: Field 'title' was not specified for getting tags
Asking for tags in a field which wasn't indexed for tagging will return an
error:
>>> results = sconn.search(q, 0, 20, gettags='title')
Traceback (most recent call last):
...
SearchError: Field 'title' was not indexed for tagging
Asking for top tags of a field which wasn't specified for counting tags will
raise a SearchError.
>>> results = sconn.search(q, 0, 20, gettags='tag')
>>> results.get_top_tags('tag', 100)
[]
>>> results.get_top_tags('tag2', 100)
Traceback (most recent call last):
...
SearchError: Field 'tag2' was not specified for getting tags
>>> results.get_top_tags('text', 100)
Traceback (most recent call last):
...
SearchError: Field 'text' was not specified for getting tags
Asking for suggested facets if none were calculated raises a SearchError:
>>> results.get_suggested_facets('text')
Traceback (most recent call last):
...
SearchError: Facet selection wasn't enabled when the search was run
Test getting metadata:
>>> sconn.get_metadata('foo1')
''
>>> sconn.get_metadata('foo')
'bar'
xappy-0.5/xappy.egg-info/ 0000755 0001750 0001750 00000000000 11005556727 015174 5 ustar richard richard xappy-0.5/xappy.egg-info/PKG-INFO 0000644 0001750 0001750 00000003125 11005556727 016272 0 ustar richard richard Metadata-Version: 1.0
Name: xappy
Version: 0.5
Summary: Easy-to-use interface to the Xapian search engine
Home-page: http://code.google.com/p/xappy
Author: Richard Boulton
Author-email: richard@lemurconsulting.com
License: GPL
Download-URL: http://xappy.googlecode.com/files/xappy-0.5.tar.gz
Description:
The "xappy" python module is an easy-to-use interface to the Xapian search
engine. Xapian provides a low level interface, dealing with terms and
documents, but not really worrying about where terms come from, or how to build
searches to match the way in which data has been indexed. In contrast, "xappy"
allows you to design a field structure, specifying what kind of information is
held in particular fields, and then uses this field structure to index data
appropriately, and to build and perform searches.
Xappy is not yet stable - in particular, both the API and database format will
change in future releases. If you wish to use it, we recommend that you
subscribe to the xappy-discuss mailing list (see
http://groups.google.com/group/xappy-discuss) to keep up-to-date with changes
to Xappy.
Platform: Any
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Programming Language :: C++
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft
Classifier: Operating System :: POSIX
xappy-0.5/xappy.egg-info/SOURCES.txt 0000644 0001750 0001750 00000012116 11005556727 017061 0 ustar richard richard AUTHORS
COPYING_GPL
ChangeLog
MANIFEST.in
README
build.py
eggsetup.py
setup.py
docs/introduction.html
docs/introduction.rst
docs/running_perftest.txt
docs/api/api-objects.txt
docs/api/class-tree.html
docs/api/crarr.png
docs/api/epydoc.css
docs/api/epydoc.js
docs/api/frames.html
docs/api/help.html
docs/api/identifier-index.html
docs/api/index.html
docs/api/module-tree.html
docs/api/redirect.html
docs/api/toc-everything.html
docs/api/toc-xappy-module.html
docs/api/toc-xappy._checkxapian-module.html
docs/api/toc-xappy.datastructures-module.html
docs/api/toc-xappy.errors-module.html
docs/api/toc-xappy.fieldactions-module.html
docs/api/toc-xappy.fieldmappings-module.html
docs/api/toc-xappy.highlight-module.html
docs/api/toc-xappy.indexerconnection-module.html
docs/api/toc-xappy.marshall-module.html
docs/api/toc-xappy.memutils-module.html
docs/api/toc-xappy.parsedate-module.html
docs/api/toc-xappy.replaylog-module.html
docs/api/toc-xappy.schema-module.html
docs/api/toc-xappy.searchconnection-module.html
docs/api/toc.html
docs/api/xappy-module.html
docs/api/xappy-pysrc.html
docs/api/xappy._checkxapian-module.html
docs/api/xappy._checkxapian-pysrc.html
docs/api/xappy.datastructures-module.html
docs/api/xappy.datastructures-pysrc.html
docs/api/xappy.datastructures.Field-class.html
docs/api/xappy.datastructures.ProcessedDocument-class.html
docs/api/xappy.datastructures.UnprocessedDocument-class.html
docs/api/xappy.errors-module.html
docs/api/xappy.errors-pysrc.html
docs/api/xappy.errors.IndexerError-class.html
docs/api/xappy.errors.SearchEngineError-class.html
docs/api/xappy.errors.SearchError-class.html
docs/api/xappy.errors.XapianError-class.html
docs/api/xappy.fieldactions-module.html
docs/api/xappy.fieldactions-pysrc.html
docs/api/xappy.fieldactions.ActionContext-class.html
docs/api/xappy.fieldactions.FieldActions-class.html
docs/api/xappy.fieldactions.SortableMarshaller-class.html
docs/api/xappy.fieldmappings-module.html
docs/api/xappy.fieldmappings-pysrc.html
docs/api/xappy.fieldmappings.FieldMappings-class.html
docs/api/xappy.highlight-module.html
docs/api/xappy.highlight-pysrc.html
docs/api/xappy.highlight.Highlighter-class.html
docs/api/xappy.indexerconnection-module.html
docs/api/xappy.indexerconnection-pysrc.html
docs/api/xappy.indexerconnection.FacetQueryTypeIter-class.html
docs/api/xappy.indexerconnection.IndexerConnection-class.html
docs/api/xappy.indexerconnection.PrefixedTermIter-class.html
docs/api/xappy.indexerconnection.SynonymIter-class.html
docs/api/xappy.marshall-module.html
docs/api/xappy.marshall-pysrc.html
docs/api/xappy.memutils-module.html
docs/api/xappy.memutils-pysrc.html
docs/api/xappy.parsedate-module.html
docs/api/xappy.parsedate-pysrc.html
docs/api/xappy.replaylog-module.html
docs/api/xappy.replaylog-pysrc.html
docs/api/xappy.replaylog.LoggedProxy-class.html
docs/api/xappy.replaylog.LoggedProxyMethod-class.html
docs/api/xappy.replaylog.NotifyingDeleteObject-class.html
docs/api/xappy.replaylog.ReplayLog-class.html
docs/api/xappy.schema-module.html
docs/api/xappy.schema-pysrc.html
docs/api/xappy.schema.Schema-class.html
docs/api/xappy.searchconnection-module.html
docs/api/xappy.searchconnection-pysrc.html
docs/api/xappy.searchconnection.SearchConnection-class.html
docs/api/xappy.searchconnection.SearchConnection.ExpandDecider-class.html
docs/api/xappy.searchconnection.SearchResult-class.html
docs/api/xappy.searchconnection.SearchResultIter-class.html
docs/api/xappy.searchconnection.SearchResults-class.html
examples/fileindex.py
examples/search.py
libs/get_xapian.py
perftest/analyse_indexlogs.py
perftest/analyse_searchlogs.py
perftest/gen_queries.py
perftest/indexer.py
perftest/parseargs.py
perftest/perftest.py
perftest/searcher.py
perftest/setuppaths.py
perftest/parse_wikipedia/Errors.py
perftest/parse_wikipedia/HTMLUtils.py
perftest/parse_wikipedia/XMLUtils.py
perftest/parse_wikipedia/wiki2dump.py
secore/__init__.py
secore/datastructures.py
secore/errors.py
secore/fieldactions.py
secore/fieldmappings.py
secore/highlight.py
secore/indexerconnection.py
secore/marshall.py
secore/parsedate.py
secore/searchconnection.py
testdata/query_sourcewords.txt
testsuite/coverage.py
testsuite/runtests.py
testsuite/unittests/facet_hierarchy_1.py
testsuite/unittests/facet_query_type_1.py
testsuite/unittests/freetext_1.py
testsuite/unittests/spell_correct_1.py
utils/make_xappy_tarballs
xappy/__init__.py
xappy/_checkxapian.py
xappy/datastructures.py
xappy/datastructures_doctest1.txt
xappy/errors.py
xappy/errors_doctest1.txt
xappy/fieldactions.py
xappy/fieldmappings.py
xappy/fieldmappings_doctest1.txt
xappy/highlight.py
xappy/highlight_doctest1.txt
xappy/indexerconnection.py
xappy/indexerconnection_doctest1.txt
xappy/indexerconnection_doctest2.txt
xappy/indexerconnection_doctest3.txt
xappy/marshall.py
xappy/marshall_doctest1.txt
xappy/marshall_doctest2.txt
xappy/memutils.py
xappy/parsedate.py
xappy/parsedate_doctest1.txt
xappy/replaylog.py
xappy/schema.py
xappy/searchconnection.py
xappy/searchconnection_doctest1.txt
xappy/searchconnection_doctest2.txt
xappy/searchconnection_doctest3.txt
xappy.egg-info/PKG-INFO
xappy.egg-info/SOURCES.txt
xappy.egg-info/dependency_links.txt
xappy.egg-info/top_level.txt xappy-0.5/xappy.egg-info/dependency_links.txt 0000644 0001750 0001750 00000000001 11005556727 021242 0 ustar richard richard
xappy-0.5/xappy.egg-info/top_level.txt 0000644 0001750 0001750 00000000006 11005556727 017722 0 ustar richard richard xappy
xappy-0.5/AUTHORS 0000644 0001750 0001750 00000002751 10770032527 013411 0 ustar richard richard Authors
=======
The Xappy module and accompanying documentation and testsuite (excluding
coverage.py) is Copyright (C) 2007 Lemur Consulting Ltd. It is released under
the GPL license; see the file COPYING_GPL in this directory for details.
Major code and design
---------------------
Richard Boulton (lead developer)
Tom Mortimer (highlighting and summarisation)
Tom Winch (facet heirarchy)
Thanks are due to MyDeco (http://mydeco.com/) who have supported much of the
development of Xappy.
Bug reports and comments
------------------------
Thanks are due to the following individuals for helpful comments, bug reports
and small patches:
Bruno Rezende
Third party code
----------------
The coverage.py file in the testsuite is Copyright 2001 Gareth Rees and
Copyright 2004-2006 Ned Batchelder. See the end of that file for details of
its licensing.
Sample data
-----------
The "testdata/query_sourcewords.txt" file contains a copy of
/usr/share/dict/words from the "dictionaries-common" package in a
Debian installation:
Copyright (C) 1999-2003 Rafael Laboissiere
Copyright (C) 2001-2004 Agustín Martín Domingo
Copyright (C) 2003-2004 René Engelhard
dictionaries-common is released under the terms of the GNU GPL, version 2,
or at your option, any later version. (see /usr/share/common-licenses/GPL).
"testdata/query_sourcewords.txt" also contains a copy of the text of John
Milton's "Paradise Lost", taken from Project Gutenberg.
xappy-0.5/COPYING_GPL 0000644 0001750 0001750 00000043103 10667526240 014077 0 ustar richard richard GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
xappy-0.5/ChangeLog 0000644 0001750 0001750 00000124574 11005555653 014125 0 ustar richard richard Tue Apr 29 08:25:59 GMT 2008 Richard Boulton
* MANIFEST.in,setup.py: Update setup.py and MANIFEST ready for 0.5
release.
Tue Apr 29 07:58:10 GMT 2008 Richard Boulton
* libs/get_xapian.py,utils/make_xappy_tarballs: Update scripts to
get custom version of xapian to latest version.
Mon Apr 28 23:25:46 GMT 2008 Richard Boulton
* xappy/: Add check that xapian is at at least version 1.0.6; raise
ImportError at import time if version is too old. Add checks for
a version of xapian with sufficient features to support tags and
facets, and disable those features if they're not present: an
exception will be raised when tag or facet features are used if
the xapian version is too old.
Fri Apr 25 12:23:09 GMT 2008 Richard Boulton
* testsuite/runtests.py: Copy fixes from xapian_1.0 branch to make
the testsuite pass on windows.
Thu Apr 17 23:07:35 GMT 2008 Richard Boulton
* testsuite/unittests/freetext_1.py: New unit test for the
search_by_default and allow_field_specific fields.
Thu Apr 17 22:04:34 GMT 2008 Richard Boulton
* docs/introduction.rst,xappy/fieldactions.py,
xappy/searchconnection.py: Add allow_field_specific and
search_by_default flags to INDEX_FREETEXT action.
Sat Mar 29 16:59:23 GMT 2008 Richard Boulton
* xappy/searchconnection.py: Fix some "foo if bar" constructions
which broken python2.4. Should now work with python 2.4 again.
Wed Mar 26 08:14:27 GMT 2008 Richard Boulton
* xappy/fieldactions.py: Tidy up the imports in this file, too.
Wed Mar 26 07:52:47 GMT 2008 Richard Boulton
* xappy/__init__.py,xappy/datastructures.py,
xappy/indexerconnection.py: Remove several "import *" lines from
__init__.py, replacing them by importing the specific symbols
desired. Remove the nasty renaming of imported symbols in the
files thus imported, since this was to work around polluting the
namespace when "import *" was used.
Tue Mar 25 12:46:33 GMT 2008 Richard Boulton
* testsuite/unittests/facet_query_type_1.py,xappy/indexerconnection.py,
xappy/searchconnection.py: More facet selection improvements from
Tom Winch: allow a set of associations between query types and
facets to be stored in the database configuration, and use these
facets to either prevent or prefer certain facets from being
chosen for a particular query type. (Query types are specified
by an additional parameter to the search() method.)
Wed Mar 19 01:42:29 GMT 2008 Richard Boulton
* xappy/indexerconnection.py,xappy/searchconnection.py: Remove
backwards compatibility support for reading fieldactions from a
file. It just makes the code more complex, and xappy really
needs to use a more recent version of xapian.
Tue Mar 18 21:34:29 GMT 2008 Richard Boulton
* AUTHORS: Add Tom Winch.
Tue Mar 18 21:29:25 GMT 2008 Richard Boulton
* testsuite/unittests/facet_hierarchy_1.py,xappy/indexerconnection.py,
xappy/searchconnection.py: Add support for defining a facet
heirarchy, for use when selecting facets. Not yet used, but is
stored in the database configuration, and available to both the
indexer connection and the search connection.
Mon Mar 17 16:46:33 GMT 2008 Richard Boulton
* xappy/searchconnection.py: Fix setting of stemmer so that it
still works with replaylog enabled.
Thu Feb 21 13:12:03 GMT 2008 Richard Boulton
* libs/get_xapian.py: Update to new tarballs which actually work,
this time.
Thu Feb 21 01:54:18 GMT 2008 Richard Boulton
* libs/get_xapian.py: Revert to earlier tarballs - the new ones
don't work.
Thu Feb 21 01:50:17 GMT 2008 Richard Boulton
* libs/get_xapian.py: Update with new tarballs.
Thu Feb 21 01:23:46 GMT 2008 Richard Boulton
* utils/make_xappy_tarballs: Update the branchpoint version
numbers.
Tue Feb 05 09:59:50 GMT 2008 Richard Boulton
* libs/get_xapian.py: Upgrade version of xapian used to one which
contains database replication functionality.
Tue Feb 05 09:45:27 GMT 2008 Richard Boulton
* xappy/indexerconnection.py,xappy/searchconnection.py,
xappy/searchconnection_doctest3.txt: Add interface to
IndexerConnection for setting and getting metadata, and interface
to SearchConnection for getting metadata.
Mon Feb 04 00:58:05 GMT 2008 Richard Boulton
* xappy/searchconnection.py: Cope with a facet being declared as
SORTABLE, but without a type, but of facet type float. (Treat the
facet search as a numeric range, correctly - used to fail to
serialise the numbers correctly.)
* xappy/searchconnection_doctest2.txt: Add regression test.
Sat Feb 02 17:59:24 GMT 2008 Richard Boulton
* xappy/indexerconnection.py: Add simple work-around for synonyms -
allow a field to be specified for the original word separately
from the synonym. Needs tidying up, but allows slightly more
flexibility in synonyms.
* xappy/searchconnection_doctest2.txt: Adjust test accordingly.
Sat Feb 02 13:14:29 GMT 2008 Richard Boulton
* xappy/indexerconnection.py,xappy/searchconnection.py: Backwards
compatibility fix for reading the metadata: if the config isn't
in the metadata key, or metadata isn't supported by the version
of xapian in use, read it from the file. When writing the
config, if it can't be stored in the metadata, store it in a
file. A database can now be upgraded to use the new metadata
method simply by opening an indexerconnection on it, and then
closing it.
Sat Feb 02 12:47:33 GMT 2008 Richard Boulton
* utils/make_xappy_tarballs: Tidy up tarball making script.
Sat Feb 02 12:44:59 GMT 2008 Richard Boulton
* xappy/searchconnection.py: Add faster implementation of expand
decider, using a regexp for the prefixes.
* xappy/searchconnection_doctest2.txt: Test it.
Mon Jan 28 15:13:04 GMT 2008 Richard Boulton
* xappy/indexerconnection.py,xappy/searchconnection.py: Change the
storage of the settings from a file in the database directory to
be in a metadata. This change allow the forthcoming replication
support to copy databases without losing their settings, and
should also be helpful when we implement remote database support.
Wed Jan 23 22:27:50 GMT 2008 Richard Boulton
* libs/get_xapian.py: Even newer xapian tarball - containing more
fixes from charlie for windows.
Wed Jan 23 16:04:12 GMT 2008 Richard Boulton
* libs/get_xapian.py,utils/make_xappy_tarballs: Update xapian
tarballs - mainly to get fixes for the build system on windows.
Thu Jan 10 00:28:26 UTC 2008 Richard Boulton
* libs/get_xapian.py: Update to get latest archives.
Thu Jan 10 00:04:51 UTC 2008 Richard Boulton
* utils/make_xappy_tarballs: Update with new branchpoint.
Wed Jan 09 22:50:36 UTC 2008 Richard Boulton
* utils/make_xappy_tarballs: Update with version numbers for latest
branches.
* libs/get_xapian.py: Update with details of latest tarballs, which
include OP_VALUE_GE and OP_VALUE_LE.
* xappy/searchconnection.py: Allow None to be specified as the
begin or end or a range query - allows half ranges to be
specified.
* xappy/searchconnection_doctest2.txt: Test passing None as the end
parameters of a range query.
Wed Jan 09 22:46:31 GMT 2008 Richard Boulton
* utils/make_xappy_tarballs: Update with version numbers for latest
branches.
* libs/get_xapian.py: Update with details of latest tarballs, which
include OP_VALUE_GE and OP_VALUE_LE.
* xappy/searchconnection.py: Allow None to be specified as the
begin or end or a range query - allows half ranges to be
specified.
* xappy/searchconnection_doctest2.txt: Test passing None as the
end parameters of a range query.
Mon Jan 07 19:47:36 GMT 2008 Richard Boulton
* libs/get_xapian.py: New script (taken from flax) to download the
xapian tarballs and unpack them, ready to be built.
* libs/*.tgz: Remove the tarballs from svn - they were too big to
be kept here. They're now hosted on the googlecode download
area, which should be as reliable as the googlecode svn server.
* utils/make_xappy_tarballs: Update with new version numbers.
Mon Jan 07 16:59:22 GMT 2008 Richard Boulton
* utils/make_xappy_tarballs: Update version numbers for latest
branch updates, to build new tarballs.
Mon Dec 31 13:09:33 GMT 2007 Richard Boulton
* xappy/searchconnection.py,xappy/searchconnection_doctest1.txt:
Test opening of a database which doesn't exist, and set _index to
None in class initialiser to avoid assertion error when calling
close() from __del__() in this situation.
Mon Dec 17 09:28:01 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add _cluster method, and
_reorder_by_clusters() method.
Mon Dec 10 19:46:25 GMT 2007 Richard Boulton
* utils/make_xappy_tarballs: Update to apply the changes in the
clustering branch.
Mon Dec 10 19:45:30 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add ability to restrict the reordering
to just use specific fields, and to use approximations for the
termfreqs to speed it up.
Mon Dec 10 17:19:34 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Remove accidentally committed
debugging prints.
Mon Dec 10 17:18:34 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add (experimental)
_reorder_by_similarity() method to SearchResults.
Thu Dec 06 16:53:23 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add a "userdata" parameter to the
closehandler callback, to make writing the callbacks easier.
* xappy/searchconnection_doctest2.txt: Test the userdata parameter.
Thu Dec 06 12:27:53 GMT 2007 Richard Boulton
* xappy/highlight_doctest1.txt: Don't display the output of the
highlighter - we're just testing that it returns promptly.
Thu Dec 06 12:19:55 UTC 2007 Tom Mortimer
* xappy/highlight.py,xappy/highlight_doctest1.txt: Simplified
regexp to work around freezing problem. Less procise now but
probably good enough temporarily. Fixed test case.
Thu Dec 06 07:38:49 GMT 2007 Richard Boulton
* xappy/highlight_doctest1.txt: Add testcase of a pathological
document for highlighting - the regular expression currently
takes a ridiculously long time to process this.
Thu Dec 06 07:29:28 GMT 2007 Richard Boulton
* testsuite/runtests.py: Fix for running with debug logging.
Wed Dec 05 15:57:41 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Improve a documentation comment.
Mon Dec 03 18:01:51 GMT 2007 Richard Boulton
* xappy/searchconnection.py,xappy/searchconnection_doctest2.txt:
Add ability to set a callback on SearchConnection to be called
when the object is closed (even if this is an implicit close due
to being deleted).
Thu Nov 29 17:58:18 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Expose an API for setting the minimum
weight or percentage allowed for a result to be returned; this is
done by supplying the percentcutoff or weightcutoff parameters to
SearchConnection.search()
* xappy/searchconnection_doctest2.txt: Test the weight and
percentage cutoff parameters.
Wed Nov 28 10:18:43 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Fix returning of empty facet value,
which translates into numeric range from -inf to -inf: this is
returned when some documents do not have an entry in a numeric
range, with a count of the number of documents which matched but
didn't have a numeric facet. Just ignore this information.
Wed Nov 28 08:37:08 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Remove a typo.
Wed Nov 28 08:15:09 GMT 2007 Richard Boulton
* docs/introduction.rst,xappy/indexerconnection_doctest2.txt,
xappy/searchconnection.py,xappy/searchconnection_doctest2.txt:
Modify query parsing to ensure that exact matches are given a
higher weight than stemmed or synonym matches. Update testcases
accordingly.
Wed Nov 28 07:34:21 GMT 2007 Richard Boulton
* libs/: Update the xapian tarballs; these now include OP_SYNONYM
and use it for synonym searches, wildcards, and partial searches.
Tue Nov 27 22:39:54 GMT 2007 Richard Boulton
* utils/make_xappy_tarballs: Add script to update the xappy
tarballs from xapian SVN.
Mon Nov 26 14:51:24 GMT 2007 Richard Boulton
* testsuite/runtests.py: Call close methods on anything from xappy
which has one when cleaning up.
Mon Nov 26 14:11:46 GMT 2007 Richard Boulton
* xappy/indexerconnection_doctest1.txt: Windows doesn't give a
detail for why a DatabaseLockError can't be obtained, so make the
test case more flexible there.
Mon Nov 26 12:36:38 GMT 2007 Richard Boulton
* testsuite/runtests.py: Delete entries in the dictionary before
calling teardown; should help avoid trying to delete open files
on windows.
Sun Nov 18 15:45:26 GMT 2007 Richard Boulton
* xappy/replaylog.py: New file - allows all calls to xapian to be
logged, such that they could be replayed later for debugging.
Has rather an unpleasant implementation, but as a result has
minimal impact when not turned on - I've not been able to measure
any performance impact incurred when not logging.
* xappy/__init__.py: Expose new function "set_replay_path" used to
start logging.
* xappy/marshall.py, xappy/fieldactions.py,
xappy/datastructures.py, xappy/indexerconnection.py,
xappy/searchconnection.py: Hook into the replay logging.
Sun Nov 18 15:44:50 GMT 2007 Richard Boulton
* testsuite/runtests.py: Run without profiling by default - much
faster.
Thu Nov 15 08:38:18 GMT 2007 Richard Boulton
* testsuite/runtests.py: Allow coverage and profiling measures to
be turned on and off easily (not yet with command line options,
but now only needs a simple edit to the code).
Wed Nov 07 17:45:48 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add extra "query" parameter to
summarise() and highlight() methods, which can be used to
override the query used as the basis of the highlighting.
Wed Nov 07 17:30:02 GMT 2007 Richard Boulton
* xappy/highlight.py: Fix tests to correspond to recent change.
* xappy/searchconnection.py: Add "query_none()" to get an empty
query explicitly. Can be useful as a placeholder.
Tue Nov 06 13:54:13 UTC 2007 Tom Mortimer
* xappy/highlight.py: Highlighter works with stemmed and unstemmed
terms. Workaround until we have proper phrase highlighting
Thu Nov 01 14:43:34 UTC 2007 Richard Boulton
* libs/win32msvc.tgz: Updated build files for windows.
Wed Oct 31 19:01:03 UTC 2007 Richard Boulton
* libs/xapian-bindings-xappy.tgz: Version with a concurrency
problem fixed.
Wed Oct 31 17:57:00 UTC 2007 Richard Boulton
* libs/matchspy.cc: Version of matchspy.cc with quick workaround to
avoid segfault.
Tue Oct 30 11:12:28 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Document the members of SearchResult.
Tue Oct 30 11:02:22 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Add weight and percent members to
SearchResult objects.
Mon Oct 29 21:21:27 GMT 2007 Richard Boulton
* README: Update to tell users to use the tarballs from the libs/
subdirectory.
Mon Oct 29 21:19:01 GMT 2007 Richard Boulton
* xappy/searchconnection.py,xappy/searchconnection_doctest2.txt:
Fix setting of the prefix to use the correct form of add_prefix,
and fix the expected output of scale weight queries to use the
new style of output.
Mon Oct 29 20:19:27 GMT 2007 Richard Boulton
* libs/win32msvc.tgz,libs/xapian-bindings-xappy.tgz,
libs/xapian-core-xappy.tgz: Add tarballs containing a suitable
version of xapian to use with xappy.
Mon Oct 29 15:07:00 GMT 2007 Richard Boulton
* xappy/indexerconnection.py: Turn off the max_mem_use setting by
default, so we don't mess up performance of existing applications.
Mon Oct 29 14:59:26 GMT 2007 Richard Boulton
* xappy/indexerconnection.py: Increase estimate of amount of memory
used, based on profiling observations.
Mon Oct 29 14:14:04 GMT 2007 Richard Boulton
* testsuite/unittests/spell_correct_1.py: Add unittest
demonstrating problem with spelling correction.
Mon Oct 29 14:08:59 GMT 2007 Richard Boulton
* xappy/memutils.py: New file, which gets the total amount of
physical memory on the system (for windows and POSIX).
* xappy/indexerconnection.py: Add set_max_mem_use(), which causes
an automatic flush if more than a certain (configurable) amount
of memory is used. This should help to avoid using all the
memory for buffered changes, resulting in swapping. The estimate
of the memory used is fairly primitive, though, so could do with
improvment.
Mon Oct 29 09:30:21 GMT 2007 Richard Boulton
* xappy/searchconnection.py: Retry parse_query() attempt without
support for boolean operators if it fails in spell correct
routine, to match behaviour of query_parse() routine.
Fri Oct 12 09:52:31 BST 2007 Richard Boulton
* xappy/searchconnection.py: If allow, deny, default_deny or
default_allow are passed as empty lists, behave as if they were
passed as None.
Wed Oct 10 22:56:19 BST 2007 Richard Boulton
* xappy/searchconnection.py: Update some documentation comments.
Wed Oct 10 18:21:33 BST 2007 Richard Boulton
* xappy/searchconnection.py: Add the default_op, default_allow, and
default_deny optional parameters to spell_correct(), so that it
takes the same arguments as query_parse().
Wed Oct 10 01:25:01 BST 2007 Richard Boulton
* perftest/perftest.py: Remove facet and tags test runs - we don't
have the data needed to make them run, anyway.
Wed Oct 10 01:22:20 BST 2007 Richard Boulton
* perftest/perftest.py,perftest/searcher.py: Add use_or option to
search runs, and do an "OR" run by default.
Tue Oct 09 16:03:42 BST 2007 Richard Boulton
* xappy/searchconnection.py: Expand documentation comment to
explain the distinction between default_{allow,deny} and
{allow,deny}.
Tue Oct 09 15:36:32 BST 2007 Richard Boulton
* perftest/perftest.py: Add "--usedb" parameter - if supplied, a
ready made DB is assumed to be at that path, and no index run
will be done.
Tue Oct 09 15:10:00 BST 2007 Richard Boulton
* perftest/perftest.py: If pylab isn't available, don't call the
analyse_* functions (and don't produce pretty graphs, as a
result).
Tue Oct 09 14:55:53 BST 2007 Richard Boulton
* README,docs/introduction.rst: Update comments about the version
of Xapian which is required.
Tue Oct 09 02:14:24 BST 2007 Richard Boulton
* docs/running_perftest.txt: More instructions.
Tue Oct 09 02:05:03 BST 2007 Richard Boulton
* docs/running_perftest.txt: Add some notes on running the
performance tests, with wikipedia data.
Tue Oct 09 01:48:58 BST 2007 Richard Boulton
* perftest/perftest.py: More tidying, ready for running big tests
against wikipedia.
Tue Oct 09 01:32:43 BST 2007 Richard Boulton
* perftest/searcher.py: Tidy up headings.
Tue Oct 09 01:21:38 BST 2007 Richard Boulton
* perftest/: Sort out search side of performance tests.
Mon Oct 08 23:46:18 BST 2007 Richard Boulton
* perftest/: Tidy up, towards making automated performance tests
runnable just by running a single script. Fix graph drawing for
cases where there are few sample points.
Mon Oct 08 14:22:25 BST 2007 Richard Boulton
* AUTHORS: Add second name for Bruno Rezende.
Sun Oct 07 01:56:47 BST 2007 Richard Boulton
* xappy/searchconnection.py: Change from using OP_MULT_WEIGHT to
use OP_SCALE_WEIGHT, to work with latest version of xapian.
Sat Oct 06 01:55:34 BST 2007 Richard Boulton
* MANIFEST.in,eggsetup.py,setup.py: Basic start of distutils
packaging.
Wed Oct 03 14:00:17 BST 2007 Richard Boulton
* build.py: Don't include private variables in the output of epydoc;
this makes it more useful as an API reference.
* docs/introduction.rst: Add a note on error handling.
Wed Oct 03 13:04:01 BST 2007 Richard Boulton
* xappy/errors.py,xappy/errors_doctest1.txt: Export all the xapian
error types (eg, xapian.FooError) as xappy.XapianFooError. Also,
make them all subclasses of xappy.XapianError. This allow
a particular Xapian error to be caught using "except
xappy.XapianFooError", or all Xapian errors to be caught using
"except xappy.XapianError".
Wed Oct 03 12:36:27 BST 2007 Richard Boulton
* xappy/highlight.py,xappy/searchconnection_doctest3.txt: Fix from
Alex Bowley to coerce maxlen into an int in highlight.py
Tue Oct 02 18:31:54 BST 2007 Richard Boulton
* xappy/searchconnection.py: Minor correction to a documentation
comment.
Tue Oct 02 18:03:31 BST 2007 Richard Boulton
* xappy/searchconnection.py: Add query_adjust(), allowing the
weights of one query to be adjusted based on the results of a
second query.
* xappy/searchconnection_doctest2.txt: Add test for query_adjust()
Mon Oct 01 15:23:11 BST 2007 Richard Boulton
* xappy/searchconnection.py: Add a __len__() method for
SearchResults().
* xappy/searchconnection_doctest1.txt,
xappy/searchconnection_doctest2.txt: Test it
Mon Oct 01 14:23:22 BST 2007 Richard Boulton
* xappy/searchconnection.py: Add SearchConnection.query_multweight,
which produces a query from a subquery by multiplying the weights
by a multiplier.
* xappy/indexerconnection_doctest2.txt: Modify test of "Cannot
specify both `allow` and `deny`" to expect new extended message.
* xappy/searchconnection_doctest2.txt: Add test of a multweight
query.
Sun Sep 30 10:37:21 BST 2007 Richard Boulton
* xappy/searchconnection.py,xappy/searchconnection_doctest2.txt:
Add "required_facets" parameter to get_suggested_facets(),
allowing certain facets to be required in the list of returned
facets.
Fri Sep 28 16:12:35 BST 2007 Richard Boulton
* testsuite/coverage.py: Update copy of coverage.py to latest
version (with patches applied) to get correct results with
python2.5
Mon Sep 24 14:21:48 BST 2007 Richard Boulton
* xappy/searchconnection.py,xappy/searchconnection_doctest2.txt:
Add default_allow and default_deny parameters to query_parse.
These allow a list of field names to be specified which will be
searched by default (instead of searching all free-text fields).
Needs latest SVN version of xapian.
Sat Sep 22 09:21:13 BST 2007 Richard Boulton
* xappy/searchconnection.py: Add 'rb' to another call to open that
I missed.
Thu Sep 20 15:20:41 BST 2007 Richard Boulton
* AUTHORS: Start list of individuals who have contributed in any
way.
Tue Sep 18 13:23:15 BST 2007 Richard Boulton
* xappy/datastructures.py,xappy/indexerconnection_doctest1.txt:
Document, and test, that it's okay to use an iterator for
UnprocessedDocument.fields.
Tue Sep 18 13:05:53 BST 2007 Richard Boulton
* docs/introduction.rst: Clarify some of the documentation about
facets.
Fri Sep 07 16:51:33 BST 2007 Richard Boulton
* ChangeLog: Tidy-up whitespace.
Wed Sep 05 15:33:27 BST 2007 Richard Boulton
* examples/fileindex.py,examples/search.py,perftest/index_from_dump.py,
perftest/search_speed.py: Change all remaining references to
"secore" name, except in the compatibility wrapper and the tests
for that, to "xappy".
Wed Sep 05 15:29:22 BST 2007 Richard Boulton
* docs/introduction.rst: Change references to secore to references
to xappy.
* xappy/fieldmappings_doctest1.txt: Add test which I wrote ages
ago, but had forgotten to commit.
Wed Sep 05 15:05:57 BST 2007 Richard Boulton
* secore/,testsuite/runtests.py: Add compatibility layer so that
old scripts can run without needing to change from "secore" to
"xappy", for now. Change testsuite to run using new names (but
use the old ones too, to test the compatibility layer).
Wed Sep 05 14:24:52 BST 2007 Richard Boulton
* AUTHORS,README,build.py,secore/,xappy/__init__.py: Rename secore
to xappy. Adjust accompanying scripts and documentation
accordingly.
Wed Sep 05 02:23:46 BST 2007 Richard Boulton
* secore/searchconnection_doctest2.txt: Change expected output to
match output given by xapian SVN HEAD, once the bug in
check_at_least is resolved.
Fri Aug 17 14:41:13 BST 2007 Richard Boulton
* perftest/index_from_dump.py: Remove pointless "os.stat"
Fri Aug 17 14:38:46 BST 2007 Richard Boulton
* secore/indexerconnection.py: Add a method to get a list of the
fields which have actions defined.
Thu Aug 16 17:42:30 BST 2007 Richard Boulton
* secore/indexerconnection.py: Add a check for the database not
having been closed.
* secore/searchconnection.py: Add method for getting an iterator
over all the documents in the database. Add support for
rerunning the attempted access if get_document() catches a
DatabaseModifiedError.
* secore/searchconnection_doctest2.txt: Change
"get_significant_terms" to "significant_terms()", and test it.
Thu Aug 16 17:24:06 BST 2007 Richard Boulton
* secore/searchconnection.py,secore/searchconnection_doctest2.txt:
Add new method "get_significant_terms()" which returns the most
significant terms in the set of ids specified.
Thu Aug 16 10:22:16 BST 2007 Richard Boulton
* secore/searchconnection_doctest2.txt: Add test for supplying a
document ID to query_similar() which isn't in the database.
Thu Aug 16 09:49:09 BST 2007 Richard Boulton
* docs/introduction.rst: Add documentation for similarity search.
Thu Aug 16 09:15:44 BST 2007 Richard Boulton
* secore/searchconnection.py: Retry the expand until we don't get a
DatabaseModifiedError.
Thu Aug 16 09:06:44 BST 2007 Richard Boulton
* secore/searchconnection.py,secore/searchconnection_doctest2.txt:
Implementation of the query_similar() method, returning a query
to use to get a new set of results based on similarity.
Wed Aug 08 18:52:24 BST 2007 Richard Boulton
* secore/searchconnection.py,secore/searchconnection_doctest2.txt:
Add API for performing searches for similar documents. Currently
just works out which fields should be used for performing the
similarity comparison, but doesn't do the actual similarity
search.
Wed Aug 08 13:37:26 BST 2007 Richard Boulton
* secore/searchconnection.py: Fix up calculation of significant
digits to cope with extreme values (ie, 0), to round to the
nearest significant digit (previously, it rounded down), and to
use math.log10 instead of a loop to calculate the logarithm.
Wed Aug 08 13:21:41 BST 2007 Richard Boulton
* secore/searchconnection.py: Fix issue with new match estimate
rounding when match estimate is 0.
Wed Aug 08 03:17:37 BST 2007 Richard Boulton
* secore/searchconnection.py: Improve documentation comment.
Wed Aug 08 03:13:10 BST 2007 Richard Boulton
* secore/searchconnection.py: Add "matches_human_readable_estimate"
to search results - returns an estimate of the number of matching
documents, rounded according to how tight the upper and lower
bounds are.
Sat Aug 04 08:16:01 BST 2007 Richard Boulton
* secore/searchconnection.py: Add convenience methods for checking
if a particular field can be collapsed or sorted on.
Sat Aug 04 03:09:32 BST 2007 Richard Boulton
* docs/introduction.rst,secore/: Reorganise field structures,
allowing us to support multiple occurrences of facets of string
type for a single document. This change requires all databases
to be rebuilt. Tests updated accoringly. Also, requires latest
SVN HEAD build of xapian.
Wed Aug 01 14:45:41 BST 2007 Richard Boulton
* secore/searchconnection_doctest2.txt: Test for multiple facet
values in a single document (currently fails, due to this not
being supported correctly yet)
Wed Aug 01 14:23:24 BST 2007 Richard Boulton
* secore/searchconnection_doctest2.txt: More tests, including a
regression test for bug with facet calculation on database with
no facet fields defined.
Wed Aug 01 12:43:57 BST 2007 Richard Boulton
* secore/searchconnection_doctest2.txt: Improve test coverage.
Wed Aug 01 12:28:48 BST 2007 Richard Boulton
* secore/searchconnection.py: Fix bug when facet calculation is
requested, but no facet fields are present in the database (used
to throw an exception when the list of suggested facets was
requested in this case - now it just returns an empty list).
Tue Jul 31 08:34:49 BST 2007 Richard Boulton
* secore/indexerconnection_doctest2.txt,secore/searchconnection.py,
secore/searchconnection_doctest3.txt: Improve test coverage - in
particular, add tests of various conditions which cause errors.
Mon Jul 30 16:10:52 BST 2007 Richard Boulton
* secore/datastructures.py,secore/datastructures_doctest1.txt:
Add test for terms which are too long, and note in the code about
why this restriction exists, and how it could be removed.
Mon Jul 30 14:29:51 BST 2007 Richard Boulton
* docs/introduction.rst: Update test for displaying a facet range.
Mon Jul 30 14:29:08 BST 2007 Richard Boulton
* secore/searchconnection.py: Update documentation comment for
query_facet() method.
Mon Jul 30 12:38:25 BST 2007 Richard Boulton
* secore/searchconnection.py: Fix bug with handling of facets of
type 'float'.
Fri Jul 27 02:04:27 BST 2007 Richard Boulton
* secore/fieldactions.py,secore/searchconnection.py: Add facet
searching.
Fri Jul 27 01:13:27 BST 2007 Richard Boulton
* secore/searchconnection.py: For facet selection - don't return
facets which only have 1 or 0 values.
Thu Jul 26 17:02:33 BST 2007 Richard Boulton
* secore/datastructures.py: Warn early if a field is too long:
we might be able to replace this by hashing if necessary, but
this is better than waiting for the xapian error in this case.
Wed Jul 25 08:37:51 BST 2007 Richard Boulton
* docs/introduction.rst: Add documentation on indexing and
searching facets.
Wed Jul 25 03:06:19 BST 2007 Richard Boulton
* secore/searchconnection.py: Correct small initialisation bug.
Wed Jul 25 01:53:51 BST 2007 Richard Boulton
* secore/: Change string marshalling to use xapian's stuff; cuts
down code, uses a more compact representation, and is compatible
with the facet range calculation stuff. Update tests to cover
the facet calculation stuff in more detail (but still need more
coverage). Fix bug with converting string range to a numeric
range more than once if get_suggested_facets is called
repeatedly.
Tue Jul 24 10:32:56 BST 2007 Richard Boulton
* secore/fieldactions.py,secore/searchconnection.py,
secore/searchconnection_doctest2.txt: Add the "FACET" action, to
store facets for field search and facet selection. Still
remaining is to change the serialisation of floats to match
Xapian to make the numeric range calculation work correctly,
translate the resulting numeric ranges into a more suitable
python representation, and handle multiple values for a
particular facet being specified for a single document.
Mon Jul 23 10:59:58 BST 2007 Richard Boulton
* docs/introduction.rst,secore/searchconnection.py: Add special
value of -1 for checkatleast parameter, to check all matches, and
document it (and the general reason for setting the checkatleast
parameter when using get_top_tags()).
Mon Jul 23 10:40:22 BST 2007 Richard Boulton
* secore/: Add missing synonym stuff.
Tue Jul 17 13:42:39 BST 2007 Richard Boulton
* docs/introduction.rst,secore/fieldactions.py,
secore/searchconnection.py: Add some documentation of tags, and
fix a couple of bugs.
Tue Jul 17 13:25:10 BST 2007 Richard Boulton
* secore/fieldactions.py,secore/searchconnection.py: Add support
for tagging - as yet, undocumented, and minimally tested.
Mon Jul 16 11:32:18 BST 2007 Richard Boulton
* secore/searchconnection.py: Check for KeyError when getting a
slot number for a range restriction, too.
Mon Jul 16 11:18:36 BST 2007 Richard Boulton
* secore/searchconnection.py: Check for KeyError when accessing
list of field actions, and behave as if an empty list was found
if the field is unknown.
Fri Jul 13 16:39:50 BST 2007 Richard Boulton
* secore/searchconnection.py: Add an option to query_filter to
return only those documents which _don't_ match the filter,
instead of those which do.
* secore/searchconnection_doctest2.txt: Add a test for using a
filter with exclude=True.
Mon Jul 09 11:23:56 BST 2007 Richard Boulton
* secore/searchconnection.py: Convert supplied sequence of queries
to list, since xapian query constructor isn't happy to take an
iterator.
Fri Jul 06 16:38:11 BST 2007 Richard Boulton
* secore/indexerconnection.py: Fix bug in replace() causing the
document data not to be stored.
Wed Jul 04 17:24:40 BST 2007 Richard Boulton
* docs/introduction.rst,perftest/index_from_dump.py,secore/:
Change all occurrences of unique_id to just "id" - no need to say
the unique bit, so it's just wasted typing.
Mon Jul 02 09:08:39 BST 2007 Richard Boulton
* secore/searchconnection.py: If a search connection is opened
before the fieldmappings file has been created, give it an empty
FieldMappings object. Also, fix a bug in handling of
checkatleast.
Sun Jul 01 18:13:34 BST 2007 Richard Boulton
* secore/searchconnection.py: Add query_all(), to make a search
matching all documents in the database.
Fri Jun 29 09:36:49 BST 2007 Richard Boulton
* secore/searchconnection.py: Encode correctly spelt queries in UTF8,
for consistency with output of Xapian.
* secore/searchconnection_doctest2.txt: Test spelling correction
with unicode strings.
Fri Jun 29 09:00:14 BST 2007 Richard Boulton
* secore/indexerconnection_doctest3.txt,
secore/searchconnection_doctest2.txt: Improve test coverage.
Fri Jun 29 08:47:34 BST 2007 Richard Boulton
* docs/introduction.rst,secore/: Finally, properly implement and
document the spelling correction support.
Thu Jun 28 23:33:06 BST 2007 Richard Boulton
* docs/introduction.rst: Fix documentation of parameters to
INDEX_FREETEXT, and adjust an example to give expected output
after recent fix to highlighting.
* secore/fieldactions.py: Add an option allowing indexing without
positional information, and an option allowing indexing with
spelling correction.
* secore/highlight.py,secore/searchconnection_doctest1.txt: Update
output of examples to match recent fix to highlighting.
Thu Jun 28 15:26:36 BST 2007 Tom Mortimer
* secore/fieldactions.py: Add stopwording, and an option not to
store prefixed terms, to freetext indexing.
* secore/highlight.py: Fix a bug causing the requested maxlength to
be exceeded if the derived blocks were too big.
Fri Jun 08 15:37:21 BST 2007 Richard Boulton
* AUTHORS,testdata/query_sourcewords.txt: Add source words for
generating queries to test with, and list the copyright holders
in AUTHORS.
* perftest/: Add some routines for performing performance tests,
and analysing the logs of these tests.
* perftest/parse_wikipedia/: Add some routines which convert XML
dumps of wikipedia data into scriptindex compatible forms.
Fri Jun 08 11:58:54 BST 2007 Richard Boulton
* Initial import into code.google.com repository.
Wed May 16 20:03:02 BST 2007 Richard Boulton
* Remove textprocessor.py in favour of using the new TermGenerator
stuff in Xapian 1.0.0. Implement sorting by date or floating
point. Add query_range() method for searching all documents in a
given range.
Wed May 16 15:44:18 BST 2007 Richard Boulton
* README: Add a note on the name, and list docutils as a
dependency.
Wed May 16 10:27:22 BST 2007 Richard Boulton
* secore/indexerconnection.py: Add get_document() method, to get a
document given it's unique ID.
Fri Apr 27 18:34:25 BST 2007 Richard Boulton
* README: Adjust some paths.
Fri Apr 27 18:22:19 BST 2007 Richard Boulton