;;; rutils-rmd.el --- Rmarkdown transient      -*- lexical-binding: t; -*-

;; Copyright (C) 2021-2024  Shuguang Sun

;; Author: Shuguang Sun <shuguang79@qq.com>
;; Created: 2021/06/26
;; URL: https://github.com/ShuguangSun/rutils.el
;; Package-Requires: ((emacs "27.1") (ess "19") (transient "0.4"))
;; Keywords: convenience

;; This program 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.

;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; Rmarkdown transient.  Every command is generated by
;; `rutils-define-rcommand' from an explicit spec and sent through the
;; unified send layer (`rutils-send-r').

;;; Code:

(eval-when-compile
  (require 'cl-lib)
  (require 'subr-x))
(require 'rutils-lib)

(defgroup rutils-rmd nil
  "Rmd utilities with transient menu."
  :group 'rutils
  :prefix "rutils-rmd")


;;; * Generated commands

;;;###autoload (autoload 'rutils-rmd-knit "rutils-rmd" nil t)
(rutils-define-rcommand rutils-rmd-knit
  :r-call "knitr::knit"
  :group "Rmd::"
  :key "k"
  :doc "R knitr::knit."
  :args
  ((input   :key "i" :type file :arg "--input="
            :desc "The input .Rmd/.Rnw file.")
   (output  :key "o" :type file :arg "--output="
            :desc "The output file. Default NULL (next to input).")
   (tangle  :key "t" :type boolean :arg "--tangle"
            :desc "Tangle (extract code)? Default FALSE")
   (quiet   :key "q" :type boolean :arg "--quiet"
            :desc "Suppress progress messages? Default FALSE")))

;;;###autoload (autoload 'rutils-rmd-purl "rutils-rmd" nil t)
(rutils-define-rcommand rutils-rmd-purl
  :r-call "knitr::purl"
  :group "Rmd::"
  :key "p"
  :doc "R knitr::purl."
  :args
  ((input         :key "i" :type file :arg "--input="
                  :desc "The input .Rmd file.")
   (output        :key "o" :type file :arg "--output="
                  :desc "The output .R file. Default NULL.")
   (documentation :key "d" :type choice :arg "--documentation="
                  :desc "How much documentation to include."
                  :choices ("0" "1" "2"))))

;;;###autoload (autoload 'rutils-rmd-spin "rutils-rmd" nil t)
(rutils-define-rcommand rutils-rmd-spin
  :r-call "knitr::spin"
  :group "Rmd::"
  :key "i"
  :doc "R knitr::spin."
  :args
  ((hair   :key "h" :type file :arg "--hair="
           :desc "The input R script.")
   (knit   :key "k" :type boolean :arg "--knit"
           :desc "Knit the result? Default TRUE")
   (report :key "r" :type boolean :arg "--report"
           :desc "Create a report? Default TRUE")
   (format :key "f" :type choice :arg "--format="
           :desc "The output format."
           :choices ("Rmd" "Rnw" "Rhtml" "Rtex" "Rrst" "qmd"))))

;;;###autoload (autoload 'rutils-rmd-render "rutils-rmd" nil t)
(rutils-define-rcommand rutils-rmd-render
  :r-call "rmarkdown::render"
  :group "Rmd::"
  :key "r"
  :doc "R rmarkdown::render."
  :args
  ((input          :key "i" :type file :arg "--input="
                   :desc "The input .Rmd file.")
   (output_format  :key "o" :type string :arg "--output_format="
                   :desc "The output format, e.g. html_document.")
   (output_file    :key "f" :type file :arg "--output_file="
                   :desc "The output file name.")
   (output_dir     :key "d" :type directory :arg "--output_dir="
                   :desc "The output directory.")
   (runtime        :key "u" :type choice :arg "--runtime="
                   :desc "The runtime mode."
                   :choices ("auto" "static" "shiny" "shinyrmd" "shiny_prerendered"))
   (params         :key "a" :type string :arg "--params="
                   :desc "Parameters as a named list, e.g. list(a=1).")
   (clean          :key "c" :type boolean :arg "--clean"
                   :desc "Clean intermediate files? Default TRUE")
   (quiet          :key "q" :type boolean :arg "--quiet"
                   :desc "Suppress progress messages? Default FALSE")))

;;;###autoload (autoload 'rutils-rmd-render-site "rutils-rmd" nil t)
(rutils-define-rcommand rutils-rmd-render-site
  :r-call "rmarkdown::render_site"
  :group "Rmd::"
  :key "s"
  :label "render site"
  :doc "R rmarkdown::render_site."
  :args
  ((input         :key "i" :type directory :arg "--input="
                  :desc "The site directory. Default \".\".")
   (output_format :key "o" :type string :arg "--output_format="
                  :desc "The output format. Default \"all\".")
   (quiet         :key "q" :type boolean :arg "--quiet"
                  :desc "Suppress progress messages? Default FALSE")))


;;; * Main menu

;;;###autoload (autoload 'rutils-rmd "rutils-rmd" nil t)
(transient-define-prefix rutils-rmd ()
  "R Rmarkdown menu."
  [["knitr"
    ("k" "Knit"    rutils-rmd-knit)
    ("p" "Purl"    rutils-rmd-purl)
    ("i" "Spin"    rutils-rmd-spin)]
   ["rmarkdown"
    ("r" "Render"  rutils-rmd-render)
    ("s" "Site"    rutils-rmd-render-site)]])


(provide 'rutils-rmd)
;;; rutils-rmd.el ends here
