R/install.R

Defines functions install.cmake package_authors fetch_tag_from_Rd installr restart_RGui require2 source.https install.texmaker install.Texmaker install.github install.GitHub system.PATH install.ffmpeg install.FFmpeg install.7zip install.cygwin install.Cygwin install.latex2rtf install.LaTeX2RTF install.swftools install.SWFTools install.graphicsmagick install.GraphicsMagick install.imagemagick install.ImageMagick install.rstudio install.RStudio install.lyx install.LyX install.miktex install.MikTeX install.npptor install.notepadpp install.git ask.user.for.a.row check.integer install.pandoc install.URL havingIP uninstall.packages install.packages.zip up_folder file.name.from.url

Documented in ask.user.for.a.row check.integer fetch_tag_from_Rd file.name.from.url install.7zip install.cmake install.cygwin install.Cygwin install.ffmpeg install.FFmpeg install.git install.github install.GitHub install.graphicsmagick install.GraphicsMagick install.imagemagick install.ImageMagick install.latex2rtf install.LaTeX2RTF install.lyx install.LyX install.miktex install.MikTeX install.notepadpp install.npptor install.packages.zip install.pandoc installr install.rstudio install.RStudio install.swftools install.SWFTools install.texmaker install.Texmaker install.URL package_authors require2 restart_RGui source.https system.PATH uninstall.packages up_folder

# Copyright (C) Tal Galili
#
# This file is part of installr.
#
# installr 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 2 of the License, or
# (at your option) any later version.
#
# installr 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.
#
#  A copy of the GNU General Public License is available at
#  http://www.r-project.org/Licenses/
#



#' @title Extract the file name from some URL
#' @description Gets a character of link to some file, and returns the name of the file in this link.
#' @details
#' The install.packages.zip must use this function, since it is crucial that the name of the file into which the ZIPPED package is downloaded to the computer, will have the same name as the file which is online.
#' @param URL Some url to a file.
#' @param rm.params (optional, default=\code{FALSE}). Whether or not to remove query parameters from URL.
#' @return The name of the file in the URL
#' @export
#' @seealso \code{\link{install.URL}}, \code{\link{install.packages.zip}}
#' @examples
#' \dontrun{
#' url <- "https://cran.r-project.org/bin/windows/base/R-2.15.3-win.exe"
#' file.name.from.url(url) # returns: "R-2.15.3-win.exe"
#'
#' url <- "https://bioconductor.org/packages/R/genetics?version=5.01&f=gz"
#' file.name.from.url(url, rm.params=TRUE)  # returns: "genetics?version=5.01&f=gz"
#' file.name.from.url(url, rm.params=FALSE) # returns: "genetics"
#' file.name.from.url(url)                  # returns: "genetics"
#' }
file.name.from.url <- function(URL, rm.params=FALSE) {
    name <- basename(URL);
    if(rm.params) name <- gsub('^((?:(?!\\?).)*).*', '\\1', name, perl=TRUE);
    return(name);
};




#' @title Performs "up-level" on a folder string
#' @export
#' @description Gets a character vector of folder strings and
#'  returns the same vector after removing the end of the folder path.
#' @param FOLDER a character vector of folders
#' @param n passed to n in function \link{head}
#' @param ... not used.
#' @return The name of the file in the URL
#' @examples
#' up_folder(FOLDER = c("D:/R/R-3.0.1", "D:/R/R-3.0.2", "D:/R/R-3.0.3"))
up_folder <- function(FOLDER, n = -1,...) {
#    strsplit("a\\b/c",   "/|\\\\")
   splitted_folders <- lapply(FOLDER, strsplit,   split="/|\\\\")
   tailed_splitted_folders <- lapply(splitted_folders, function(x) {head(x[[1]], n = n)})
   sapply(tailed_splitted_folders, paste, collapse = "/")
}



#' @title Downloads and installs a ZIP R package Binary (for Windows) from a URL
#' @description Gets a character with a link to an R package Binary, downloads it, and installs it.
#' @details
#' To my knowledge, there is currently three ways to install packages on R:
#' 1. To get the package through a repository (such as CRAN or RForge) through install.packages.
#' 2. To manually download a ZIP file locally to the computer, and use install.packages on it.
#' 3. To get the package from github, by using devtools (but this will require you to first install RTools, and not everyone wishes to do it for just some package).
#' This function aims to combine option 1 and 2, by automatically downloading the ZIP file locally and then running install.packages on it. After being downloaded and installed, the binary is erased from the computer.
#' @param zip_URL a link to a ZIP R package Binary.
#' @return Invisible NULL
#' @export
#' @seealso \code{\link{install.packages}}, \code{\link[R.utils]{installPackages}}
#' @examples
#' \dontrun{
#' install.packages.zip("https://cran.r-project.org/bin/windows/contrib/r-release/devtools_1.1.zip")
#' }
install.packages.zip <- function(zip_URL) {
   name <- file.name.from.url(zip_URL, rm.params=TRUE);
   # Note: zip_URL does NOT need to be related at all to the URL for the package_name.zip file
   # see https://github.com/RLogik/utilsRL/blob/master/R/packages.r >> install.from.url for a more comprehensive solution.
   zip_filename <- file.path(tempdir(), name); 
   download.file(zip_URL, destfile=zip_filename, mode = 'wb');
   install.packages(pkgs=zip_filename, repos=NULL);
   unlink(zip_filename);
   invisible(NULL);
};
# a simple example of use:
# install.packages.zip(zip_URL="https://cran.r-project.org/bin/windows/contrib/r-release/TeachingSampling_2.0.1.zip")




#' @title uninstalls (removes) Installed Packages
#' @export
#' @description 
#' A wrapper for \link{remove.packages}. Useful since it also works if the
#' package is currently loaded into the workspace.
#' @param pkgs a character vector with the names of the packages to be removed.
#' @param lib a character vector giving the library directories to remove the packages from. 
#' If missing, defaults to the first element in \link{.libPaths}.
#' @param warning boolean (TRUE), should a message be printed in various cases.
#' @param ... currently ignored.
#' @return Invisible NULL
#' @seealso \code{\link{install.packages}}, \code{\link{remove.packages}},
#' \code{\link[installr]{install.packages.zip}}
#' @examples
#' \dontrun{
#' install.packages(c("reshape", "plyr"))
#' require(plyr)
#' uninstall.packages(c("reshape", "plyr"))
#' install.packages(c("reshape", "plyr"))
#' }
uninstall.packages <- function(pkgs,lib, warning = TRUE, ...) {   
   
   if(missing(lib)) lib <- .libPaths()[1]   
   
   uninstall_1_pkg <- function(pkg,lib,...) {      
      pkg_pkg <- paste("package:", pkg, sep = "")
      if (pkg_pkg %in% search()) { detach(pkg_pkg, unload=TRUE, character.only=TRUE) }
      if (pkg %in% rownames(installed.packages())) { 
         remove.packages(pkg,lib) 
      } else {
         if(warning) warning(paste("Package {", pkg , "}, was not installed in ", lib, "\n", sep=""))
      }
   }
   uninstall_n_pkg <- Vectorize(FUN=uninstall_1_pkg, vectorize.args=c("pkg"))
   
   uninstall_n_pkg(pkgs,lib,...)
   
   invisible(NULL)
}
# a simple example of use:
# install.packages.zip(zip_URL="https://cran.r-project.org/bin/windows/contrib/r-release/TeachingSampling_2.0.1.zip")



# source: https://stackoverflow.com/questions/5076593/how-to-determine-if-you-have-an-internet-connection-in-r
# checks if there is internet.
havingIP <- function() {
   if (.Platform$OS.type == "windows") {
      ipmessage <- system("ipconfig", intern = TRUE)
   } else {
      ipmessage <- system("ifconfig", intern = TRUE)
   }
   validIP <- "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
   any(grep(validIP, ipmessage))
}



