Function: kexport:html

kexport:html is an autoloaded, interactive and byte-compiled function defined in kexport.el.

Signature

(kexport:html EXPORT-FROM OUTPUT-TO &optional SOFT-NEWLINES-FLAG)

Documentation

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.

Key Bindings

Source Code

;; Defined in ~/.emacs.d/elpa/hyperbole-20260414.325/kotl/kexport.el
;;;###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 (list (read-file-name
		      "Koutline buffer/file to export: " nil (hypb:buffer-file-name) t)
		     (read-file-name "HTML buffer/file to save to: ")
		     current-prefix-arg))
  (let* ((export-buf-name
	  (cond ((get-file-buffer export-from)
		 (buffer-name (get-file-buffer export-from)))
		((and (or (bufferp export-from)
			  (get-buffer export-from))
		      (kotl-mode:is-p))
		 (buffer-name (get-buffer export-from)))
		((and (stringp export-from)
		      (string-match "\\.kotl$" export-from)
		      (file-readable-p export-from))
		 (buffer-name (find-file-noselect export-from)))
		(t (error
		    "(kexport:html): `%s' is an invalid `export-from' argument" export-from))))
	 (output-to-buf
	  (cond ((or (bufferp output-to)
		     (get-buffer output-to))
		 (get-buffer output-to))
		((get-file-buffer output-to)
		 (get-file-buffer output-to))
		((stringp output-to)
		 (find-file-noselect output-to))
		(t (error
		    "(kexport:html): `%s' is an invalid `output-to' argument" output-to))))
	 (standard-output output-to-buf)
	 ;; Get any title attribute from cell 0, invisible root of the outline
	 (title (kcell:get-attr (kcell-view:cell-from-ref 0) 'title)))

    (with-current-buffer standard-output
      (font-lock-mode 0) ;; Prevent syntax highlighting
      (setq buffer-read-only nil
	    kexport:output-filename (hypb:buffer-file-name))
      (erase-buffer))
    (with-current-buffer export-buf-name
      (save-excursion
	(kotl-mode:beginning-of-buffer)
	(setq kexport:input-filename (hypb:buffer-file-name))

	;; If called interactively, prompt user for the title to use.
	(if (called-interactively-p 'interactive)
	    (setq title (read-string (format "Title for %s: " (buffer-name output-to-buf))
				     title))
	  ;; Otherwise, use any previously retrieved title attribute or if
	  ;; none, then the name of the current file sans the .kotl suffix.
	  (unless title
	    (setq title (file-name-sans-extension (file-name-nondirectory
						   (hypb:buffer-file-name)))))
	  (when (string-match "\n" title)
	    (setq title (substring title 0 (match-beginning 0)))))

	(princ "<!DOCTYPE html>\n")
	(princ "<html lang=\"en\">\n")

        ;; HEAD
        (princ "<head>\n")
        (princ (format "<title>%s</title>\n" title))

        (princ "<meta charset=\"utf-8\">\n\n")
	(if kexport:html-description
	    (princ (format "<meta name=\"description\" content=\"%s\">\n"
			   kexport:html-description)))
	(if kexport:html-keywords
	    (princ (format "<meta id=\"keywords\" content=\"%s\">\n"
			   kexport:html-keywords)))
	(princ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">")

	;; CSS
	(princ (format "<link rel=\"stylesheet\" href=\"%s\">\n" kexport:font-awesome-css-url))
	(princ kexport:font-awesome-css-include)

	(princ "</head>\n\n")

        ;; BODY
	(princ "<body>\n\n")
        (princ (format "<h1>%s</h1>\n\n" title))

	(let* ((separator
		(replace-regexp-in-string
		 ">" "&gt;"
		 (replace-regexp-in-string
		  "<" "&lt;" (kview:label-separator kotl-kview))))
               no-sibling-stack)

          (princ "<ul>\n")

	  (kview:map-tree
	   (lambda (_kview)
	     (let ((is-parent (kcell-view:child-p))
                   (is-last-sibling (not (kcell-view:sibling-p))))

               (princ (format "<!-- Level: %s, is-parent: %s, is-last-sibling: %s -->\n"
                              (kcell-view:level) is-parent is-last-sibling))
               (princ "<li>\n")

               (kexport:princ-cell is-parent separator soft-newlines-flag)

               (if is-parent
                   (progn
                     (princ "<ul>\n")
                     (push is-last-sibling no-sibling-stack))
                 (princ "</li>\n")
                 (when is-last-sibling
                   (princ "</ul>\n")
                   (princ "</li>\n")
                   (pop no-sibling-stack)
                   (while (pop no-sibling-stack)
                     (princ "</ul>\n")
                     (princ "</li>\n"))))))
	   kotl-kview t)

          (princ "</ul>\n")

	  ;; Remove any extra newline at the end of any <pre> text
	  (save-excursion
	    (goto-char (point-min))
	    (when (re-search-forward "\r?\n\\'" nil t)
	      (replace-match "" nil nil))))
	;; JavaScript
	(princ kexport:font-awesome-collapsible-javascript-btn)
	(princ "</body></html>\n")))
    (with-current-buffer standard-output
      (save-buffer))))