# HG changeset patch # User Paul Boddie # Date 1555450674 -7200 # Node ID 0613eeb78609200b48ff69838b23def30953ed10 # Parent 15d155fac3450ea649a0fa02daf9d8d339e232b2# Parent 55a7e02c39aed2e7fcb85ba05b5c1d4c9e790dfe Merged changes from the default branch. diff -r 15d155fac345 -r 0613eeb78609 README.txt --- a/README.txt Sun Apr 14 00:29:40 2019 +0200 +++ b/README.txt Tue Apr 16 23:37:54 2019 +0200 @@ -12,8 +12,9 @@ format to other formats. For example, the supplied documentation can be converted as follows: -./moinconvert --all --input-dir docs/wiki --format html \ - --output-dir docs/html --macros --document-index index.html +./moinconvert --input-dir docs/wiki --output-dir docs/html \ + --document-index index.html \ + --macros --all This converts all documents in the indicated input directory to HTML format, storing the converted documents in the indicated output directory, evaluating @@ -32,11 +33,20 @@ See the bundled documentation for more details of the software and how it can be used: - * docs/wiki/FrontPage (and accompanying files) are the documentation files in + * docs/wiki/MoinLight (and accompanying files) are the documentation files in Moin format - * docs/html/index.html is the front page of the documentation converted to HTML - format + * docs/html/index.html is the front page of the documentation converted to + HTML format + +A more convenient way of generating the documentation is to use the following +command: + +docs/tools/make_docs.sh + +For Web server deployment, add the --web option for cleaner links: + +docs/tools/make_docs.sh --web Test Suite ========== diff -r 15d155fac345 -r 0613eeb78609 docs/tools/make_docs.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/tools/make_docs.sh Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,34 @@ +#!/bin/sh + +THISDIR=`dirname "$0"` +INDIR="$THISDIR/../wiki" +OUTDIR="$THISDIR/../html" + +ROOT="MoinLight" + +MAPPING=' +--mapping WikiPedia https://en.wikipedia.org/wiki/ +--mapping MoinMoin https://moinmo.in/ +' + +THEME='--theme mercurial' + +if [ "$1" = '--web' ] ; then + DOCINDEX= + shift 1 +else + DOCINDEX='--document-index index.html' +fi + +FILENAMES=${*:-'--all'} + +moinconvert --input-dir "$INDIR" \ + --input-page-sep '--' \ + --output-dir "$OUTDIR" \ + --root "$ROOT" \ + --format html \ + --macros \ + $DOCINDEX \ + $MAPPING \ + $THEME \ + $FILENAMES diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/FrontPage --- a/docs/wiki/FrontPage Sun Apr 14 00:29:40 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -= MoinLight = - -MoinLight is a distribution of programs and libraries for working with content -encoded in the [[https://moinmo.in/|MoinMoin]] wiki markup format. This markup -format is generally concise and supports many kinds of HTML document features -using intelligible plain text representations. - -########## The graph below shows the architecture of the system... - -{{{#!graphviz -#format svg -#transform notugly -digraph architecture { - node [shape=box,fontsize="13.0",fontname="Helvetica"]; - rankdir=LR; - - subgraph { - rank=same; - input [label="Input context",URL="Input"]; - markup [label="Moin content",shape=folder,style=filled,fillcolor=cyan]; - } - - parser [label="Parser",URL="Parsers"]; - - subgraph { - rank=same; - tree [label="Document tree",shape=folder,style=filled,fillcolor=cyan]; - evaluation [label="Macro evaluation",shape=ellipse]; - } - - serialiser [label="Serialiser",URL="Serialisers"]; - - theme [label="Theme",URL="Themes"]; - - subgraph { - rank=same; - output [label="Output context",URL="Output"]; - pages [label="Web content",shape=folder,style=filled,fillcolor=cyan]; - } - - markup -> input -> parser -> tree -> evaluation -> tree -> serialiser -> - theme -> output -> pages; -} -}}} - -########## - -Although it is obviously possible to use the MoinMoin software (hereafter -referred to as Moin) to work such such content, there are a few advantages in -developing independent tools instead: - - * To eliminate any dependency on the Moin code, its bundled libraries, or on - its external dependencies (of which there are many for Moin 2.0) - - * To focus on areas of functionality that are considered priorities, such as - the publishing of content as static Web sites, which may not be adequately - or optimally supported by Moin - - * To provide other implementations of parsers and serialisers for the markup - format, thus establishing it as more genuinely interoperable markup - standard - - * To be able to work with the content more easily and to develop tools for - doing so - -== Getting Started == - -To convert a collection of wiki pages in a directory (with `pages` containing -the original pages and `htdocs` being the desired output directory), run the -`moinconvert` program as follows: - -{{{ -moinconvert --input-dir pages --output-dir htdocs --all -}}} - -To convert a single file from such a collection (such as `FrontPage`), run the -program as follows: - -{{{ -moinconvert --input-dir pages FrontPage -}}} - -This will produce the serialised page on standard output rather than writing -it to a file. - -Other options are typically useful when running the program, such as `--theme` -for styling and wrapping the output, `--macros` for expanding macros in -documents, and `--format` for choosing alternative output formats. - -== Abstractions and Architecture == - -MoinLight provides a number of abstractions for working with Moin wiki content: - - * [[/Parsers]] interpret various forms of markup-related content, producing a - document tree representation that can be inspected and processed - - * [[/Serialisers]] convert the document tree representation into other - content formats such as HTML or even back into Moin format - - * [[/Themes]] augment serialised content with additional details and - resources - - * [[/Macros]] define locations in documents where content is to be inserted - or expanded - - * [[/Input]] contexts permit the interpretation of existing content in - certain ways so that a collection of text files can be treated like a wiki - - * [[/Output]] contexts permit the publishing of content in certain - ways so that wiki content can be shared on the Web - -A major objective with MoinLight is to be able to produce static files that -can be served using a typical Web server without any need for scripts, -applications or other kinds of dynamic content. Other objectives are described -in the [[/Roadmap]] document. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Input --- a/docs/wiki/Input Sun Apr 14 00:29:40 2019 +0200 +++ b/docs/wiki/Input Tue Apr 16 23:37:54 2019 +0200 @@ -1,22 +1,26 @@ = Input = -Input contexts determine how content provided for processing should be interpreted. -Typically, wiki content will either be provided as a single file containing a -single wiki page or as collections of such files arranged within a directory -hierarchy. +Input contexts determine how content provided for processing should be +interpreted. Typically, wiki content will either be provided as a single file +containing a single wiki page or as collections of such files arranged within a +directory hierarchy. -The following input contexts are supported: +The supported input contexts are described below. + +== Directory == + +A directory containing wiki page files. -{{{#!table -'''Name''' || '''Format''' || '''Details''' -== -directory -|| A directory containing wiki page files -|| Each file contains a different wiki page with its filename indicating the -.. page name, and with any configured `input_separator` being used in -.. filenames to construct hierarchical page relationships -== -standalone -|| A standalone wiki page file -|| A single file containing a single wiki page -}}} +[[Metadata#input_context|input_context]]: `directory` + +Each file contains a different wiki page with its filename indicating the page +name, and with any configured `input_separator` being used in filenames to +construct hierarchical page relationships. + +== Standalone == + +A standalone wiki page file. + +[[Metadata#input_context|input_context]]: `standalone` + +A single file containing a single wiki page. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Macros --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/Macros Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,15 @@ += Macros = + +As [[MoinMoin:HelpOnMacros|in MoinMoin]], macros are instructions that are +replaced or expanded to produce content within documents. A number of macros +are provided in MoinLight, some of which are provided for compatibility with +Moin, including the following: + +|| '''Name''' || '''Purpose''' || +|| `Anchor` || Insert a link anchor || +|| `AttachList` || Show a list of page attachments || +|| `BR` || Insert a line break || +|| `MailTo` || Encode a `mailto:` link || +|| `PageList` || Show a list of pages || +|| `TableOfContents` || Show a table of contents || +|| `Verbatim` || Insert text without formatting || diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Metadata --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/Metadata Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,111 @@ += Metadata = + +The metadata abstraction is used in MoinLight to control the conversion of +wiki content from its [[Input|input]] form to its eventual [[Output|output]] +form. + +The settings or properties retained by the conversion metadata are described +below. + +<> + +== attachments == + + Default:: `attachments` + +The name used for attachment directories. + +== document_index == + + Default:: (none) + +The filename to be incorporated into page links so that such links reference a +particular file instead of the page directory containing the file. This is +useful when generating HTML content to be browsed as local files. + +== input_context == + + Default:: `standalone` + Alternative:: `directory` + +The form of the [[Input|input]] to be processed. + +== input_encoding == + + Default:: `utf-8` + +The character encoding used in the input documents. + +== input_filename == + + Default:: (none) + +The location of the input document or directory of documents. + +== input_format == + + Default:: `moin` + +The default format of input documents. + +== input_separator == + + Default:: (none) + +The separator used to structure hierarchical pagenames. + +== link_format == + + Default:: (depends on the [[#output_format| output format]]) + +The format of encoded links in converted documents. Typically, this will +conform to the general output format of the documents. + +== mapping == + + Default:: (none) + +A mapping of identifiers to URLs, used to generate interwiki links. + +== output_context == + + Default:: `standalone` + Alternative:: `directory` + +The form of the [[Output|output]] to be processed. + +== output_encoding == + + Default:: `utf-8` + +The character encoding used in the output documents. + +== output_format == + + Default:: `moin` + +The default format of output documents. + +== output_filename == + + Default:: (none) + +The location of the output document or directory of documents. + +== root_pagename == + + Default:: `FrontPage` + +The pagename of the root document in a collection of documents. + +== theme_name == + + Default:: (none) + Alternatives:: (see below) + +Required for applying themes to output. The names combine a theme name with an +output format. For example: + +|| '''Alternative''' || '''Theme''' || '''Format''' || +|| `default.html` || `default` || `html` || +|| `mercurial.html` || `mercurial` || `html` || diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/MoinLight --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/MoinLight Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,122 @@ += MoinLight = + +MoinLight is a distribution of programs and libraries for working with content +encoded in the [[https://moinmo.in/|MoinMoin]] wiki markup format. This markup +format is generally concise and supports many kinds of HTML document features +using intelligible plain text representations. + +########## The graph below shows the architecture of the system... + +{{{#!graphviz +#format svg +#transform notugly +digraph architecture { + node [shape=box,fontsize="13.0",fontname="Helvetica"]; + rankdir=LR; + + subgraph { + rank=same; + input [label="Input context",URL="Input"]; + markup [label="Moin content",shape=folder,style=filled,fillcolor=cyan]; + } + + parser [label="Parser",URL="Parsers"]; + + subgraph { + rank=same; + tree [label="Document tree",shape=folder,style=filled,fillcolor=cyan]; + evaluation [label="Macro evaluation",shape=ellipse]; + } + + serialiser [label="Serialiser",URL="Serialisers"]; + + theme [label="Theme",URL="Themes"]; + + subgraph { + rank=same; + output [label="Output context",URL="Output"]; + pages [label="Web content",shape=folder,style=filled,fillcolor=cyan]; + } + + markup -> input -> parser -> tree -> evaluation -> tree -> serialiser -> + theme -> output -> pages; +} +}}} + +########## + +Although it is obviously possible to use the MoinMoin software (hereafter +referred to as Moin) to work such such content, there are a few advantages in +developing independent tools instead: + + * To eliminate any dependency on the Moin code, its bundled libraries, or on + its external dependencies (of which there are many for Moin 2.0) + + * To focus on areas of functionality that are considered priorities, such as + the publishing of content as static Web sites, which may not be adequately + or optimally supported by Moin + + * To provide other implementations of parsers and serialisers for the markup + format, thus establishing it as more genuinely interoperable markup + standard + + * To be able to work with the content more easily and to develop tools for + doing so + +The wiki format is described in the [[/MoinSyntax|syntax documentation]]. + +== Getting Started == + +To convert a collection of wiki pages in a directory (with `pages` containing +the original pages and `htdocs` being the desired output directory), run the +`moinconvert` program as follows: + +{{{ +moinconvert --input-dir pages --output-dir htdocs --all +}}} + +To convert a single file from such a collection (such as `FrontPage`), run the +program as follows: + +{{{ +moinconvert --input-dir pages FrontPage +}}} + +This will produce the serialised page on standard output rather than writing +it to a file. + +Other options are typically useful when running the program, such as `--theme` +for styling and wrapping the output, `--macros` for expanding macros in +documents, and `--format` for choosing alternative output formats. + +See [[/moinconvert]] for more information on the `moinconvert` program. + +== Abstractions and Architecture == + +MoinLight provides a number of abstractions for working with Moin wiki content: + + * [[/Input]] contexts permit the interpretation of existing content in + certain ways so that a collection of text files can be treated like a wiki + + * [[/Output]] contexts permit the publishing of content in certain + ways so that wiki content can be shared on the Web + + * [[/Macros]] define locations in documents where content is to be inserted + or expanded + + * [[/Metadata]] is used to configure the processing of content by defining + the different abstractions involved + + * [[/Parsers]] interpret various forms of markup-related content, producing a + document tree representation that can be inspected and processed + + * [[/Serialisers]] convert the document tree representation into other + content formats such as HTML or even back into Moin format + + * [[/Themes]] augment serialised content with additional details and + resources + +A major objective with MoinLight is to be able to produce static files that +can be served using a typical Web server without any need for scripts, +applications or other kinds of dynamic content. Other objectives are described +in the [[/Roadmap]] document. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/MoinSyntax --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/MoinSyntax Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,123 @@ += Moin Format Syntax = + +The syntax of the wiki format is described in various locations on the +[[MoinMoin:]] site: + + * [[MoinMoin:HelpOnMoinWikiSyntax]] + * [[MoinMoin:HelpOnEditing]] + +Various enhancements are introduced in MoinLight, and these are described +below. + +== Anchor == + +Introduce an anchor employing a fragment identifier that can be reached by a +link employing the identifier. For example, [[#end]] is a link to the anchor +{{{((end))}}} near the end of this page. + +=== Syntax === + +{{{ +((identifier)) +}}} + +Here, `identifier` is the fragment identifier for the anchor. + +=== Related === + +The {{{<>}}} macro has the same function. + +== Line Break == + +Introduces a line break in the page. For example: + +Above\\Below + +=== Syntax === + +{{{ +Above +\\ +Below +}}} + +Here, {{{\\}}} is the line break symbol. + +=== Related === + +The {{{<
>}}} macro has the same function. + +== Links == + +Link syntax remains largely compatible with Moin, but it is possible to break +links across lines. For example: + +[[MoinSyntax|a description of a link to the Moin format syntax +wrapped across multiple lines]] + +=== Syntax === + +{{{ +[[MoinSyntax|a description of a link to the Moin format syntax +wrapped across multiple lines]] +}}} + +=== Related === + +The [[MoinMoin:HelpOnLinking|Moin link syntax]] applies, including the +transclusion syntax. + +== Table Regions == + +Provides a more readable and convenient way of describing tables. For example: + +{{{#!table +Top Left || Top Right +== +Bottom Left || Bottom Right + .. (continued) +}}} + +=== Syntax === + +{{{{ +{{{#!table +Top Left || Top Right +== +Bottom Left || Bottom Right + .. (continued) +}}} +}}}} + +=== Related === + +Provides mostly the same functionality as the MoinMoin extension +[[MoinMoin:ParserMarket/ImprovedTableParser|ImprovedTableParser]]. + +== Verbatim == + +Introduce text verbatim in the page, ignoring any other markup features that +may be present. For example: + +<<>> + +=== Syntax === + +{{{ +<<>> +}}} + +Here, {{{<<<}}} and {{{>>>}}} enclose the verbatim text. + +=== Related === + +The {{{<>}}} macro has a similar function, +but being a macro it imposes limitations on the enclosed content, such as not +permitting newlines. + +---- + +((end)) +A demonstration of the [[#Anchor|anchor]] syntax. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Output --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/Output Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,32 @@ += Output = + +Output contexts determine the form of converted wiki content. As with [[Input| +input contexts]], typical forms will include a single file representing a wiki +page or collections of files arranged within a directory hierarchy. + +The supported output contexts are described below. + +== Directory == + +A directory containing wiki page resources in a hierarchy. + +[[Metadata#output_context|output_context]]: `directory` + +Each converted wiki page will reside at a path within the hierarchy +corresponding to the page name, with top-level pages residing directly within +the top-level output directory, and with subpages residing within the +directories of their parents. + +Page content is stored in index files within each page +directory, typically `index.html` (defined by the [[Metadata#index_name| +index_name]] metadata property), with the designated [[Metadata#root|root]] +page content appearing in the index file directly inside the top-level output +directory. + +== Standalone == + +A standalone wiki page file. + +[[Metadata#output_context|output_context]]: `standalone` + +A single file containing a single wiki page. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Parsers --- a/docs/wiki/Parsers Sun Apr 14 00:29:40 2019 +0200 +++ b/docs/wiki/Parsers Tue Apr 16 23:37:54 2019 +0200 @@ -5,17 +5,16 @@ {{{#!table '''Name''' || '''Format''' || '''Details''' == -graphviz +`graphviz` || [[http://graphviz.org/|Graphviz]] DOT language || A complete graph description with optional processing directives == -moin +`moin` || [[https://moinmo.in/|Moin]] markup -|| Plain text with additional -.. [[https://moinmo.in/HelpOnMoinWikiSyntax|syntax]] for formatting +|| Plain text with additional [[MoinSyntax|syntax]] for formatting == -table +`table` || Multiline table || Moin markup with multiline table -.. [[https://moinmo.in/ParserMarket/ImprovedTableParser|syntax enhancements]] +.. [[MoinSyntax#Table Regions|syntax enhancements]] }}} diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Serialisers --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/Serialisers Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,21 @@ += Serialisers = + +Serialisers convert page content, producing output in a particular format. +The following serialisers are currently supported: + +{{{#!table +'''Name''' || '''Format''' || '''Details''' +== +`html` +|| HTML markup format +|| Without a [[Themes|theme]] applied to the output, only a document fragment +.. is produced; otherwise, a complete document should be produced +== +`moin` +|| [[MoinSyntax|Moin]] markup format +|| The output should correspond to the input provided to the +.. [[Parsers|parser]] +}}} + +Within each serialiser's package, parser-specific modules handle the document +nodes created by each different [[Parsers|parser]]. diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/Themes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/Themes Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,16 @@ += Themes = + +For certain [[Output|output]] formats, themes can be applied to the converted +documents to produce content that can be usefully published. Typically, this +applies only to HTML format documents. + +Currently, the following themes are defined: + +{{{#!table +'''Name''' || '''Description''' +== +`default` || A simple HTML document theme with minimal decoration +== +`mercurial` || A relatively clean theme resembling that of the Mercurial Web + .. site +}}} diff -r 15d155fac345 -r 0613eeb78609 docs/wiki/moinconvert --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/moinconvert Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,11 @@ += moinconvert = + +The `moinconvert` program is the principal means of converting content using +MoinLight. Its help message can be obtained as follows: + +{{{ +moinconvert --help +}}} + +The program employs command options to configure the conversion [[Metadata| +metadata]], then converts the indicated content to the desired form. diff -r 15d155fac345 -r 0613eeb78609 moinformat/input/directory.py --- a/moinformat/input/directory.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/input/directory.py Tue Apr 16 23:37:54 2019 +0200 @@ -51,7 +51,7 @@ # Support attachments directories. - self.attachments_dir = metadata.get("attachments", "attachments") + self.attachments_dir = metadata.get("attachments") def all(self): diff -r 15d155fac345 -r 0613eeb78609 moinformat/links/common.py --- a/moinformat/links/common.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/links/common.py Tue Apr 16 23:37:54 2019 +0200 @@ -67,8 +67,8 @@ # Obtain essential metadata. self.mapping = metadata.get("mapping", {}) - self.root_pagename = metadata.get("root_pagename", "FrontPage") - self.attachments_dir = metadata.get("attachments", "attachments") + self.root_pagename = metadata.get("root_pagename") + self.attachments_dir = metadata.get("attachments") def resolve(path, pagename, root_pagename): diff -r 15d155fac345 -r 0613eeb78609 moinformat/links/html.py --- a/moinformat/links/html.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/links/html.py Tue Apr 16 23:37:54 2019 +0200 @@ -135,13 +135,15 @@ # Attachment links. if type == "attachment": - return Link(self.translate_attachment(identifier), identifier, target) + return Link(self.translate_attachment(identifier), + identifier, target) # Interwiki links. url = self.mapping.get(type) if url: - return Link(self.translate_interwiki(url, identifier), identifier, target) + return Link(self.translate_interwiki(url, identifier), + identifier or type, target) return None diff -r 15d155fac345 -r 0613eeb78609 moinformat/macros/attachlist.py --- a/moinformat/macros/attachlist.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/macros/attachlist.py Tue Apr 16 23:37:54 2019 +0200 @@ -19,6 +19,7 @@ this program. If not, see . """ +from mimetypes import guess_type from moinformat.macros.common import Macro from moinformat.tree.moin import Link, LinkLabel, List, ListItem, Text from moinformat.utils.links import LinkTarget @@ -43,10 +44,26 @@ # Access the input context to get the attachment details. input = self.metadata.get_input() - filenames = pagename and input.get_attachments(pagename) or [] # Select attachments by type. - # NOTE: To do. + + all_filenames = pagename and input.get_attachments(pagename) or [] + + if mimetype: + filenames = [] + + for filename in all_filenames: + type, encoding = guess_type(filename) + + if type == mimetype: + filenames.append(filename) + else: + filenames = all_filenames + + # Sort the filenames. + # NOTE: The actual sort order should be controlled. + + filenames.sort() # Prepare a list of links. diff -r 15d155fac345 -r 0613eeb78609 moinformat/macros/mailto.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/macros/mailto.py Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +""" +Mail-to macro for Moin compatibility. + +Copyright (C) 2019 Paul Boddie + +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 3 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, see . +""" + +from moinformat.macros.common import Macro +from moinformat.tree.moin import Link, LinkLabel, Text +from moinformat.utils.links import LinkTarget + +def get_address(label): + + "Decode the address found in 'label'." + + l = [] + d = {"AT" : "@", "DASH" : "-", "DOT" : "."} + + for word in label.split(): + if d.has_key(word): + l.append(d[word]) + elif not word.isupper(): + l.append(word) + + return u"".join(l) + +class MailToMacro(Macro): + + "A mail-to macro." + + name = "MailTo" + + def evaluate(self): + + "Evaluate the macro, producing a mailto link." + + # Replace the macro node with the link. + + macro = self.node + args = self.node.args + + # Obtain a label and an address. + + label = args and args[0] or None + address = get_address(label) + + if address: + link = Link([LinkLabel([Text(label)])], + LinkTarget("url", "mailto:%s" % address)) + else: + link = Text("") + + macro.parent.replace(macro, link) + +macro = MailToMacro + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 15d155fac345 -r 0613eeb78609 moinformat/macros/pagelist.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/macros/pagelist.py Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +""" +PageList macro for Moin compatibility. + +Copyright (C) 2019 Paul Boddie + +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 3 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, see . +""" + +from moinformat.macros.common import Macro +from moinformat.tree.moin import Link, LinkLabel, List, ListItem, Text +from moinformat.utils.links import LinkTarget + +class PageListMacro(Macro): + + "A page list macro." + + name = "PageList" + + def evaluate(self): + + "Evaluate the macro, producing a list of pages." + + # Obtain the parameters. + + args = self.node.args + pattern = args and args[0] or None + + # Access the input context to get page details. + + input = self.metadata.get_input() + + # Select pages according to the parameters. + # NOTE: Currently using prefix matching only. + + if pattern: + pagenames = [] + for pagename in input.all(): + if pagename.startswith(pattern): + pagenames.append(pagename) + else: + pagenames = input.all() + + # Sort the pagenames. + # NOTE: The actual sort order should be controlled. + + pagenames.sort() + + # Prepare a list of links. + + items = [] + indent = 0 + marker = "*" + space = " " + num = None + + for pagename in pagenames: + text = [Text(pagename)] + nodes = [Link([LinkLabel(text)], LinkTarget("page", pagename))] + items.append(ListItem(nodes, indent, marker, space, num)) + + # Replace the macro node with the list. + + macro = self.node + macro.parent.replace(macro, List(items)) + +macro = PageListMacro + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 15d155fac345 -r 0613eeb78609 moinformat/macros/verbatim.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/macros/verbatim.py Tue Apr 16 23:37:54 2019 +0200 @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +""" +Verbatim macro for Moin compatibility. + +Copyright (C) 2019 Paul Boddie + +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 3 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, see . +""" + +from moinformat.macros.common import Macro +from moinformat.tree.moin import Verbatim + +class VerbatimMacro(Macro): + + "A verbatim text macro." + + name = "Verbatim" + + def evaluate(self): + + "Evaluate the macro, producing a verbatim text node." + + # Replace the macro node with the verbatim node. + + macro = self.node + macro.parent.replace(macro, Verbatim(",".join(self.node.args))) + +macro = VerbatimMacro + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 15d155fac345 -r 0613eeb78609 moinformat/metadata.py --- a/moinformat/metadata.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/metadata.py Tue Apr 16 23:37:54 2019 +0200 @@ -3,7 +3,7 @@ """ Metadata for document conversion. -Copyright (C) 2018 Paul Boddie +Copyright (C) 2018, 2019 Paul Boddie 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 @@ -31,9 +31,11 @@ "Metadata employed in the document conversion process." defaults = { + "attachments" : "attachments", "input_format" : "moin", "output_context" : "standalone", "output_format" : "moin", + "root_pagename" : "FrontPage", } default_effects = { diff -r 15d155fac345 -r 0613eeb78609 moinformat/output/directory.py --- a/moinformat/output/directory.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/output/directory.py Tue Apr 16 23:37:54 2019 +0200 @@ -40,10 +40,14 @@ self.dir = Directory(metadata.get("output_filename")) self.dir.ensure() - self.index_name = metadata.get("index_name", "index.html") + # Use any document index setting as the default for the index filename. + + document_index = metadata.get("document_index", "index.html") + + self.index_name = metadata.get("index_name", document_index) self.page_suffix = metadata.get("page_suffix", "%shtml" % extsep) - self.root_pagename = metadata.get("root_pagename", "FrontPage") - self.attachments_dir = metadata.get("attachments", "attachments") + self.root_pagename = metadata.get("root_pagename") + self.attachments_dir = metadata.get("attachments") # Convenience methods. diff -r 15d155fac345 -r 0613eeb78609 moinformat/parsers/common.py --- a/moinformat/parsers/common.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/parsers/common.py Tue Apr 16 23:37:54 2019 +0200 @@ -3,7 +3,7 @@ """ Moin wiki parsing functionality. -Copyright (C) 2017, 2018 Paul Boddie +Copyright (C) 2017, 2018, 2019 Paul Boddie 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 @@ -434,22 +434,28 @@ the 'region' object. """ - while True: - preceding = self.read_until(["directive"], False) + try: + while True: + preceding = self.read_until(["directive"], False) - # With an immediately-appearing directive, handle its details. + # With an immediately-appearing directive, handle its details. - if preceding == "": - handler = self.handlers.get(self.matching_pattern()) - if handler: - handler(self, region) + if preceding == "": + handler = self.handlers.get(self.matching_pattern()) + if handler: + handler(self, region) + else: + break + + # Otherwise, with no immediate directive (or none at all), stop. + else: break - # Otherwise, with no immediate directive (or none at all), stop. + # Handle a premature end of region. - else: - break + except StopIteration: + pass # Parsing utilities. diff -r 15d155fac345 -r 0613eeb78609 moinformat/parsers/moin.py --- a/moinformat/parsers/moin.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/parsers/moin.py Tue Apr 16 23:37:54 2019 +0200 @@ -139,6 +139,8 @@ if self.headings: metadata.set("title", self.headings[0].text_content()) + else: + metadata.set("title", self.metadata.get("pagename")) # Heading disambiguation. @@ -783,13 +785,13 @@ # Links and transclusions may start inline spans. "link" : join((r"\[\[", # [[ - group("target", r"\E*?"), # ... + group("target", r"\P*?"), # ... choice((r"\|", # | group("end", r"]]"))))), # ]] "transclusion" : join((r"\{\{", # {{ excl(r"\{"), # not-{ - group("target", ".*?"), # ... + group("target", r"\P*?"), # ... choice((r"\|", # | group("end", r"}}"))))), # }} @@ -810,7 +812,7 @@ ">>")), # >> "verbatim" : join(("<<<", # <<< - group("verbatim", ".*?"), # ... + group("verbatim", r"\P*?"), # ... ">>>")), # Ending patterns for inline features: diff -r 15d155fac345 -r 0613eeb78609 moinformat/serialisers/html/moin.py --- a/moinformat/serialisers/html/moin.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/serialisers/html/moin.py Tue Apr 16 23:37:54 2019 +0200 @@ -3,7 +3,7 @@ """ HTML serialiser. -Copyright (C) 2017, 2018 Paul Boddie +Copyright (C) 2017, 2018, 2019 Paul Boddie 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 @@ -20,7 +20,8 @@ """ from moinformat.serialisers.common import escape_attr, escape_text, Serialiser -from moinformat.tree.moin import LinkLabel, LinkParameter +from moinformat.tree.moin import LinkLabel, LinkParameter, Text +from moinformat.utils.links import parse_link_target class HTMLSerialiser(Serialiser): @@ -59,6 +60,12 @@ out("type-%s" % escape_attr(type or "opaque")) tag = self._region_tag(type) + + # Inline regions must preserve "indent" as space in the text. + + if type == "inline" and indent: + self.out(" " * indent) + self.out("<%s class='%s'>" % (tag, " ".join(l))) def end_region(self, level, indent, type, extra): @@ -247,7 +254,20 @@ pass def directive(self, directive, extra): - pass + name, text = directive.split(None, 1) + + # Produce a readable redirect. + + if name.lower() == "redirect": + self.start_block() + + # Process the redirect argument as a link target, producing a link + # element. + + target = parse_link_target(text, self.metadata) + self._link(target, [LinkLabel([Text(text)])], "a", "href") + + self.end_block() def linebreak(self): self.out("
") diff -r 15d155fac345 -r 0613eeb78609 moinformat/tree/moin.py --- a/moinformat/tree/moin.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/tree/moin.py Tue Apr 16 23:37:54 2019 +0200 @@ -418,7 +418,9 @@ return "List(%r)" % self.nodes def prettyprint(self, indent=""): - l = ["%sList: indent=%d marker=%r num=%r" % (indent, self.indent, self.marker, self.num)] + if not self.first: + self.init() + l = ["%sList: indent=%r marker=%r num=%r" % (indent, self.indent, self.marker, self.num)] return self._prettyprint(l, indent) def to_string(self, out): diff -r 15d155fac345 -r 0613eeb78609 moinformat/utils/links.py --- a/moinformat/utils/links.py Sun Apr 14 00:29:40 2019 +0200 +++ b/moinformat/utils/links.py Tue Apr 16 23:37:54 2019 +0200 @@ -42,7 +42,10 @@ __unicode__ = __str__ def get_identifier(self): - return self.identifier or self.text + if self.identifier is not None: + return self.identifier + else: + return self.text def get_text(self): return self.text diff -r 15d155fac345 -r 0613eeb78609 tests/test_formatting.txt --- a/tests/test_formatting.txt Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_formatting.txt Tue Apr 16 23:37:54 2019 +0200 @@ -16,7 +16,8 @@ Some --(deleted)-- text. -Some <<>>. +Some <<>>. Some ^superscript text wrapped^. diff -r 15d155fac345 -r 0613eeb78609 tests/test_links.tree --- a/tests/test_links.tree Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_links.tree Tue Apr 16 23:37:54 2019 +0200 @@ -74,3 +74,9 @@ Text Link Text + Break + Block + Text + Break + Block + Text diff -r 15d155fac345 -r 0613eeb78609 tests/test_links.txt --- a/tests/test_links.txt Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_links.txt Tue Apr 16 23:37:54 2019 +0200 @@ -12,3 +12,7 @@ link|wrapped link with label]], a [[link|link with wrapped label]], and a [[#wrapped intra-page link]]. + +Do not allow [[links + +broken into separate paragraphs]]. diff -r 15d155fac345 -r 0613eeb78609 tests/test_macros.tree --- a/tests/test_macros.tree Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_macros.tree Tue Apr 16 23:37:54 2019 +0200 @@ -18,3 +18,8 @@ Text Macro Text + Break + Block + Text + Macro + Text diff -r 15d155fac345 -r 0613eeb78609 tests/test_macros.tree-exp --- a/tests/test_macros.tree-exp Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_macros.tree-exp Tue Apr 16 23:37:54 2019 +0200 @@ -33,3 +33,8 @@ Text LineBreak Text + Break + Block + Text + Verbatim + Text diff -r 15d155fac345 -r 0613eeb78609 tests/test_macros.txt --- a/tests/test_macros.txt Sun Apr 14 00:29:40 2019 +0200 +++ b/tests/test_macros.txt Tue Apr 16 23:37:54 2019 +0200 @@ -7,3 +7,5 @@ == Subheading == More<
>text. + +Some <>.