#' @title Downloads and runs a .exe installer file for some software from a URL
#' @description Gets a character with a link to an installer file, downloads it, runs it, and then erases it.
#' @details
#' This function is used by many functions in the installr package.
#' The .exe file is downloaded into a temporary directory, where it is erased after installation has started (by default - though this can be changed)
#' @param exe_URL A character with a link to an installer file (with the .exe file extension)
#' @param keep_install_file If TRUE - the installer file will not be erased after it is downloaded and run.
#' @param wait should the R interpreter wait for the command to finish? The default is to NOT wait.
#' @param download_dir A character of the directory into which to download the file. (default is \link{tempdir}())
#' @param message boolean. Should a message on the file be printed or not (default is TRUE)
#' @param installer_option A character of the command line arguments
#' @param download_fun a function to use for downloading. Default is \link{download.file}. We can also use
#' \link[curl]{curl_download} (but it doesn't give as good of an output while downloading the file).
#' @param ... parameters passed to 'shell'
#' @return invisible(TRUE/FALSE) - was the installation successful or not. (this is based on the output of shell of running the command being either 0 or 1/2.  0 means the file was successfully installed, while 1 or 2 means there was a failure in running the installer.)
#' @seealso \link{shell}
#' @export
#' @author GERGELY DAROCZI, Tal Galili
#' @examples
#' \dontrun{
#' install.URL("adfadf") # shows the error produced when the URL is not valid.
#' }
install.URL <- function(exe_URL, keep_install_file = FALSE, wait = TRUE, download_dir = tempdir(), message = TRUE, installer_option = NULL, download_fun = download.file, ...) {
   # source: https://stackoverflow.com/questions/15071957/is-it-possible-to-install-pandoc-on-windows-using-an-r-command
   # input: a url of an .exe file to install
   # output: it runs the .exe file (for installing something)   
   
   
   if(!havingIP()) warning("You do not seem to be connected to the internet. Hence - you will likely not be able to download software.")
  
   if(!(is.character(exe_URL) && length(exe_URL) == 1)) {
     stop("exe_URL is not a single URL")
   }
   
   
   exe_filename <- file.path(download_dir, file.name.from.url(exe_URL))   # the name of the zip file MUST be as it was downloaded...   
   # tryCatch(curl::curl_download(exe_URL, destfile=exe_filename, quiet = FALSE, mode = 'wb'), 
   tryCatch(download_fun(exe_URL, destfile=exe_filename, quiet = FALSE, mode = 'wb'), 
                     error = function(e) {
               cat("\nExplanation of the error: You didn't enter a valid .EXE URL. \nThis is likely to have happened because there was a change in the URL of the installer file in the download page of the software (making our function unable to know what to download). \n\nThis might have already been fixed in the latest version of installr. Install the latest version of installr using devtools::install_github('talgalili/installr') and try again.\n\nIf this doesn't help please e-mail: tal.galili@gmail.com and let me know this function needs updating/fixing (please include the output of sessionInfo() ) - thanks!\n")
               return(invisible(FALSE))
               })  
   
   # check if we downloaded the file.
   if(file.exists(exe_filename)) {
      if(message) cat("\nThe file was downloaded successfully into:\n", exe_filename, "\n")
   } else {
      if(message) cat("\nWe failed to download the file into:\n", exe_filename, "\n(i.e.: the installation failed)\n")
      return(invisible(FALSE))      
   }
   
   if(!keep_install_file & !wait) {
      wait <- TRUE
      if(message) cat("wait was set to TRUE since you wanted to installation file removed. In order to be able to run the installer AND remove the file - we must first wait for the installer to finish running before removing the file.")
   }

   if(message) cat("\nRunning the installer now...\n")
   

   if(!is.null(installer_option)){
      install_cmd <- paste(exe_filename, installer_option)
   } else{
      install_cmd <- exe_filename
   }

   if(is.windows()) {
      shell_output <- shell(install_cmd, wait = wait,...) # system(exe_filename) # I suspect shell works better than system
   } else {
      shell_output <- system(install_cmd, wait = wait,...) # system(exe_filename) # I suspect shell works better than system
   }   
   if(!keep_install_file) {
      if(message) cat("\nInstallation status: ", shell_output == 0 ,". Removing the file:\n", exe_filename, "\n (In the future, you may keep the file by setting keep_install_file=TRUE) \n")
      unlink(exe_filename, force = TRUE) # on.exit(unlink(exe_filename)) # on.exit doesn't work in case of problems in the running of the file
   }
   # unlink can take some time until done, for some reason.
      #    file.remove(exe_filename)
      #    file.info(exe_filename)
      #    file.access(exe_filename, mode = 0)
      #    file.access(exe_filename, mode = 1)
      #    file.access(exe_filename, mode = 2)
      #    file.access(exe_filename, mode = 3)
   return(invisible(shell_output == 0))
   # error code 1/2 means that we couldn't finish running the file
   # # 0 means - the file was successfully installed.   
}



#' @title Downloads and installs pandoc
#' @description Downloads and installs the latest version of pandoc for Windows.
#' @details
#' pandoc is a free open source software for converting documents from many filetypes to many filetypes.  For details, see \url{https://johnmacfarlane.net/pandoc/}.
#' 
#' Credit: the code in this function is based on GERGELY DAROCZIs coding in his answer on the Q&A forum StackOverflow, and also G. Grothendieck for the non-XML addition to the function. 
#' I thank them both!
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @author GERGELY DAROCZI, G. Grothendieck, Tal Galili
#' @param URL a link to the list of download links of pandoc
#' @param use_regex (default TRUE) - deprecated (kept for legacy purposes).
#' @param to_restart boolean. Should the computer be restarted 
#'  after pandoc is installed? (if missing then the user is prompted 
#' 	for a decision)
#' @param ... extra parameters to pass to \link{install.URL}
#' @source \url{https://stackoverflow.com/questions/15071957/is-it-possible-to-install-pandoc-on-windows-using-an-r-command}
#' @examples
#' \dontrun{
#' install.pandoc() 
#' }
install.pandoc <- function(
   URL = 'https://github.com/jgm/pandoc/releases',
   use_regex = TRUE, to_restart,...
) {
   page_with_download_url <- URL
   # source: https://stackoverflow.com/questions/15071957/is-it-possible-to-install-pandoc-on-windows-using-an-r-command
   # published on: https://www.r-statistics.com/2013/02/installing-pandoc-from-r-on-windows/
   
   # https://github.com/jgm/pandoc/releases/download/1.12.4/pandoc-1.12.4.msi.Windows.installer.msi
   
   if(!use_regex) warning("use_regex is no longer supported, you can stop using it from now on...")
   
      page     <- readLines(page_with_download_url, warn = FALSE)
      #"//pandoc.googlecode.com/files/pandoc-1.11.1.msi"
      # https://github.com/jgm/pandoc/releases/download/1.12.4/pandoc-1.12.4-windows.msi
      # https://github.com/jgm/pandoc/releases/download/1.12.4.2/pandoc-1.12.4.2-1-windows.msi
#    pat <- "jgm/pandoc/releases/download/[0-9.]+/pandoc-[0-9.]+-windows\\.msi"
   #pat <- "jgm/pandoc/releases/download/[0-9.]+/pandoc-[0-9.-]+-windows\\.msi"
	sysArch <- Sys.getenv("R_ARCH") 
	sysArch <-  gsub("/ |/x", "", sysArch)
  	pat <- paste0("jgm/pandoc/releases/download/[0-9.]+/pandoc-[0-9.-]+-windows",".*", sysArch, ".*", ".msi")
   #    grep(pat, page, value = TRUE, fixed = F)
#    glob2rx("jgm/pandoc/releases/download/1.12.4/pandoc-1.12.4.msi.Windows.installer.msi")
#    grep("aaa[:graph:]*", "aaasdfadsfa  adaf / sdfa", value = TRUE)
   
      target_line <- grep(pat, page, value = TRUE)
      m <- regexpr(pat, target_line); 
      URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
      URL      <- head(URL,1)
# https://github.com/jgm/pandoc/releases/download/1.12.4/pandoc-1.12.4.msi.Windows.installer.msi
      URL      <- paste('https://github.com/', 
                        URL, 
#                         ".Windows.installer.msi",
                        sep = '')
   
   installed <- install.URL(URL,...)
   
   # if the installation failed, no need to ask about restarting the computer!
   if(!installed) return(invisible(FALSE))
   
   if(missing(to_restart)) {
	   if(is.windows()) {
			you_should_restart <- "You should restart your computer\n in order for pandoc to work properly"
		  winDialog(type = "ok", message = you_should_restart)
		  choices <- c("Yes", "No")
		  question <- "Do you want to restart your computer now?"
		  the_answer <- menu(choices, graphics = "TRUE", title = question)
		  to_restart <- the_answer == 1L 
		}   else {
			to_restart <- FALSE
		}
	}
   if(to_restart) os.restart()
   
}

