====== Page ======

The page object represents the data that should be shown as one page. This data does not necessarily has to be one data object. It is the responsibility of the [[repository|repository object]] to map data objects to page objects. In the most simple case the data objects are files and each page corresponds to a file. In a more complex case the data object might for example be a table in a database while the page object represents only a selection from the data in the table.

By default pages of class Zim::Page::Text can contain a source (which is handled with IO objects) and a [[formats|formatter]]. These are both initialized by the repository object when creating the page object. Other interfaces are possible but these need to be supported by a widget in the GUI.

A page object that for example uses a DBI interface to represent a table might have neither source or formatter. For such a page subclass the GUI needs a custom view that can use the DBI interface; most likely this would be a table view.

Since it is possible that a similar table view could be used with the IO interface (think csv files etc.) we get several possible combinations of interfaces. Therefor page objects can tell the GUI which interfaces they support. The default interface is "formatted" which is supported by the hypertext page view. Other interfaces that might be implemented in the future could be "source", "table" and "diagram".

===== Page Names =====
* Page names can only contain alpha-numeric charcters and the following chars: "''.''", "''-''", "''_''", "''(''" and "'')''".
* The underscore "_" is used as a substitute
* The colon "'':''" is used as the namespace separator and is not part of the name itself.
* The first character of any part of the name (that is the character directly after a "'':''") can only be alpha-numeric.
* The last character of any part can not be a underscore.
* Utf8 letters and numbers are allowed with page names

=== Rationale ===
* This set of allowed characters is expected to be portable in the sense that they are allowed as part of a filename is almost any filesystem.
* White-space is not allowed because so it can be used as a separator between page names.
* A non-letter character at the begin of the name is reserved for special uses.
* The ":" was choosen as the separator so the "/" can be reserved for file names and can be used to distinguise between files and pages.

Note that utf8 characters in the page name are simply passed to the filesystem. If your filesystem can not handle utf8 this migh be a problem.

When dealing with user input page names are converted to a valid form by changing all invalid characters into underscores and removing leading non-letter characters. Since a white space is a very common invalid character some parts of the interface show whitespace instead of underscores. Effectively all forbidden characters are rendered as whitespace in the GUI. For this reason trailing underscores or trailing forbidden characters are also forbidden, they would result in a trailing whitespace that is part of the name.

===== Random: =====
* When talking about the DBI interface it is not intended that the raw dbi object is exposed to the gui. Rather the page object would have methods to update and insert records that use this dbi object. If the actual SQL queries are done from the page object it can more easily be subclassed. In the IO interface a raw IO object is exposed, but not the filename (after all we might be using IO::Scalar).

* When it is the //repository// that uses DBI, you're still going to want to use the IO interface for pages, in this case IO::Scalar comes in handy

* Complete model-view support where the page is the model would call for a TextBuffer interface that directly manipulates the parsetree instead of doing load/save requests. This would be nice but will turn out to be rather complicated.

* One could think of the interfaces as parent classes (while allowing for multiple-inheritance). The implementation differs a bit because this would leave these parent classes empty. Also the current implementation allows for a more dynamic calculation of the interfaces supported based on the actual data (instead of based on the class).
