1.1 --- a/moinconvert Sat Apr 13 19:30:33 2019 +0200
1.2 +++ b/moinconvert Sun Apr 14 00:29:40 2019 +0200
1.3 @@ -333,7 +333,7 @@
1.4 output.writepage(outtext, pagename)
1.5 print >>sys.stderr, pagename
1.6
1.7 - copy_attachments(p, input, output)
1.8 + copy_attachments(p, input, output, all=True)
1.9
1.10 # Install any theme resources.
1.11
2.1 --- a/moinformat/input/common.py Sat Apr 13 19:30:33 2019 +0200
2.2 +++ b/moinformat/input/common.py Sun Apr 14 00:29:40 2019 +0200
2.3 @@ -3,7 +3,7 @@
2.4 """
2.5 Input context common functionality.
2.6
2.7 -Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
2.8 +Copyright (C) 2018, 2019 Paul Boddie <paul@boddie.org.uk>
2.9
2.10 This program is free software; you can redistribute it and/or modify it under
2.11 the terms of the GNU General Public License as published by the Free Software
2.12 @@ -44,6 +44,18 @@
2.13
2.14 return []
2.15
2.16 + def all_attachments(self):
2.17 +
2.18 + "Return all attachment filenames in the context."
2.19 +
2.20 + return []
2.21 +
2.22 + def get_attachments(self, pagename):
2.23 +
2.24 + "Return all attachment filenames for the given 'pagename'."
2.25 +
2.26 + return []
2.27 +
2.28 # Page characteristics.
2.29
2.30 def parent(self, pagename):
3.1 --- a/moinformat/input/directory.py Sat Apr 13 19:30:33 2019 +0200
3.2 +++ b/moinformat/input/directory.py Sun Apr 14 00:29:40 2019 +0200
3.3 @@ -45,7 +45,7 @@
3.4
3.5 self.level_sep = metadata.get("input_separator", sep)
3.6
3.7 - # Search recursively in nested directories for pages and files.
3.8 + # Search recursively in nested directories for pages.
3.9
3.10 self.nested = self.level_sep == sep
3.11
3.12 @@ -65,7 +65,20 @@
3.13
3.14 "Return all attachment filenames in the context."
3.15
3.16 - return self.dir.select_files("%s/*" % self.attachments_dir, self.nested)
3.17 + return self.dir.select_files(join(self.attachments_dir, "*"), True)
3.18 +
3.19 + def get_attachments(self, pagename):
3.20 +
3.21 + """
3.22 + Return all attachment filenames for the given 'pagename'. Each filename
3.23 + is relative to the appropriate attachment directory.
3.24 + """
3.25 +
3.26 + attachments_dir = Directory(join(self.dir.filename,
3.27 + self.attachments_dir,
3.28 + pagename))
3.29 +
3.30 + return attachments_dir.select_files("*")
3.31
3.32 # Page characteristics.
3.33
3.34 @@ -73,7 +86,7 @@
3.35
3.36 "Return the subpage filenames of 'pagename'."
3.37
3.38 - pattern = self.to_filename("%s/*" % pagename)
3.39 + pattern = self.to_filename("%s%s*" % (pagename, self.level_sep))
3.40 return self.dir.select_files(pattern, self.nested)
3.41
3.42 def subpages(self, pagename):
3.43 @@ -105,11 +118,8 @@
3.44 if not pagename:
3.45 return None
3.46
3.47 - if self.nested:
3.48 - return self.dir.get_filename(join(self.to_filename(pagename),
3.49 - self.attachments_dir, filename))
3.50 - else:
3.51 - return self.dir.get_filename(join(self.attachments_dir, filename))
3.52 + return self.dir.get_filename(join(self.attachments_dir,
3.53 + pagename, filename))
3.54
3.55 # NOTE: Translation methods should encode filenames appropriately.
3.56
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/moinformat/macros/attachlist.py Sun Apr 14 00:29:40 2019 +0200
4.3 @@ -0,0 +1,71 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +"""
4.7 +AttachList macro for Moin compatibility.
4.8 +
4.9 +Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
4.10 +
4.11 +This program is free software; you can redistribute it and/or modify it under
4.12 +the terms of the GNU General Public License as published by the Free Software
4.13 +Foundation; either version 3 of the License, or (at your option) any later
4.14 +version.
4.15 +
4.16 +This program is distributed in the hope that it will be useful, but WITHOUT
4.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4.19 +details.
4.20 +
4.21 +You should have received a copy of the GNU General Public License along with
4.22 +this program. If not, see <http://www.gnu.org/licenses/>.
4.23 +"""
4.24 +
4.25 +from moinformat.macros.common import Macro
4.26 +from moinformat.tree.moin import Link, LinkLabel, List, ListItem, Text
4.27 +from moinformat.utils.links import LinkTarget
4.28 +
4.29 +class AttachListMacro(Macro):
4.30 +
4.31 + "An attachment list macro."
4.32 +
4.33 + name = "AttachList"
4.34 +
4.35 + def evaluate(self):
4.36 +
4.37 + "Evaluate the macro, producing a list of attachments."
4.38 +
4.39 + # Obtain the parameters.
4.40 +
4.41 + args = self.node.args
4.42 +
4.43 + pagename = args and args[0] or self.metadata.get("pagename")
4.44 + mimetype = len(args) > 1 and args[1] or None
4.45 +
4.46 + # Access the input context to get the attachment details.
4.47 +
4.48 + input = self.metadata.get_input()
4.49 + filenames = pagename and input.get_attachments(pagename) or []
4.50 +
4.51 + # Select attachments by type.
4.52 + # NOTE: To do.
4.53 +
4.54 + # Prepare a list of links.
4.55 +
4.56 + items = []
4.57 + indent = 0
4.58 + marker = "*"
4.59 + space = " "
4.60 + num = None
4.61 +
4.62 + for filename in filenames:
4.63 + text = [Text(filename)]
4.64 + nodes = [Link([LinkLabel(text)], LinkTarget("attachment", filename))]
4.65 + items.append(ListItem(nodes, indent, marker, space, num))
4.66 +
4.67 + # Replace the macro node with the list.
4.68 +
4.69 + macro = self.node
4.70 + macro.parent.replace(macro, List(items))
4.71 +
4.72 +macro = AttachListMacro
4.73 +
4.74 +# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- a/moinformat/macros/toc.py Sat Apr 13 19:30:33 2019 +0200
5.2 +++ b/moinformat/macros/toc.py Sun Apr 14 00:29:40 2019 +0200
5.3 @@ -127,7 +127,7 @@
5.4
5.5 else:
5.6 new_items = []
5.7 - new_list = List(new_items, indent, marker, num)
5.8 + new_list = List(new_items)
5.9
5.10 # Add the list to the current item, if any.
5.11
6.1 --- a/moinformat/parsers/moin.py Sat Apr 13 19:30:33 2019 +0200
6.2 +++ b/moinformat/parsers/moin.py Sun Apr 14 00:29:40 2019 +0200
6.3 @@ -327,7 +327,7 @@
6.4
6.5 "Create a list, starting with 'item'."
6.6
6.7 - list = List([item], item.indent, item.marker, item.num)
6.8 + list = List([item])
6.9 self.parse_region_details(list, self.list_pattern_names, True)
6.10 return list
6.11
7.1 --- a/moinformat/tree/moin.py Sat Apr 13 19:30:33 2019 +0200
7.2 +++ b/moinformat/tree/moin.py Sun Apr 14 00:29:40 2019 +0200
7.3 @@ -3,7 +3,7 @@
7.4 """
7.5 Moin wiki format document tree nodes.
7.6
7.7 -Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
7.8 +Copyright (C) 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
7.9
7.10 This program is free software; you can redistribute it and/or modify it under
7.11 the terms of the GNU General Public License as published by the Free Software
7.12 @@ -404,20 +404,26 @@
7.13
7.14 "A list."
7.15
7.16 - def __init__(self, nodes, indent, marker, num):
7.17 + def __init__(self, nodes):
7.18 Container.__init__(self, nodes)
7.19 - self.indent = indent
7.20 - self.marker = marker
7.21 - self.num = num
7.22 + self.init()
7.23 +
7.24 + def init(self):
7.25 + self.first = first = self.nodes and self.nodes[0] or None
7.26 + self.indent = first and first.indent
7.27 + self.marker = first and first.marker
7.28 + self.num = first and first.num
7.29
7.30 def __repr__(self):
7.31 - return "List(%r, %r, %r, %r)" % (self.nodes, self.indent, self.marker, self.num)
7.32 + return "List(%r)" % self.nodes
7.33
7.34 def prettyprint(self, indent=""):
7.35 l = ["%sList: indent=%d marker=%r num=%r" % (indent, self.indent, self.marker, self.num)]
7.36 return self._prettyprint(l, indent)
7.37
7.38 def to_string(self, out):
7.39 + if not self.first:
7.40 + self.init()
7.41 out.start_list(self.indent, self.marker, self.num)
7.42 self._to_string(out)
7.43 out.end_list(self.indent, self.marker, self.num)
8.1 --- a/moinformat/utils/copying.py Sat Apr 13 19:30:33 2019 +0200
8.2 +++ b/moinformat/utils/copying.py Sun Apr 14 00:29:40 2019 +0200
8.3 @@ -21,32 +21,43 @@
8.4
8.5 from shutil import copy
8.6
8.7 -def copy_attachments(parser, input, output):
8.8 +def copy_attachments(parser, input, output, all=False):
8.9
8.10 - "Copy attachments referenced by 'parser' from 'input' to 'output'."
8.11 + """
8.12 + For attachments referenced by the page processed by 'parser', copy them from
8.13 + 'input' to 'output'. If 'all' is set to a true value, all stored attachments
8.14 + are copied; otherwise, only those explicitly linked in the page are copied.
8.15 + """
8.16
8.17 pagename = parser.metadata.get("pagename")
8.18
8.19 if not pagename:
8.20 return
8.21
8.22 - for link_target in parser.link_targets:
8.23 -
8.24 - # Obtain attachments.
8.25 + # Obtain attachments.
8.26
8.27 - if link_target.get_type() == "attachment":
8.28 + if not all:
8.29 + filenames = []
8.30 + for link_target in parser.link_targets:
8.31 + if link_target.get_type() == "attachment":
8.32 + filenames.append(link_target.get_identifier())
8.33 + else:
8.34 + input = parser.metadata.get_input()
8.35 + filenames = input.get_attachments(pagename)
8.36
8.37 - # Obtain the attachment filename, the source location and the
8.38 - # destination.
8.39 + # Copy attachments.
8.40
8.41 - filename = link_target.get_identifier()
8.42 - input_filename = input.get_attachment_filename(pagename, filename)
8.43 - output_filename = output.get_attachment_filename(pagename, filename)
8.44 + for filename in filenames:
8.45 +
8.46 + # Obtain the source location and the destination.
8.47
8.48 - # Copy the file if possible.
8.49 + input_filename = input.get_attachment_filename(pagename, filename)
8.50 + output_filename = output.get_attachment_filename(pagename, filename)
8.51
8.52 - if input_filename and output_filename:
8.53 - output.ensure_attachments(pagename)
8.54 - copy(input_filename, output_filename)
8.55 + # Copy the file if possible.
8.56 +
8.57 + if input_filename and output_filename:
8.58 + output.ensure_attachments(pagename)
8.59 + copy(input_filename, output_filename)
8.60
8.61 # vim: tabstop=4 expandtab shiftwidth=4