#' @title Check if a number is integer
#' @description Returns TRUE/FALSE on whether a number is integer or not.
#' @details
#' Surprising as it may be, R doesn't come with a handy function to check if the number is integer.
#' This function does just this.
#' @param N A number (if a vector is supplied only the first element is checked - without warning)
#' @return TRUE/FALSE on whether a number is integer or not.
#' @author VitoshKa
#' @source \url{https://stackoverflow.com/questions/3476782/how-to-check-if-the-number-is-integer}
#' @examples
#' check.integer <- installr:::check.integer
#' check.integer(4) # TRUE
#' check.integer(3243) #TRUE
#' check.integer(3243.34) #FALSE
#' check.integer("sdfds") #FALSE
#' check.integer(1e4) #TRUE
#' check.integer(1e6) #TRUE
#' check.integer(1e600) #FALSE - the function is having a hardtime with Inf...
#' rm(check.integer)
check.integer <- function(N){
   # source: https://stackoverflow.com/questions/3476782/how-to-check-if-the-number-is-integer
   # author: VitoshKa
   
   # notice that the function "is.integer" is used by based R for checking the object if it is of type integer.
   
   # TODO: one day - to vectorize this.
   
   !length(grep("[^[:digit:]]", format(N[1], scientific = FALSE)))
}
# check.integer(3)


#' @title Asks the user for a row number from a data.frame table
#' @description The function gets a data.frame and asks the user to choose a row number.  Once choosen, that row number is returned from the function.
#' @details
#' This function is used in \code{installr} when we are not sure what version of the software to download, or when various actions are available for the user to choose from.
#' If the user doesn't give a valid row number, the function repeats its questions until a valid row number is chosen (or the user escapes)
#' @param TABLE a data.frame table with rows from which we wish the user to choose a row.  If TABLE is not a data.frame, it will be coerced into one.
#' @param header_text the text the users sees (often a question) as a title for the printed table - explaining which row they should choose from
#' @param questions_text the question the users see after the printing of the table - explaining which row they should choose from.
#' (the default is: "Please review the table of versions 
#' from above, and enter the row number of the file-version 
#' you'd like to install: ")
#' @return The row number the user has choosen from the data.frame table.
#' @source On how to ask the user for input:
#' 
#' \url{https://stackoverflow.com/questions/5974967/what-is-the-correct-way-to-ask-for-user-input-in-an-r-program}
#' @examples
#' \dontrun{
#' version_table <- data.frame(versions = c("devel", "V 1.0.0", "V 2.0.0"))
#' installr:::ask.user.for.a.row(version_table)
#' }
ask.user.for.a.row <- function(TABLE, 
                               header_text = "Possible versions to download (choose one)",
                               questions_text) {
   # https://stackoverflow.com/questions/5974967/what-is-the-correct-way-to-ask-for-user-input-in-an-r-program
   # based on code by Joris Meys

   if(missing(questions_text)) questions_text <- "Please review the table of versions from above,
and enter the row number of the file-version you'd like to install: "

   if(!inherits(TABLE,"data.frame")) {
      TABLE <- as.data.frame(TABLE)
      colnames(TABLE)[1] <- "Choose:"
   }
   
   rownames(TABLE) <- seq_len(nrow(TABLE))# makes sure that the table's row names are in the "rownames"
   
   correct_input <- F
   nrow_TABLE <- nrow(TABLE)
   
   while(!correct_input){# n is the row number from the user
      cat("=============",header_text,"====================\n")      
      print(TABLE)
      ROW_id <- readline(questions_text)
      ROW_id <- as.numeric(ROW_id)
      correct_input <- 
         !is.na(ROW_id) && # don't check other condition if this is not met.
         check.integer(ROW_id) & # is integer AND
         ROW_id >= 1 & # make sure our ROW_id is within range (between 1 and the number of rows in the table)
         ROW_id <= nrow_TABLE
      if(!correct_input) cat("Wrong input: Please enter a valid number (integer, between 1 to the number of rows) \n  for the row number of your choice\n")
      # if(is.na(n)){break}  # breaks when hit enter
   }
   
   ROW_id
}
# version_table <- data.frame(versions = c("devel", "V 1.0.0", "V 2.0.0"))
# ask.user.for.a.row(version_table)















#' @title Downloads and installs git and git-gui for windows
#' @description Allows the user to downloads and install the latest version of git for Windows.
#' @details
#' Git is a distributed revision control and source code management system with an emphasis on speed.
#' @param URL the URL of the git download page.
#' @param version numeric - either 32 or 64 (default)
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' git homepage: \url{https://git-scm.com/}
#' git download page: \url{https://git-scm.com/download/win}
#' @examples
#' \dontrun{
#' install.git() # installs the latest version of git
#' }
install.git <- function(URL="https://git-scm.com/download/win", version = 64, ...) {
   # "https://git-scm.com/download/win"
   # get download URL:
   page     <- readLines(URL, warn = FALSE)
   # https://msysgit.googlecode.com/files/Git-1.8.1.2-preview20130201.exe
#    pat <- "//msysgit.googlecode.com/files/Git-[0-9.]+-preview[0-9.]+.exe"; 
# https://github.com/msysgit/msysgit/releases/download/Git-1.9.4-preview20140611/Git-1.9.4-preview20140611.exe
   # https://github.com/git-for-windows/git/releases/download/v2.6.2.windows.1/Git-2.6.2-64-bit.exe
   pat <- paste0("//github.com/git-for-windows/git/releases/download/v[0-9.]+.windows[0-9.]+/Git-[0-9.]+-",version,"-bit.exe"); 
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   URL      <- paste('https', URL, sep = ':')[1] # we might find the same file more than once - so we'll only take its first one
# https://github.com/msysgit/msysgit/releases/download/Git-1.9.4-preview20140611/Git-1.9.4-preview20140611.exe
   # install.
   install.URL(URL[1],...)   
}







