# Package initialization # Copyright (C) 2022-2023 Nguyễn Gia Phong # # This file is part of rub. # # Rub is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Rub 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with rub. If not, see . from functools import cached_property from os import walk from pathlib import Path from shutil import copytree, rmtree from rub import xml __all__ = ['Rubber', 'xml'] def glob_files(root: Path, suffix=''): """Return the list of all files in given directory, recursively.""" return [Path(path).relative_to(root)/file for path, dirs, files in walk(root) for file in files if file.endswith(suffix)] def replace(source: Path, destination: Path): """Replace destination with source directory.""" rmtree(destination, ignore_errors=True) copytree(source, destination, dirs_exist_ok=True) class Rubber: """Static generator.""" def __init__(self, generate_article, base, src, cache, out): self.generate_article = generate_article self.base, self.src = base, src self.cache, self.out = cache, out @cached_property def tasks(self): def assox(): for k in dir(self): if not k.startswith('task_'): continue v = getattr(self, k) if callable(v): yield k, v return dict(assox()) def task_base(self): paths = glob_files(self.base) return {'doc': 'copy base directory', 'file_dep': [self.base/path for path in paths], 'actions': [(replace, [self.base, self.out])], 'targets': [self.out/path for path in paths], 'clean': True} def task_articles(self): """process articles into XHTML""" for path in glob_files(self.src, '.xml'): source = self.src / path destination = self.out / path yield {'name': path, 'doc': f'process {path} into XHTML', 'file_dep': [source], 'actions': [(self.generate_article, [source, destination])], 'targets': [destination], 'clean': True}