diff --git a/docs/extending-jrnl.md b/docs/extending-jrnl.md index dc37f57f..494bd0ce 100644 --- a/docs/extending-jrnl.md +++ b/docs/extending-jrnl.md @@ -8,33 +8,33 @@ jrnl can be extended with custom importers and exporters. Note that custom importers and exporters can be given the same name as a built-in importer or exporter to override it. -Custom Importers and Exporters can traditional Python packages, and are -installed simply by installing them so they are available to the Python -intrepreter that is running jrnl. +Custom Importers and Exporters are traditional Python packages, and are +installed (into jrnl) simply by installing them so they are available to the +Python interpreter that is running jrnl. ## Entry Class Both the Importers and the Exporters work on the `Entry` class. Below is a -(selective) desciption of the class, it's properties and functions: +(selective) description of the class, it's properties and functions: - **Entry** (class) at `jrnl.Entry.Entry`. - - **title** (string): a single line that represents a entry's title. - - **date** (datetime.datetime): the date and time asigned to an entry. - - **body** (string): the main body of the entry. Can be basically any - length. *jrnl* assumes no particular structure here. - - **starred** (boolean): is an entry starred? Presumably, starred entries - are of partiulcar importance. - - **tags** (list of strings): the tags attached to an entry. Each tag - includes the pre-facing "tag symbol". - - **__init__(journal, date=None, text="", starred=False)**: contructor - method - - **jounral** (*jrnl.Journal.Journal*): a link to an existing Jounral - class. Mainly used to access it's configuration. - - **date** (datetime.datetime) - - **text** (string): assumed to include both the title and the body. When - the title, body, or tags of an entry are requested, this text will the - parsed to determine the tree. - - **starred** (boolean) + - **title** (string): a single line that represents a entry's title. + - **date** (datetime.datetime): the date and time assigned to an entry. + - **body** (string): the main body of the entry. Can be basically any + length. *jrnl* assumes no particular structure here. + - **starred** (boolean): is an entry starred? Presumably, starred entries + are of particular importance. + - **tags** (list of strings): the tags attached to an entry. Each tag + includes the pre-facing "tag symbol". + - **\_\_init\_\_(journal, date=None, text="", starred=False)**: contractor + method + - **journal** (*jrnl.Journal.Journal*): a link to an existing Journal + class. Mainly used to access it's configuration. + - **date** (datetime.datetime) + - **text** (string): assumed to include both the title and the body. + When the title, body, or tags of an entry are requested, this text + will the parsed to determine the tree. + - **starred** (boolean) Entries also have "advanced" metadata if they are using the DayOne backend, but we'll ignore that for the purposes of this demo. @@ -50,21 +50,18 @@ nicely formated JSON file: ~~~ python # pelican\contrib\importer\json_importer.py +import sys + +from jrnl import Entry +from jrnl.plugins.base import BaseImporter + +__version__ = "1.0.0" class Importer: """JSON Importer for jrnl.""" - import sys - - from jrnl import Entry - - names = ["json"] - version = "1.0.0" - - @classmethod - def class_path(cls): - return cls.__module__ + version = __version__ @staticmethod def import_(journal, input=None) @@ -91,11 +88,11 @@ class Importer: raw = json_entry["title"] + "/n" + json_entry["body"] date = json_entry["date"] entry = Entry.Entry(self, date, raw) - jounral.entries.append(entry) + journal.entries.append(entry) new_cnt = len(journal.entries) print( - "[{} imported to {} journal]".format( + "[{} entries imported to '{}' journal]".format( new_cnt - old_cnt, journal.name ), file=sys.stderr, @@ -107,21 +104,22 @@ try to import all possible entry metadata. Some implementation notes: -- The importer class must be named **Importer**. +- The importer class must be named **Importer**, and should sub-class + **jrnl.plugins.base.BaseImporter**. - The importer module must be within the **jrnl.contrib.importer** namespace. -- The importer must not any `__init__.py` files in the base directories. +- The importer must not have any `__init__.py` files in the base directories. - The importer must be installed as a Python package available to the same - Python intrepretor running jrnl. + Python interpreter running jrnl. - The importer must expose at least the following the following members: - - **version** (string): the version of the plugin. Displayed to help user - debug their installations. - - **names** (list of strings): these are the "names" that can be passed to - the CLI to invole your importer. If you specify one used by a built-in - plugin, it will overwrite it (effectively making the built-in one - unavailable). - - **import_(journal, input=None)**: the actual importer. Must append entries - to the jounral passed to it. It is recommended to accept either a filename - or standard input as a source. + - **version** (string): the version of the plugin. Displayed to help the + user debug their installations. + - **names** (list of strings): these are the "names" that can be passed to + the CLI to invole your importer. If you specify one used by a built-in + plugin, it will overwrite it (effectively making the built-in one + unavailable). + - **import_(journal, input=None)**: the actual importer. Must append + entries to the journal passed to it. It is recommended to accept either a + filename or standard input as a source. ## Custom Exporter @@ -135,18 +133,21 @@ included in jrnl and so this (if installed) would override the built in exporter. ~~~ python -# pelican\contrib\importer\custom_json_exporter.py +# pelican\contrib\exporter\custom_json_exporter.py import json -from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter +from jrnl.plugins.base import BaseExporter -class Exporter(TextExporter): +__version__ = "1.0.0" + +class Exporter(BaseExporter): """ This basic Exporter can convert entries and journals into JSON. """ names = ["json"] extension = "json" + version = __version__ @classmethod def entry_to_dict(cls, entry): @@ -178,23 +179,29 @@ export all entry metadata. Some implementation notes: -- the exporter class must be named **Exporter**. +- the exporter class must be named **Exporter** and should sub-class + **jrnl.plugins.base.BaseExporter**. - the exporter module must be within the **jrnl.contrib.exporter** namespace. -- The exporter must not any `__init__.py` files in the base directories. +- The exporter must not have any `__init__.py` files in the base directories. - The exporter must be installed as a Python package available to the same - Python intrepretor running jrnl. + Python interpreter running jrnl. - the exporter should expose at least the following the following members (there are a few more you will need to define if you don't subclass `jrnl.plugins.exporter.text_exporter`): - - **version** (string): the version of the plugin. Displayed to help user - debug their installations. - - **names** (list of strings): these are the "names" that can be passed to - the CLI to invole your exporter. If you specific one used by a built-in - plugin, it will overwrite it (effectively making the built-in one - unavailable). - - **extension** (string): the file extention used on exported entries. - - **class_path()**: returns the module of the exporter. - - **export_entry(entry)**: given an entry, returns a string of the formatted, - exported entry. - - **export_journal(journal)**: given a journal, returns a string of the - formatted, exported entries of the journal. + - **version** (string): the version of the plugin. Displayed to help the + user debug their installations. + - **names** (list of strings): these are the "names" that can be passed to + the CLI to invole your exporter. If you specific one used by a built-in + plugin, it will overwrite it (effectively making the built-in one + unavailable). + - **extension** (string): the file extention used on exported entries. + - **export_entry(entry)**: given an entry, returns a string of the formatted, + exported entry. + - **export_journal(journal)**: given a journal, returns a string of the + formatted, exported entries of the journal. + +## Development Tips + +- editable installs (`pip install -e ...`) don't seem to play nice with + the namespace layout. If your plugin isn't appearing, try a non-editable + install of both jrnl and your plugin.