#' @title Downloads and installs Notepad++ for windows
#' @description Allows the user to downloads and install the latest version of Notepad++ for Windows.
#' @details
#' Notepad++ is a free (as in "free speech" and also as in "free beer") source code editor and Notepad replacement that supports several languages. Running in the MS Windows environment, its use is governed by GPL License.
#' Based on the powerful editing component Scintilla, Notepad++ is written in C++ and uses pure Win32 API and STL which ensures a higher execution speed and smaller program size. By optimizing as many routines as possible without losing user friendliness, Notepad++ is trying to reduce the world carbon dioxide emissions. When using less CPU power, the PC can throttle down and reduce power consumption, resulting in a greener environment.
#' @param page_with_download_url the URL of the Notepad++ download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return invisible TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' homepage: \url{https://notepad-plus-plus.org/}
#' download page: \url{https://notepad-plus-plus.org/downloads/}
#' @examples
#' \dontrun{
#' install.notepadpp() # installs the latest version of Notepad++
#' }
install.notepadpp <- function(page_with_download_url="https://notepad-plus-plus.org/downloads/",...) {
   # "https://git-scm.com/download/win"
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # OLD: http://download.tuxfamily.org/notepadplus/6.3.1/npp.6.3.1.Installer.exe
   # https://notepad-plus-plus.org/repository/6.x/6.7.8.2/npp.6.7.8.2.Installer.exe
   pat <- "repository/[0-9.]+.x/[0-9.]+/npp.[0-9.]+.Installer.exe"
   target_line <- grep(pat, page, value = TRUE) 
   m <- regexpr(pat, target_line); 
   URL <- regmatches(target_line, m) # (The http still needs to be prepended.
   
   URL <- paste0("https://notepad-plus-plus.org/", URL)
   
   
   # install.
   install.URL(URL,...)   
}






#' @title Downloads and installs NppToR for windows
#' @description Allows the user to downloads and install the latest version of NppToR extension for Notepad++ for Windows.
#' @details
#' Similar to the windows R gui built in editor, NppToR aims to extend the functionality of code passing to the Notepad++ code editor. In addition to passing to the R gui, NppToR provides optional passing to a PuTTY window for passing to an R instance a remote machine.
#' 
#' NppToR is a companion utility that facilitates communication between R and Notepad++. It provides code passing from Notepad++ into the windows R Gui. NppToR also provides an autocompletion database which is dynamically generated from the users' R library of packages, thanks to an addition by Yihui Xie. Notepad++ provides built it R code highlighting and folding.
#' @param URL the URL of the Notepad++ download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return invisible TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' download page: \url{https://sourceforge.net/projects/npptor/}
#' @examples
#' \dontrun{
#' install.npptor() # installs the latest version of NppToR
#' }
install.npptor <- function(URL="http://sourceforge.net/projects/npptor/files/npptor%20installer/",...) {
   page_with_download_url <- URL
   # "https://git-scm.com/download/win"
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # /npptor installer/NppToR-2.6.2.exe
   # http://sourceforge.net/projects/npptor/files/npptor%20installer/NppToR-2.6.2.exe/
   # http://sourceforge.net/projects/npptor/files/npptor%20installer/NppToR-[0-9.]+.exe
   # pat <- "http://sourceforge.net/projects/npptor/files/npptor%20installer/NppToR-[0-9.]+.exe"
   
   # http://downloads.sourceforge.net/project/npptor/npptor%20installer/NppToR-2.6.4.exe
   
   if(!requireNamespace("stringr")) {
      cat("The package 'stringr' is missing - trying to install it")
      install.packages("stringr")
      requireNamespace("stringr")
   }
   
   pat <- "NppToR-[0-9.]+.exe" # I assume the first option on the page is the most up-to-date
   filename <- na.omit(stringr::str_extract(page, pat))[1]
   URL      <- paste0("http://downloads.sourceforge.net/project/npptor/npptor%20installer/",
                      filename)
   
   
   cat("Please wait a moment while downloading (you may not see R respond for half a minute)\n ")
   if(!requireNamespace("curl")) {
      cat("The package 'curl' is missing - trying to install it")
      install.packages("curl")
      requireNamespace("curl")
   }
   install.URL(URL, download_fun = curl::curl_download, ...)
   
   # download.file("http://downloads.sourceforge.net/project/npptor/npptor%20installer/NppToR-2.7.0.exe",
   #             destfile="c:\\temp.exe", mode = 'wb')
   
}



#' @title Downloads and installs MikTeX for windows
#' @aliases install.miktex
#' @description Allows the user to downloads and install the latest version of MikTeX for Windows.
#' @details
#' MiKTeX is a typesetting system for Microsoft Windows that is developed by Christian Schenk. It consists of an implementation of TeX and a set of related programs. MiKTeX provides the tools necessary to prepare documents using the TeX/LaTeX markup language, as well a simple tex editor (TeXworks).
#' 
#' MiKTeX is essential for using Sweave, knitr, and creating Vignette for R packages.
#' @param page_with_download_url the URL of the MikTeX download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' MikTeX homepage: \url{http://miktex.org/}
#' MikTeX download page: \url{http://miktex.org/download}
#' @examples
#' \dontrun{
#' install.MikTeX() # installs the latest version of MikTeX 62 bit
#' }
install.MikTeX  <- function(page_with_download_url="https://miktex.org/download", ...) {
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # cat(page, sep = "\n")
   # The damn url keeps changing...
   #"http://mirrors.ctan.org/systems/win32/miktex/setup/basic-miktex-2.9.4757.exe
   # "http://mirrors.ctan.org/systems/win32/miktex/setup/basic-miktex-2.9.4757-x64.exe"
   # http://ctan.mirror.ftn.uns.ac.rs/systems/win32/miktex/setup/basic-miktex-2.9.6069-x64.exe
   # https://miktex.org/download/ctan/systems/win32/miktex/setup/windows-x64/basic-miktex-2.9.6615-x64.exe
   # I'm noticing that the one thing that doesn't change is that it is a .exe link - so let's only rely on this.
   # https://miktex.org/download/ctan/systems/win32/miktex/setup/windows-x64/basic-miktex-2.9.6942-x64.exe
   pat <- "download.*basic.*64.*.exe"; 
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL <- regmatches(target_line, m) # (The http still needs to be prepended.
   URL <- URL[1] # use basic instead of setup
   URL <- paste0("https://miktex.org/", URL)
   # install.URL(URL)   
   install.URL(URL,...)   
}

#' @export
install.miktex <- function(...) install.MikTeX(...)





#' @title Downloads and installs LyX for windows
#' @aliases install.lyx
#' @description Allows the user to downloads and install the latest version of LyX for Windows.
#' @details
#' LyX is an advanced open source document processor running on Linux/Unix, Windows, and Mac OS X.
#' It is called a "document processor", because unlike standard word processors, LyX encourages an approach to writing based on the structure of your documents, not their appearance.#' 
#' LyX lets you concentrate on writing, leaving details of visual layout to the software.
#' LyX automates formatting according to predefined rule sets, yielding consistency throughout even the most complex documents.
#' LyX produces high quality, professional output - using LaTeX, an open source, industrial strength typesetting engine, in the background. 
#' @param page_with_download_url the URL of the LyX download page.
#' @param new_installation boolean. TRUE means we should make a new installation of LyX. FALSE means to update an existing installation.  Missing - prompts the user to decide.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item LyX homepage: \url{http://www.lyx.org/}
#' } 
#' @examples
#' \dontrun{
#' install.LyX() # installs the latest version of LyX
#' }
install.LyX  <- function(page_with_download_url="http://www.lyx.org/Download", new_installation, ...) {    

   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   
   
   # decide which version to get:
   if(missing(new_installation) || is.logical(new_installation)) {
      choices <- c("New: install a new version of LyX",
                   "Update: update an existing installation of LyX")   
      the_answer <- menu(choices, graphics = FALSE, title = "Do you wish a new installation of LyX\n or an update to an existing installation?")                  
   } else {
      the_answer <- ifelse(new_installation, 1, 2)
   }

   pat <-    switch(the_answer,           
                    "ftp://ftp.lyx.org/pub/lyx/bin/[0-9.]+/LyX-[0-9.]+-Bundle-[0-9.]+.exe",
                    "ftp://ftp.lyx.org/pub/lyx/bin/[0-9.]+/LyX-[0-9.]+-Installer-[0-9.]+.exe"
                  )   
   
   # ftp://ftp.lyx.org/pub/lyx/bin/2.0.5.1/LyX-2.0.5.1-Bundle-4.exe
   # URL = "ftp://ftp.lyx.org/pub/lyx/bin/2.0.5.1/LyX-2.0.5.1-Installer-4.exe"
   # install.URL(URL)
   
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   
   # install.
   install.URL(URL,...)   
}


