Parsers create objects that can be manipulated and rendered into the final webpage.
Modules in this package:
| feeds | |
| posts | |
| static | |
| staticrst | |
| tags |
The string representation of a class’s name.
For example if we define the class Foo, the full name of the class is firmant.utils.Foo. class_name() will return this as a string.
>>> class Foo(object): pass
...
>>> class_name(Foo)
'firmant.utils.Foo'
If an object that is not a class is passed to class_name(), then a TypeError will be raised.
>>> class_name('Foo')
Traceback (most recent call last):
TypeError: `cls` does not name a type.
Catch and log exceptions of func.
Returns True if the function succeeds without throwing an exception.
message will be written to log if an exception is thrown, and False is returned. If save_trackback is true, the traceback will be saved to a temporary file.
In the normal case, the func will be called and True will be returned.
>>> def wont_raise_error():
... print 'Success!'
>>> log_uncaught_exceptions(wont_raise_error, log, 'error!')
Success!
True
When func raises an error, the error will be caught, and message will be written to log as an error.
>>> def raises_error():
... raise RuntimeError('Intentionally thrown')
>>> log_uncaught_exceptions(raises_error, log, 'error!')
Called log.error('error!')
Called log.info('traceback not saved')
False
If save_traceback is True, then a temporary file created with tempfile.mkstemp will be used to store the traceback.
>>> log_uncaught_exceptions(raises_error, log, 'error!', True)
Called log.error('error!')
Called mkstemp(prefix='firmant', text=True)
Called log.error('...traceback saved to /...')
False
If an exception is thrown while saving to the file, it will warn about the potential for infinite recursion and stop:
>>> log_uncaught_exceptions(raises_error, log, 'error!', True)
Called log.error('error!')
Called mkstemp(prefix='firmant', text=True)
Called log.error("it's turtles all the way down")
False
Set up & run a Publisher for custom programmatic use. Return the encoded string output and the Publisher object.
Applications should not need to call this function directly. If it does seem to be necessary to call this function directly, please write to the Docutils-develop mailing list <http://docutils.sf.net/docs/user/mailing-lists.html#docutils-develop>.
Parameters:
Bases: object
A parsed object that represents the structures on disk in a form that is suitable for writing.
The constructor will accept keyword arguments to automatically fill slots.
>>> class SampleObject(ParsedObject):
... __slots__ = ['someattr']
... _attributes = property(lambda s: {'someattr': s.someattr})
...
>>> SampleObject(someattr='value').someattr
'value'
>>> SampleObject(permalink='http://').permalink
'http://'
It is an error to provide arguments that are not in the slots of the class (or its base classes).
>>> SampleObject(notinslots=True)
Traceback (most recent call last):
AttributeError: Excess attributes: 'notinslots'
Bases: firmant.chunks.AbstractChunk
The base class of all chunks.
This class defines an abstract base class that all parsers are required to adhere to. To use this class in the creation of a parser, create a subclass with all necessary methods and properties overwritten.
See also
To create a new type of parser, inherit from Parser:
>>> class SampleParser(Parser):
... type = 'objs'
... paths = '^numbers/[0-9]$'
... cls = ParsedObject
... def parse(self, environment, objects, path):
... objects[self.type].append(str(path))
... def attributes(self, environment, path):
... return {'path': path}
... def root(self, environment):
... return 'testdata/pristine/sample'
The new parser meets the criteria for two different abstract base classes:
>>> import firmant.chunks
>>> issubclass(SampleParser, firmant.chunks.AbstractChunk)
True
>>> issubclass(SampleParser, Parser)
True
Warning
When creating a parser, do not store state in the parser itself. While it appears that a parser is a single object, it will actually share state across two or more chunks during typical usage.
If it is necessary to store state, place it in environment keyed to the parser class:
>>> environment[SampleParser] = 'stored state goes here'
This is because of the split between path selection and parsing.
The remainder of this section is devoted to describing the implementation details of Parser‘s template methods.
Chunks are passed environment and object dictionaries. While it is not technically a chunk, the Parser interface follows the same pattern. When called with an environment and set of objects, a parser will return one more chunk (in addition to the environment and object dictionaries).
>>> environment = {'log': logger
... }
>>> objects = {}
>>> sp = SampleParser(environment, objects)
>>> sp.scheduling_order
10
>>> pprint(sp(environment, objects))
({'log': <logging.Logger instance at 0x...>},
{},
[<firmant.parsers.SampleParser object at 0x...>])
Note
The chunks returned do not share any state with the Parser that created them. The fact that the class name is the same is an implementation detail that may change in the future.
The first chunk performs all parsing. In the future, parsing may be broken into more fine-grained steps. Right now, this is unnecessary.
>>> environment, objects, (parse,) = sp(environment, objects)
>>> parse.scheduling_order
200
>>> pprint(parse(environment, objects))
({'log': <logging.Logger instance at 0x...>},
{'objs': ['numbers/1', 'numbers/2', 'numbers/3']},
[])
Parse the object at path.
Any new objects that are created during the parsing of the object at path should be added directly to the objects dictionary (this includes the parsed object itself).
Determine which paths should be parsed.
This is a regular expression that will be used to match pathnames relative to root().
The following scheduling orders apply to parsers:
The type of the primary object to be parsed (e.g. posts).
Parsed objects will be added to the objects dictionary under this key.
This value has no impact on secondary objects that are generated (e.g. objects that are created from embedded LaTeX equations).
A facade encapsulating the high-level logic of a Docutils system.
Set and return default settings (overrides in defaults dict).
Set components first (self.set_reader & self.set_writer). Explicitly setting self.settings disables command line option processing from self.publish().
Pass an empty list to argv to avoid reading sys.argv (the default).
Set components first (self.set_reader & self.set_writer).
Bases: abc.ABCMeta
A metaclass for dealing with RstParsedObject.
This class prvoides the magic that allows the document tree to be mutated and have the attributes of a RstParsedObject update.
Bases: firmant.parsers.ParsedObject
The base class of all objects parsed from reSt documents.
Bases: firmant.parsers.Parser
A parser containing common functionality for parsing reStructuredTest.
Determine which paths should be parsed.
This is a regular expression that will be used to match pathnames relative to root().
The main method to override when creating new reStructuredText parsers.
The pieces dictionary contains the following keys:
The following scheduling orders apply to parsers:
The type of the primary object to be parsed (e.g. posts).
Parsed objects will be added to the objects dictionary under this key.
This value has no impact on secondary objects that are generated (e.g. objects that are created from embedded LaTeX equations).