;;; kexport.el --- Convert koutlines to other textual formats, including HTML -*- lexical-binding:t -*- ;; ;; Author: Bob Weiner ;; ;; Orig-Date: 26-Feb-98 ;; ;; Copyright (C) 1998-2017 Free Software Foundation, Inc. ;; See the "../HY-COPY" file for license information. ;; ;; This file is part of GNU Hyperbole. ;;; Commentary: ;;; Code: ;;; ************************************************************************ ;;; Other required Elisp libraries ;;; ************************************************************************ (require 'hypb) (require 'hpath) (require 'hibtypes) (require 'klink) (declare-function kotl-mode:beginning-of-buffer "kotl-mode") ;;; ************************************************************************ ;;; Public variables ;;; ************************************************************************ (defvar kexport:input-filename nil "This is automatically set to the full pathname of the file presently being exported.") (defvar kexport:output-filename nil "This is automatically set to the full pathname of the file presently being exported.") (defcustom kexport:html-body-attributes "BGCOLOR=\"#FFFFFF\"" ;; white background "*String of HTML attributes attached to the
tag of an HTML exported koutline file." :type 'string :group 'hyperbole-koutliner) (defcustom kexport:html-description "Created by Hyperbole's outliner.\nSee \"(hyperbole)Koutliner\" for more information." "*String to insert as the HTML-exported document's description, or nil for none." :type '(choice (const nil) (string)) :group 'hyperbole-koutliner) (defcustom kexport:html-keywords nil "*String of comma separated keywords to include with an HTML-exported document, or nil for none." :type '(choice (const nil) (string)) :group 'hyperbole-koutliner) (defcustom kexport:label-html-font-attributes "COLOR=\"#C100C1\" SIZE=\"-1\"" "*String of HTML font attributes attached to kcell labels when exported." :type 'string :group 'hyperbole-koutliner) (defvar kexport:kcell-reference-regexp "[0-9a-zA-Z][.0-9a-zA-Z]*=\\([.0-9a-zA-Z]+\\)") (defvar kexport:kcell-partial-reference-regexp "\\([0-9a-zA-Z][.0-9a-zA-Z]*\\)") (defvar kexport:html-replacement-alist (list ;; make <> into literal markup '("<" . "<") '(">" . ">") ;; ;; italicize keybindings '("{[^}]+}" . "\\0") ;; ;; make URLs into hyperlinks (cons hpath:url-regexp 'kexport:html-url) ;; tightened version of hpath:url-regexp2 (cons (concat "\\(URL:\\|[^/@]\\|\\`\\|\"\\)\\(\\(\\)\\(\\)\\(" hpath:url-hostnames-regexp "\\.[^/:@ \t\n\r\"`']+\\)\\(:[0-9]+\\)?\\([/~]\\([^\]\[@ \t\n\r\"`'(){}<>]+[^\]\[@ \t\n\r\"`'(){}<>.,?#!*]\\)*\\)?\\)>?") 'kexport:html-url) ;; ;; make mail addresses into hyperbuttons (cons mail-address-regexp "\\1\\2") ;; ;; make klinks into hyperlinks (cons (concat "<\\s-*@\\s-*" kexport:kcell-reference-regexp "[^&>]*>") "\\0") (cons (format "<\\s-*@\\s-*\\(%s\\)[^=&>]*>" kexport:kcell-partial-reference-regexp) "\\0") (cons (format "<\\s-*\\([^ \t\n\r,<>]+\\)\\s-*,\\s-*%s[^=&>]*>" kexport:kcell-reference-regexp) 'kexport:html-file-klink) (cons (format "<\\s-*\\([^ \t\n\r,<>]+\\)\\s-*,\\s-*%s[^=&>]*>" kexport:kcell-partial-reference-regexp) 'kexport:html-file-klink) ) "*List of (regexp . replacement-pattern) elements applied in order to the contents of each kcell from a koutline exported to HTML format. Replacement pattern may be: a string with references to regexp's grouping numbers, e.g. \\1, or a function of one argument (it is passed the string being replaced in) which returns the modified string. The function may use expressions such as (match-beginning 1) since the regexp has just been matched against the target string when it is called.") ;;; ************************************************************************ ;;; Public functions ;;; ************************************************************************ ;;;###autoload (defun kexport:html (export-from output-to &optional soft-newlines-flag) "Export a koutline buffer or file in EXPORT-FROM to html format in OUTPUT-TO. By default, this retains newlines within cells as they are. With optional prefix arg, SOFT-NEWLINES-FLAG, hard newlines are not used. Also converts Urls and Klinks into Html hyperlinks. STILL TODO: Make delimited pathnames into file links (but not if within klinks). Copy attributes stored in cell 0 and attributes from each cell." (interactive "fKoutline buffer/file to export: \nFHTML buffer/file to save to: \nP") ;; (defvar html-mode-hook) (defvar hm--html-mode-hook) (defvar psgml-mode-hook) ;; FIXME: These are presumably used to prevent syntax highlighting, but in ;; Emacs they don't exist, so I'm not sure if it means that we have a bug (we ;; need to prevent font-lock for Emacs as well), or rather that Emacs's ;; version of font-lock doesn't get in the way. (defvar font-lock-auto-fontify) (defvar font-lock-mode-disable-list) (defvar font-lock-mode-enable-list) (let* ((export-buf-name (cond ((or (bufferp export-from) (get-buffer export-from)) (buffer-name (get-buffer export-from))) ((get-file-buffer export-from) (buffer-name (get-file-buffer export-from))) ((stringp export-from) (buffer-name (find-file-noselect export-from))) (t (error "(kexport:html): `%s' is an invalid `export-from' argument" export-from)))) (font-lock-auto-fontify) ;; Prevent syntax highlighting (font-lock-mode-disable-list '(html-mode)) (font-lock-mode-enable-list) ;; Avoid running user hooks in the destination file. ;; FIXME: There should be a better way to do that than to enumerate ;; the possible modes's hooks. (html-mode-hook) (hm--html-mode-hook) (psgml-mode-hook) (output-to-buf-name (cond ((or (bufferp output-to) (get-buffer output-to)) (buffer-name (get-buffer output-to))) ((get-file-buffer output-to) (buffer-name (get-file-buffer output-to))) ((stringp output-to) (buffer-name (find-file-noselect output-to))) (t (error "(kexport:html): `%s' is an invalid `output-to' argument" output-to)))) (standard-output (get-buffer output-to-buf-name)) title) (set-buffer standard-output) (setq buffer-read-only nil kexport:output-filename buffer-file-name) (erase-buffer) (set-buffer export-buf-name) (setq kexport:input-filename buffer-file-name) ;; Use the first line of the first cell as the default HTML document title. (setq title (save-excursion (kotl-mode:beginning-of-buffer) (kcell-view:contents))) (if (string-match "\n" title) (setq title (substring title 0 (match-beginning 0)))) ;; If called interactively, prompt user for the title to use. (if (called-interactively-p 'interactive) (setq title (read-string (format "Title for %s: " output-to-buf-name) title))) (princ "\n\n") (princ "\n") (princ (format "