#' @export
install.lyx <- function(...) install.LyX(...)



#' @title Downloads and installs RStudio for windows
#' @aliases install.rstudio
#' @description Allows the user to downloads and install the latest version of RStudio for Windows.
#' @details
#' RStudio is a free and open source integrated development environment (IDE) for R, a programming language for statistical computing and graphics.
#' @param page_with_download_url the URL of the RStudio download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item RStudio homepage: \url{https://posit.co/}
#' } 
#' @examples
#' ### devtools::source_url
#' \dontrun{
#' install.RStudio() # installs the latest version of RStudio
#' }
install.RStudio  <- function(page_with_download_url, ...) {    
   if(missing(page_with_download_url)) page_with_download_url <- "https://www.rstudio.com/products/rstudio/download/#download"
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # http://download1.rstudio.org/RStudio-0.97.318.exe#
   # https://download1.rstudio.org/desktop/windows/RStudio-1.2.1335.exe
   pat <- "http.*.rstudio.org/.*/RStudio-[0-9.]+.exe"
   target_line <- grep(pat, page, value = TRUE)
   m <- regexpr(pat, target_line)
   URL <- unique(regmatches(target_line, m))
   
   if(length(URL) != 1) {
      message("You'll need to go to the site and download this yourself. I'm now going to try and open the url for you.")
      browseURL(page_with_download_url)
      return(FALSE)
   }
   
   # install.
   install.URL(URL,...)   
}

#' @export
install.rstudio <- function(...) install.RStudio(...)



#' @title Downloads and installs ImageMagick for windows
#' @aliases install.imagemagick
#' @description Allows the user to downloads and install the latest version of ImageMagick for Windows.
#' @details
#' ImageMagick is a software suite to create, edit, compose, or convert bitmap images. It can read and write images in a variety of formats (over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF. Use ImageMagick to resize, flip, mirror, rotate, distort, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bezier curves.
#' This function downloads Win32 dynamic at 16 bits-per-pixel.
#' @param URL the URL of the ImageMagick download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item ImageMagick homepage: \url{http://www.imagemagick.org/script/index.php}
#' } 
#' @examples
#' \dontrun{
#' install.ImageMagick() # installs the latest version of ImageMagick
#' }
install.ImageMagick  <- function(URL="https://www.imagemagick.org/script/download.php",...) {    
   page_with_download_url <- URL
   # get download URL:
   # cat(page)
   page     <- readLines(page_with_download_url, warn = FALSE)
   # https://imagemagick.org/download/binaries/ImageMagick-7.0.10-23-Q16-HDRI-x64-dll.exe
   pat <- "http.+imagemagick.org.+download/binaries.+exe"
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL <- regmatches(target_line, m) # (The http still needs to be prepended.
   URL <- URL[1] # take the first option that comes up
   # install.
   install.URL(URL,...)   
}

#' @export
install.imagemagick <- function(...) install.ImageMagick(...)



