diff options
-rw-r--r-- | tissue/skribilo.scm | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/tissue/skribilo.scm b/tissue/skribilo.scm new file mode 100644 index 0000000..4a216d3 --- /dev/null +++ b/tissue/skribilo.scm @@ -0,0 +1,97 @@ +;;; tissue --- Text based issue tracker +;;; Copyright © 2023 Arun Isaac <arunisaac@systemreboot.net> +;;; +;;; This file is part of tissue. +;;; +;;; tissue 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. +;;; +;;; tissue 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 tissue. If not, see <https://www.gnu.org/licenses/>. + +(define-module (tissue skribilo) + #:use-module (rnrs conditions) + #:use-module (rnrs exceptions) + #:use-module (srfi srfi-26) + #:use-module (ice-9 match) + #:use-module (oop goops) + #:use-module (skribilo ast) + #:use-module (skribilo evaluator) + #:use-module (skribilo reader) + #:use-module (tissue document) + #:use-module (tissue file-document) + #:use-module (tissue utils) + #:export (<skribilo-fragment> + skribilo-fragment-filename + skribilo-fragment-identifier + document-fragment)) + +(define-class <skribilo-fragment> (<file-document>) + (identifier #:getter skribilo-fragment-identifier #:init-keyword #:identifier) + (reader-name #:getter skribilo-fragment-reader-name #:init-keyword #:reader-name)) + +(define (document-node file identifier reader-name) + "Return @code{<markup>} object describing node identified by +@var{identifier} in @var{file} read using reader named by +@var{reader-name}." + (find1-down (lambda (node) + (and (is-a? node <markup>) + (string=? (markup-ident node) identifier))) + (call-with-input-file file + (cut evaluate-ast-from-port <> #:reader (make-reader reader-name))))) + +(define* (document-fragment file identifier #:key (reader-name 'skribe)) + "Return a @code{<skribilo-fragment>} object describing node identified +by @var{identifier} in @var{file} read using reader named by +@var{reader-name}." + (make <skribilo-fragment> + #:title (ast->string + (markup-option (document-node file identifier reader-name) + #:title)) + #:path file + #:commits (commits-affecting-file file) + #:identifier identifier + #:reader-name reader-name)) + +(define-method (document-id-term (fragment <skribilo-fragment>)) + "Return the ID term for skribilo @var{fragment}." + (string-append "Qskribilofragment." + (file-document-path fragment) + "#" + (skribilo-fragment-identifier fragment))) + +(define (ast->text node port) + "Serialize AST @var{node} into text suitable for indexing. Write +output to @var{port}." + (cond + ((is-a? node <node>) + (for-each (match-lambda + ((_ . value) + (display (ast->string value) port))) + (node-options node)) + (newline port) + (ast->text (node-body node) port)) + ((string? node) + (display node port)) + ((number? node) + (display (number->string node) port)) + ((list? node) + (for-each (lambda (element) + (ast->text element port) port) + node)))) + +(define-method (document-text (fragment <skribilo-fragment>)) + "Return the full text of skribilo @var{fragment}." + (call-with-output-string + (cut ast->text + (document-node (file-document-path fragment) + (skribilo-fragment-identifier fragment) + (skribilo-fragment-reader-name fragment)) + <>))) |