#' @title Downloads and installs GraphicsMagick for windows
#' @aliases install.graphicsmagick
#' @description Allows the user to downloads and install the latest version of GraphicsMagick for Windows.
#' @details
#' GraphicsMagick is the swiss army knife of image processing. Comprised of 282K physical lines (according to David A. Wheeler's SLOCCount) of source code in the base package (or 964K including 3rd party libraries) it provides a robust and efficient collection of tools and libraries which support reading, writing, and manipulating an image in over 88 major formats including important formats like DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF.
#' This function downloads Win32 dynamic at 16 bits-per-pixel.
#' No direct file is available to run, You'll need to open/run the file that your browser is now downloading.
#' @param URL the URL of the ImageMagick download page.
#' @param ... deprecated
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item GraphicsMagick homepage: \url{http://www.graphicsmagick.org/}
#' } 
#' @examples
#' \dontrun{
#' install.GraphicsMagick() # installs the latest version of GraphicsMagick
#' }
install.GraphicsMagick  <- function(URL="https://sourceforge.net/projects/graphicsmagick/files/latest/download",...) {    
   
   # page_with_download_url <- URL
   # # get download URL:
   # page     <- readLines(page_with_download_url, warn = FALSE)
   # # http://downloads.sourceforge.net/project/graphicsmagick/graphicsmagick-binaries/1.3.17/GraphicsMagick-1.3.17-Q16-windows-dll.exe?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fgraphicsmagick%2Ffiles%2F&ts=1362862824&use_mirror=garr
   # # http://sourceforge.net/projects/graphicsmagick/files/graphicsmagick-binaries/1.3.17/GraphicsMagick-1.3.17-Q8-windows-dll.exe/download
   # pat <- "//sourceforge.net/projects/graphicsmagick/files/graphicsmagick-binaries/[0-9.]+/GraphicsMagick-[0-9.]+-Q16-windows-dll.exe"
   # target_line <- grep(pat, page, value = TRUE); 
   # m <- regexpr(pat, target_line); 
   # URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   # URL      <- paste('http', URL, sep = ':')[1] # we might find the same file more than once - so we'll only take its first one
   # 
   # # install.
   # install.URL(URL,...)   
   browseURL(URL)
   message("No direct file is available to run, You'll need to open/run the file that your browser is now downloading.")
}

#' @export
install.graphicsmagick <- function(...) install.GraphicsMagick(...)



#' @title Downloads and installs SWFTools for windows
#' @aliases install.swftools
#' @description Allows the user to downloads and install the latest version of SWFTools for Windows.
#' @details
#' SWFTools is a collection of utilities for working with Adobe Flash files (SWF files). The tool collection includes programs for reading SWF files, combining them, and creating them from other content (like images, sound files, videos or sourcecode). SWFTools is released under the GPL. 
#' This function downloads current releases and NOT the Development Snapshots.
#' This function is useful for saveSWF() in the {animation} package.
#' @param page_with_download_url the URL of the SWFTools download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item SWFTools homepage: \url{http://swftools.org/}
#' } 
#' @examples
#' \dontrun{
#' install.SWFTools() # installs the latest version of SWFTools
#' }
install.SWFTools  <- function(page_with_download_url="http://swftools.org/download.html",...) {    
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # http://swftools.org/swftools-0.9.0.exe
   pat <- "swftools-[0-9.]+.exe"
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   URL      <- paste('http://swftools.org/', URL, sep = '')[1] # we might find the same file more than once - so we'll only take its first one
   
   # install.
   install.URL(URL,...)   
}

#' @export
install.swftools <- function(...) install.SWFTools(...)



#' @title Downloads and installs LaTeX2RTF for windows
#' @aliases install.latex2rtf
#' @description Allows the user to downloads and install the latest version of LaTeX2RTF for Windows.
#' @details
#' Latex2rtf tries to convert your LaTeX file into a RTF file for opening in Microsoft Word. The general idea is to try and get the things that computers are good at correct: character conversion, graphic conversion, etc. Page layout suffers because control in RTF is pretty pathetic compared to TeX. Consequently, it is likely that manual reformatting will be needed.
#' @param page_with_download_url the URL of the SWFTools download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item SWFTools homepage: \url{https://latex2rtf.sourceforge.net/}
#' } 
#' @examples
#' \dontrun{
#' install.LaTeX2RTF() # installs the latest version of LaTeX2RTF
#' }
install.LaTeX2RTF  <- function(page_with_download_url="http://sourceforge.net/projects/latex2rtf/",...) {    
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   #   http://sourceforge.net/projects/latex2rtf/files/latex2rtf-win/2.3.3/latex2rtf-2.3.3_win.exe/download
   pat <- "http://sourceforge.net/projects/latex2rtf/files/latex2rtf-win/[0-9.]+/latex2rtf-[0-9.]+_win.exe"
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   # install.
   install.URL(URL,...)   
}

#' @export
install.latex2rtf <- function(...) install.LaTeX2RTF(...)





#' @title Downloads and installs Cygwin for windows
#' @aliases install.cygwin
#' @description Allows the user to downloads and install the latest version of Cygwin for Windows.
#' @details
#' Cygwin is a collection of tools which provide a Linux look and feel environment for Windows.
#' @param bit Specify 32 bit or 64 for your particular version of Windows.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item Cygwin homepage: https://www.cygwin.com/
#' } 
#' @examples
#' \dontrun{
#' install.Cygwin() # installs the latest version of Cygwin
#' }
install.Cygwin  <- function(bit = 32, ...) {    
#    # get download URL:
#    page     <- readLines(page_with_download_url, warn = FALSE)
#    # http://swftools.org/swftools-0.9.0.exe
#    pat <- "swftools-[0-9.]+.exe"
#    target_line <- grep(pat, page, value = TRUE); 
#    m <- regexpr(pat, target_line); 
#    URL      <- regmatches(target_line, m) # (The http still needs to be prepended.   
   # install.
   if(bit == 32){
      install.URL("http://cygwin.com/setup-x86.exe", ...)
   }

   if(bit == 64){
      install.URL("http://cygwin.com/setup-x86_64.exe", ...)
   }

}

#' @export
install.cygwin <- function(...) install.Cygwin(...)






#' @title Downloads and installs 7-Zip for windows
#' @description Allows the user to downloads and install the latest version of 7-Zip for Windows.
#' @details
#' 7-Zip is open source software. Most of the source code is under the GNU LGPL license. The unRAR code is under a mixed license: GNU LGPL + unRAR restrictions. Check license information here: 7-Zip license.
#' You can use 7-Zip on any computer, including a computer in a commercial organization. You don't need to register or pay for 7-Zip.
#' *The main features of 7-Zip
#' *High compression ratio in 7z format with LZMA and LZMA2 compression
#' *Supported formats:
#' **Packing / unpacking: 7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM
#' **Unpacking only: ARJ, CAB, CHM, CPIO, CramFS, DEB, DMG, FAT, HFS, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, RAR, RPM, SquashFS, UDF, VHD, WIM, XAR and Z.
#' For ZIP and GZIP formats, 7-Zip provides a compression ratio that is 2-10 % better than the ratio provided by PKZip and WinZip
#' *Strong AES-256 encryption in 7z and ZIP formats
#' *Self-extracting capability for 7z format
#' *Integration with Windows Shell
#' *Powerful File Manager
#' *Powerful command line version
#' *Plugin for FAR Manager
#' *Localizations for 79 languages
#' 
#' @param page_with_download_url the URL of the 7-Zip download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item 7-zip homepage: \url{https://www.7-zip.org/}
#' } 
#' @examples
#' \dontrun{
#' install.7zip() # installs the latest version of 7-Zip
#' }
install.7zip  <- function(page_with_download_url="https://www.7-zip.org/download.html",...) {    
   # get download URL:
   page     <- readLines(page_with_download_url, warn = FALSE)
   # http://downloads.sourceforge.net/sevenzip/7z920.exe
   pat <- "7z[0-9.]+.exe"
   target_line <- grep(pat, page, value = TRUE); 
   m <- regexpr(pat, target_line); 
   URL      <- regmatches(target_line, m) # (The http still needs to be prepended.
   URL      <- paste('http://downloads.sourceforge.net/sevenzip/', URL, sep = '')[1] # we might find the same file more than once - so we'll only take its first one
   
   # install.
   install.URL(URL,...)   
}


# 
# # ' @title Unzips a file using 7z
# # ' @param page_with_download_url the URL of the FFmpeg download page.
# # ' @param ... NOT used
# # ' @return the shell output of 7z
# # ' @references
# # ' \url{https://stackoverflow.com/questions/14122732/unzip-files-7-zip-via-cmd-command}
# # ' @examples
# # ' \dontrun{
# # ' 
# # ' }
# un7zip <- function(zip_file, the_7zip_path = "C:\\Program Files (x86)\\7-Zip\\",...)
# {
#    shell(paste("'",the_7zip_path,"7z.exe' -x '", a_7z_filename, "'", sep = ""), intern = TRUE, translate = TRUE)
# }
# # This function doesn't quite work...




#' @title Downloads and installs FFmpeg for windows
#' @aliases install.ffmpeg
#' @description Allows the user to downloads the latest version of FFmpeg for Windows.
#' IMPORTANT NOTE: The user (YOU) are responsible for unpacking the 7zip file into the relevant directory.  All that this function does is to download the 7zip file and "run" it.
#' @details
#' FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. See the documentation for a complete feature list and the Changelog for recent changes.
#' This function downloads current releases and NOT the Development Snapshots.
#' This function is useful for saveVideo() in the {animation} package.
#' @param page_with_download_url the URL of the FFmpeg download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return NULL
#' @export
#' @references
#' \itemize{
#' \item FFmpeg homepage: \url{http://FFmpeg.org/}
#' } 
#' @examples
#' \dontrun{
#' install.FFmpeg() # installs the latest version of FFmpeg 
#' }
install.FFmpeg   <- function(page_with_download_url="http://ffmpeg.zeranoe.com/builds/",...) {    
   URL      <- "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-latest-win32-static.7z" # it's always the same URL. The challange is to extract the 7z from it.
   a_7z_filename <- file.path(tempdir(), file.name.from.url(URL))   # the name of the zip file MUST be as it was downloaded...
   download.file(URL, destfile=a_7z_filename, mode = 'wb') # Downloads the 7zip file

   shell(a_7z_filename,wait=FALSE)
   NULL
}

#' @export
install.ffmpeg <- function(...) install.FFmpeg(...)






#' @title Returns the search path for executable files
#' @export
#' @description Returns the search path for executable files based on %PATH%
#' @return A character vector with the search path for executable files
#' @references
#'  http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true
#' @examples
#' \dontrun{
#' system.PATH() # 
#' }
system.PATH <- function() strsplit(shell("echo %PATH% ", intern= TRUE), ";")[[1]]


 
# ' @title Extends the current path with more possible softwares
# ' @description Useful for adding new softwares to the current search path
# ' @param exe_folder the folder where the relevant .exe file is.
# ' @return The updated search PATH
# ' @references
# ' \url{https://stackoverflow.com/questions/14122732/unzip-files-7-zip-via-cmd-command}
# ' \dontrun{
# ' set.PATH("C:\\Program Files (x86)\\7-Zip\\")
# ' is.exe.installed("7z") 
# ' }
# set.PATH <- function(exe_folder){
#    shell(paste('setx PATH=%PATH%;',exe_folder, sep = ""))         
#    system.PATH()
# }





#' @title Downloads and installs GitHub for windows
#' @aliases install.github
#' @description Allows the user to downloads and install the latest version of GitHub for Windows.
#' @details
#' "The easiest way to use Git on Windows." (at least so they say...)
#' @param URL the URL of the GitHub download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item GitHub homepage: \url{https://github.com/}
#' \item GitHub for windows download page: \url{https://desktop.github.com/}
#' } 
#' @examples
#' \dontrun{
#' install.GitHub() # installs the latest version of GitHub for windows
#' }
install.GitHub <- function(URL = "http://github-windows.s3.amazonaws.com/GitHubSetup.exe",...) {
   # https://help.github.com/articles/set-up-git
   install.URL(URL,...)
}

#' @export
install.github <- function(...) install.GitHub(...)






#' @title Downloads and installs Texmaker for windows
#' @aliases install.texmaker
#' @description Allows the user to downloads and install the latest version of Texmaker for Windows.
#' @details
#' Texmaker is a free, modern and cross-platform LaTeX editor for linux,
#' macosx and windows systems that integrates many tools needed to develop
#' documents with LaTeX, in just one application.
#' @param URL the URL of the GitHub download page.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return logical - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item Texmaker homepage: \url{http://www.xm1math.net/texmaker/}
#' } 
#' @examples
#' \dontrun{
#' install.Texmaker() # installs the latest version of Texmaker for windows
#' }
install.Texmaker <- function(URL = "http://www.xm1math.net/texmaker/texmakerwin32_install.exe",...) {
   install.URL(URL,...)
}

#' @export
install.texmaker <- function(...) install.Texmaker(...)



#' @title Read R Code from a File in an https URL
#' @description source.https causes R to accept its input from a File in an https URL.
#' Input is read and parsed from that file until the end of the file is reached, then the parsed expressions are evaluated sequentially in the chosen environment.
#' @details
#' "The easiest way to use Git on Windows." (at least so they say...)
#' @param URL the URL of the .r file to download and source.
#' @param ... parameters to pass to \link{source}
#' @param remove_r_file if to remove the .r file after it was sourced.
#' @return Nothing.
#' @export
#' @seealso \link{source}
#' @references
#' Other solutions to the source.https problem:
#' \itemize{
#' \item Using RCurl
#' \item devtools::source_url 
#' \item A relevant (OLD) discussion: https://stackoverflow.com/questions/7715723/sourcing-r-script-over-https
#' }
#' @examples
#' \dontrun{
#' source.https("https://raw.github.com/talgalili/installr/master/R/install.r") 
#' }
source.https <- function(URL,..., remove_r_file = T) {
   # this is an alternative to this code: http://tonybreyal.wordpress.com/2011/11/24/source.https-sourcing-an-r-script-from-github/
   # but one which does not require RCurl
   r_filename <- file.path(tempdir(), file.name.from.url(URL))   # the name of the zip file MUST be as it was downloaded...
   download.file(URL, destfile=r_filename, mode = 'wb')     
   source(r_filename,...)
   if(remove_r_file) unlink(r_filename)
   invisible(T)
}

# 
# # being able to source from github
# source("https://www.r-statistics.com/wp-content/uploads/2012/01/source.https.r.txt")
# source.https("source url for install.packages.zip")
# install.packages.zip("URL/installR.zip")
# # actually use functions...
# 
# 






#' @title Loading Packages (and Installing them if they are missing)
#' @export
#' @description  require2 load add-on packages by passing it to \link{require}.
#' However, if the package is not available on the system, it will first install it (through \link{install.packages}),
#' and only then try to load it again.
#'
#' @param package A character of the name of a package (can also be without quotes).
#' @param ask Should the user be asked to install the require packaged, in case it is missing? (default is FALSE)
#' @param character.only logical (FALSE) - a logical indicating whether package or
#' help can be assumed to be character strings. Passed to \link{require}.
#' @param min_version Minimum version of package
#'
#' @return  returns (invisibly) a logical indicating whether the required package is available.
#' @examples
#' \dontrun{
#' require2("devtools")
#' require2(geonames)
#' require2(pkgbuild, min_version = "1.1.0")
#' data_table_loaded <- require2("data.table")
#' }
require2 <- function(package, ask = FALSE, character.only = FALSE, min_version = 0) {
  if (!character.only) package <- as.character(substitute(package))
  available <- requireNamespace(package, character.only = T, quietly = T) && packageVersion(package) >= min_version
  if (!available) {
    if (ask) {
      install_package <- ask.user.yn.question(paste(
        "Package", package, "is not installed.",
        "Do you want to install it now?"
      ))
    } else {
      install_package <- TRUE
    }

    if (install_package) install.packages(package)
  }
  require(package, character.only = TRUE)
}









#' @title Restart RGui from RGui
#' @export
#' @description Start a new RGui session and then quits the current one.
#' 
#' This is a Windows only function.
#' @param ... passed to q()
#' 
#' @return  q(...)
#' @examples
#' \dontrun{
#' restart_RGui()
#' }
restart_RGui <- function(...) {
	# start a new RGui
	# .Last <- function() 
   if(!is.windows()) stop("This function only works on Windows OS")
	if(!is.Rgui()) stop("This function only works when running it from Rgui.exe")
	shell(file.path(R.home("bin"),"Rgui.exe"), wait = FALSE)
	# close this one:
	q(...)
}










#' @title Installing software from R
#' @export
#' @description Gives the user the option to download software from within R.
#' @param GUI a logical indicating whether a graphics menu should be used if available.  If TRUE, and on Windows, it will use winDialog, otherwise it will use \link[utils]{menu}.
#' @param ... not in use
#' @return TRUE/FALSE - if the software was installed successfully or not.
#' @seealso \link{updateR}, \link{install.R}, 
#' \link{install.RStudio}, \link{install.Rtools}, \link{install.pandoc}, 
#' \link{install.MikTeX}, \link{install.git}, \link{install.git},
#' \link{install.GraphicsMagick}, \link{install.ImageMagick},
#' \link{check.for.updates.R}, \link{install.URL}, \link{install.packages.zip},
#' 
#' @examples
#' \dontrun{
#' installr()
#' }
installr <- function(GUI = TRUE, ...) {
   choices <- c("R (updateR)",
                "RStudio",
                "Rtools",
                "git",
                "MikTeX",
                "LyX",
                "pandoc",
                "LaTeX2RTF",
                "GitHub",
                "ImageMagick",
                "GraphicsMagick",
                "SWFTools",
                "FFmpeg",
                "7-zip",
                "NotePad++",
                "NppToR (R extension to NotePad++)",
                "Cygwin",
                "Cancel")
   
   the_answer <- menu(choices, graphics = GUI, title = "Which software (for Windows) would you like to install?")            
   
   switch(the_answer, 
          updateR(),
          install.RStudio(),
          install.Rtools(),
          install.git(),
          install.MikTeX(),
          install.LyX(),
          install.pandoc(),
          install.LaTeX2RTF(),
          install.GitHub(),
          install.ImageMagick(),
          install.GraphicsMagick(),
          install.SWFTools(),
          install.FFmpeg(),
          install.7zip(),
          install.notepadpp(),
          install.npptor(),
          install.Cygwin(),
          return(FALSE)
   )
}





# https://stackoverflow.com/questions/8809004/escaping-in-roxygen2-style-documentation




#' @title Access tag elements from R's Rd file
#' @export
#' @description
#' A function to extract elements from R's help file.
#' 
#' It is useful, for example, for going through a package and 
#' discover who are its authors (useful for me to help me give proper
#' credit in the DESCRIPTION file).
#' 
#' @param package a character string of the package we are interested in.
#' @param tag a character vector of tag(s) to get from a package's Rd files.
#' @param ... not in use.
#' @author Thomas J. Leeper <thosjleeper@@gmail.com>
#' @return a character vector with the tag's content, and the name of the
#' Rd source of the function the tag came from.
#' @source \url{https://stackoverflow.com/questions/17909081/access-elements-from-rs-rd-file}
#' @seealso \link{package_authors}
#' @examples
#' \dontrun{
#' fetch_tag_from_Rd("installr", "\\author")
#' fetch_tag_from_Rd("knitr", "\\author")
#' fetch_tag_from_Rd("lubridate", "\\author")
#' 
#' fetch_tag_from_Rd("installr", "\\source")
#' 
#' # get all the authors for this package
#' unique(unname(fetch_tag_from_Rd("installr", "\\author")))
#'
#' fetch_tag_from_Rd("installr", "\\author")
#' package_authors("installr")
#' 
#' }
fetch_tag_from_Rd <- function(package, tag = "\\author",...){
	# require(tools)

	# from "tools" but it is not exported
	# RdTags <- function (Rd) 
    # {
       # res <- sapply(Rd, attr, "Rd_tag")
       # if (!length(res)) 
          # res <- character()
       # res
    # }
	RdTags <- function (Rd) 
		{
			res <- sapply(Rd, attr, "Rd_tag")
			if (!length(res)) 
				res <- character()
			res
		}
	# tools:::RdTags
	# This is causing too many errors...
	
   db <- tools::Rd_db(package)
   tag_content <- lapply(db,function(x) {
      tags <- RdTags(x)
      if(tag %in% tags){
         # return a crazy list of results
         #out <- x[which(tmp=="\\author")]
         # return something a little cleaner
         out <- paste(unlist(x[which(tags %in% tag)]),collapse="")
      }
      else
         out <- NULL
      invisible(out)
   })
   tag_content <- gsub("\n","",unlist(tag_content)) # further cleanup
   
   return(tag_content)
}



#' @title Access (and clean) author elements from R's Rd file
#' @export
#' @description 
#' Find authors.
#' @details
#' List authors for a package from its "author" tag elements from its Rd files.
#' The function also separate lists of authors, and cleans the output a bit
#' (from spaces at the beginning of the strings).
#' 
#' @param package a character string of the package we are interested in.
#' @param to_strsplit logical (TRUE). Should the authors strings be split
#' (in cases of a "and" or a comma ",")?
#' @param split a character scalar to be passed to \link{strsplit} split parameter.
#' default is c(",|and)
#' @param to_table logical (FALSE). Should the authors strings be listed in a
#' table - showing a count of how many .Rd files they were listed in?
#' If not - a unique list is produced.
#' @param ... not used.
#' @return a character vector with a package authors (as extracted from 
#' the author tag in the .Rd files)
#' 
#' @seealso \link{fetch_tag_from_Rd}
#' 
#' @references
#' Useful for updating your DESCRIPTION file:
#' 
#' \url{https://cran.r-project.org/doc/manuals/R-exts.html#The-DESCRIPTION-file}
#' 
#' @examples
#' \dontrun{
#' 
#' # before:
#' fetch_tag_from_Rd("installr", "\\author")
#' # after:
#' package_authors("installr")
#' sort(package_authors("installr")) # sorted name list...
#' 
#' 
#' ## From the top R packages list: 
#' ## https://www.r-statistics.com/2013/06/top-100-r-packages-for-2013-jan-may/
#' package_authors("plyr")
#' package_authors("digest")
#' package_authors("ggplot2")
#' package_authors("colorspace")
#' package_authors("stringr") # empty string.
#' 
#' package_authors("knitr")
#' package_authors("MASS")
#' package_authors("rpart")
#' package_authors("Rcpp")
#' 
#' 
#' }
package_authors <- function(package, to_strsplit = TRUE, split=c(",|and"), to_table = FALSE, ...) {
   authors <- unname(fetch_tag_from_Rd(package, "\\author"))
   
   if(length(authors) == 0) {
      cat("No author tag found for this package.\n")
      return(invisible(authors))
   }

   # split multiple authors in the same string:
   if(to_strsplit) {
      authors <- unlist(strsplit(authors,split=split))      
   }
   
   # Remove empty spaces from the begining of the strings
   authors <- gsub("^ *","",authors) 
   
   # Remove empty char.
   ss_empty <- which(nchar(authors)==0)
   if(length(ss_empty) > 0) {
      authors <- authors[-ss_empty]   
   }  
   
   if(to_table) {
      authors <- sort(table(authors))   
   } else {
      # Keep unique names
      authors <- unique(authors)      
   }   

   return(authors)
}














#' @title Downloads and installs CMake for windows
#' @aliases install.cmake
#' @description Allows the user to downloads and install the latest version of CMake for Windows.
#' @details
#' CMake is a family of tools designed to build, test and package software. 
#' CMake is used to control the software compilation process using simple 
#' platform and compiler independent configuration files. 
#' CMake generates native makefiles and workspaces that can be used in the 
#' compiler environment of your choice.
#' If run NOT on Windows (i.e.: max/linux), this would download the file into the working directory.
#' (\link{getwd}).
#' @param URL the URL of the CMake download page.
#' @param cmake_version NULL by default, but a user can supply the version as a character.
#' @param ... extra parameters to pass to \link{install.URL}
#' @return TRUE/FALSE - was the installation successful or not.
#' @export
#' @references
#' \itemize{
#' \item CMake homepage: \url{https://cmake.org/download/}
#' } 
#' @examples
#' \dontrun{
#' install.CMake() # installs the latest version of CMake
#' }
#'

install.CMake   <-
   function (URL =  "https://github.com/Kitware/CMake/releases",
             cmake_version = NULL, 
             ...)
   {
      repo <- URL
      # enforce quality control for repo and cmake version
      if (!is.null(cmake_version) & !is.character(cmake_version)) {
         stop("cmake_version must be NULL or a character with exact version number")
      }
      page <- readLines(repo, warn = FALSE)
      
      # get architecture and OS
      arch_os <- unlist(strsplit(R.version$system, ", "))
      ver <- "v[0-9.]+/"
      target_line <- grep(ver, page, value = TRUE)
      m <- regexpr(ver, target_line)
      # get available versions and sort decreasing
      available_versions <-
         sort(unique(regmatches(target_line, m)), decreasing = TRUE)
      # remove the "/"
      available_versions <-
         gsub(x = available_versions,
              pattern = "/",
              replacement = "")
      # default to latest or user input ?
      if (is.null(cmake_version)) {
         message("Looking available versions for latest version")
         print(available_versions)
         target_version <-
            gsub(x = available_versions[1],
                 pattern = "v",
                 replacement = "")
         target_version <-
            gsub(x = target_version,
                 pattern = "/",
                 replacement = "")
      } else {
         # must be exact match
         if (!(paste0("v", cmake_version) %in% available_versions)) {
            message(
               paste0(
                  "Provided version `",
                  cmake_version,
                  "` not found on available versions. See below:"
               )
            )
            # print with no v to avoid confusion
            print(gsub(
               x = available_versions,
               pattern = "v",
               replacement = ""
            ))
            stop("provided version not available.")
         }
         target_version <- cmake_version
      }
      
      os_initial <- regmatches(arch_os[2], regexpr("([A-Za-z\\-]+)", arch_os[2]))
      file <- switch(
         os_initial,
         "mingw" = paste0("windows-", arch_os[1], ".msi"),
         "linux-gnu" = paste0("Linux-", arch_os[1], ".tar.gz"),
         "darwin" = paste0("Darwin-", arch_os[1], ".tar.gz")
      )
      
      file <- paste0("cmake-", target_version, "-", file)
      
      # links look like
      # version/cmake-3.17.0-Darwin-x86_64.dmg
      URL <-
         paste(repo, "download", paste0("v", target_version), file, sep = "/")
      message("Trying to find CMake in this URL")
      print(URL)
      
      if (os_initial == "mingw") {
         install.URL(URL, ...)
      } else {
         download.file(URL, destfile = file.path(getwd(), file))
      }
      
   }

#' @export
install.cmake <- function(...)
   install.CMake(...)
talgalili/installr documentation built on Feb. 19, 2024, 1:22 p.m.