Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: tinytex
Type: Package
Title: Helper Functions to Install and Maintain TeX Live, and Compile LaTeX Documents
Version: 0.58.6
Version: 0.58.7
Authors@R: c(
person("Yihui", "Xie", role = c("aut", "cre", "cph"), email = "xie@yihui.name", comment = c(ORCID = "0000-0003-0645-5666")),
person(given = "Posit Software, PBC", role = c("cph", "fnd")),
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
YEAR: 2017-2024
YEAR: 2017-2026
COPYRIGHT HOLDER: Yihui Xie and Posit Software, PBC
64 changes: 41 additions & 23 deletions R/install.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
#' installed. By default, a vector of all currently installed LaTeX packages
#' if an existing installation of TinyTeX is found. If you want a fresh
#' installation, you may use \code{extra_packages = NULL}.
#' @param add_path Whether to run the command \command{tlmgr path add} to add
#' the bin path of TeX Live to the system environment variable \var{PATH}.
#' @param add_path Whether to add the bin path of TeX Live to the system
#' environment variable \var{PATH}. See \code{\link{tlmgr_path}()}.
#' @references See the TinyTeX documentation (\url{https://yihui.org/tinytex/})
#' for the default installation directories on different platforms.
#' @note If you really want to disable the installation, you may set the
Expand Down Expand Up @@ -113,7 +113,6 @@ install_tinytex = function(
switch(
os,
'unix' = {
check_local_bin()
if (os_index != 3 && !any(dir_exists(c('~/bin', '~/.local/bin')))) on.exit(message(
'You may have to restart your system after installing TinyTeX to make sure ',
'~/bin appears in your PATH variable (https://github.com/rstudio/tinytex/issues/16).'
Expand Down Expand Up @@ -290,25 +289,43 @@ win_app_dir = function(s) {
# test if path is pure ASCII and has no spaces
valid_path = function(x) grepl('^[!-~]+$', x)

# check if /usr/local/bin on macOS is writable
check_local_bin = function() {
if (os_index != 3 || is_writable(p <- '/usr/local/bin')) return()
message(
'The directory ', p, ' is not writable. I recommend that you make it writable. ',
'See https://github.com/rstudio/tinytex/issues/24 for more info.'
osascript = function(cmd) {
message("Requesting admin privilege to run: sudo ", cmd)
escaped = gsub('"', '\\"', cmd, fixed = TRUE)
ret = system(sprintf(
"/usr/bin/osascript -e 'do shell script \"%s\" with administrator privileges'", escaped
))
if (ret != 0) warning(
"Please run the above command in your Terminal (password required).", call. = FALSE
)
Comment on lines +295 to 300
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before running system() command, emit a message() telling users the command to be executed so they know the purpose of requiring the password; after running system(), if it fails, add warning() to tell you to run the command in terminal (don't repeat the command in the warning message since it has been mentioned in message() before)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 71d49e3. osascript() now emits message("Requesting admin privilege to run: sudo ", cmd) before the system() call, and on failure emits warning("Please run the above command in your Terminal (password required).") without repeating the command.

if (!dir_exists(p)) osascript(paste('mkdir -p', p))
user = system2('whoami', stdout = TRUE)
osascript(sprintf('chown -R %s:admin %s', user, p))
ret
}

osascript = function(cmd) {
if (system(sprintf(
"/usr/bin/osascript -e 'do shell script \"%s\" with administrator privileges'", cmd
)) != 0) warning(
"Please run this command in your Terminal (password required):\n sudo ",
cmd, call. = FALSE
)
# on macOS, if the user doesn't have write permission to /usr/local/bin, we use
# /etc/paths.d instead
use_paths_d = function() {
is_macos() && file.access('/usr/local/bin', 2) != 0
}

# add/remove TinyTeX's bin path to/from /etc/paths.d/TinyTeX on macOS;
# if adding and the file already contains the desired path, skip the operation
macos_path = function(dir = NULL, action = 'add') {
paths_file = '/etc/paths.d/TinyTeX'
add = action == 'add'
cmd = if (add) {
if (is.null(dir) || dir == '') return(1L)
if (file.exists(paths_file) &&
identical(readLines(paths_file, warn = FALSE), dir))
return(0L)
tmp = tempfile()
writeLines(dir, tmp)
sprintf('cp "%s" "%s"', tmp, paths_file)
} else {
sprintf('rm -f "%s"', paths_file)
}
ret = osascript(cmd)
if (add && ret == 0) unlink(tmp)
ret
}

install_tinytex_source = function(repo = '', dir, version, add_path, extra_packages) {
Expand Down Expand Up @@ -587,9 +604,9 @@ download_installer = function(file, version) {
#'
#' The function \code{copy_tinytex()} copies the existing TinyTeX installation
#' to another directory (e.g., a portable device like a USB stick). The function
#' \code{use_tinytex()} runs \command{tlmgr path add} to add the copy of TinyTeX
#' in an existing folder to the \code{PATH} variable of the current system, so
#' that you can use utilities such as \command{tlmgr} and \command{pdflatex},
#' \code{use_tinytex()} adds the copy of TinyTeX in an existing folder to the
#' \code{PATH} variable of the current system via \code{\link{tlmgr_path}()},
#' so that you can use utilities such as \command{tlmgr} and \command{pdflatex},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't mention OS details; link to tlmgr_path documentation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 76970e1.

#' etc.
#' @param from The root directory of the TinyTeX installation. For
#' \code{copy_tinytex()}, the default value \code{tinytex_root()} should be a
Expand Down Expand Up @@ -632,7 +649,8 @@ use_tinytex = function(from = select_dir('Select TinyTeX Directory')) {
if (length(d) != 1) stop("The directory '", from, "' does not contain TinyTeX.")
p = file.path(d, 'tlmgr')
if (os == 'windows') p = paste0(p, '.bat')
if (system2(p, c('path', 'add')) != 0) stop(
ret = if (use_paths_d()) macos_path(normalizePath(d)) else system2(p, c('path', 'add'))
if (ret != 0) warning(
"Failed to add '", d, "' to your system's environment variable PATH. You may ",
"consider the fallback approach, i.e., set options(tinytex.tlmgr.path = '", p, "')."
)
Expand Down
27 changes: 18 additions & 9 deletions R/tlmgr.R
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ tlmgr = function(args = character(), usermode = FALSE, ..., .quiet = FALSE) {
# check if it is necessary to add ~/Library/TinyTeX/bin/*/ to PATH

#' @importFrom xfun is_linux is_unix is_macos is_windows with_ext
tweak_path = function() {
# check tlmgr exists under the default installation dir of TinyTeX, or the
# global option tinytex.tlmgr.path
# return the bin directory of TinyTeX (empty string if not found)
find_tinytex_bin = function() {
f = getOption('tinytex.tlmgr.path', find_tlmgr(extra = TRUE))
if (length(f) == 0 || !file_test('-x', f)) return()
bin = normalizePath(dirname(f))
if (length(f) == 0 || !file_test('-x', f)) '' else normalizePath(dirname(f))
}

tweak_path = function() {
bin = find_tinytex_bin()
if (bin == '') return()
# if the pdftex from TinyTeX is already on PATH, no need to adjust the PATH
if ((p <- Sys.which('pdftex')) != '') {
p2 = with_ext(file.path(bin, 'pdftex'), xfun::file_ext(p))
Expand Down Expand Up @@ -258,13 +261,19 @@ delete_tlpdb_files = function() {
))
}

#' @param action On Unix, add/remove symlinks of binaries to/from the system's
#' \code{PATH}. On Windows, add/remove the path to the TeXLive binary
#' @param action On macOS, if \file{/usr/local/bin} is not writable, add/remove
#' the TinyTeX bin path to/from \file{/etc/paths.d/TinyTeX}; otherwise (or on
#' other Unix systems), add/remove symlinks of binaries to/from the system's
#' \code{PATH}. On Windows, add/remove the path to the TeX Live binary
#' directory to/from the system environment variable \code{PATH}.
#' @rdname tlmgr
#' @export
tlmgr_path = function(action = c('add', 'remove'))
tlmgr(c('path', match.arg(action)), .quiet = TRUE)
tlmgr_path = function(action = c('add', 'remove')) {
action = match.arg(action)
if (use_paths_d()) {
invisible(macos_path(find_tinytex_bin(), action))
} else tlmgr(c('path', action), .quiet = TRUE)
}

#' @rdname tlmgr
#' @export
Expand Down
6 changes: 3 additions & 3 deletions man/copy_tinytex.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/install_tinytex.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions man/tlmgr.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 24 additions & 12 deletions tools/install-bin-unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,29 @@ fi
[ $OSNAME != "Darwin" ] && ./tlmgr option sys_bin $BINDIR
./tlmgr postaction install script xetex # GH issue #313

if [ $OSNAME = 'Darwin' ]; then
# create the dir if it doesn't exist
if [ ! -d /usr/local/bin ]; then
echo "Admin privilege (password) is required to create the directory /usr/local/bin:"
sudo mkdir -p /usr/local/bin
fi
# change owner of the dir
if [ ! -w /usr/local/bin ]; then
echo "Admin privilege (password) is required to make /usr/local/bin writable:"
sudo chown -R `whoami`:admin /usr/local/bin
NO_PATH=0
for arg in "$@"; do
case "$arg" in --no-path) NO_PATH=1 ;; esac
done

if [ $NO_PATH -eq 0 ]; then
if [ $OSNAME = 'Darwin' ]; then
if [ -w /usr/local/bin ]; then
./tlmgr path add
elif ! grep -qxF "$(pwd)" /etc/paths.d/TinyTeX 2>/dev/null; then
# add TinyTeX's bin path to /etc/paths.d instead of creating symlinks in /usr/local/bin
# (at this point we are in $TEXDIR/bin/*/ after the `cd` above)
echo "Admin privilege (password) is required to set up the PATH for TinyTeX:"
if printf '%s\n' "$(pwd)" | sudo tee /etc/paths.d/TinyTeX > /dev/null; then
# /etc/paths.d is not picked up until the shell is restarted; export PATH now
export PATH="$PATH:$(pwd)"
else
echo "To set up PATH manually, run the following command and add it to your shell startup profile (e.g. ~/.zshrc):"
echo " export PATH=\$PATH:$(pwd)"
export PATH="$PATH:$(pwd)"
fi
fi
else
./tlmgr path add
fi
fi

./tlmgr path add
4 changes: 2 additions & 2 deletions tools/install-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Add-Content tinytex.profile 'TEXMFVAR $TEXMFSYSVAR'
# download the custom package list
Invoke-WebRequest 'https://tinytex.yihui.org/pkgs-custom.txt' -OutFile pkgs-custom.txt

# an automated installation of TeXLive (infrastructure only)
# an automated installation of TeX Live (infrastructure only)
cd install-tl-*
(Get-Content install-tl-windows.bat) -notmatch '^\s*pause\s*$' | Set-Content install-tl-windows.bat
mkdir TinyTeX
Expand All @@ -39,7 +39,7 @@ ni .tinytex | Out-Null
del install-tl.log, install-tl, install-tl-windows.bat -ErrorAction SilentlyContinue
cd ..

# TeXLive installed to ./TinyTeX; move it to APPDATA
# TeX Live installed to ./TinyTeX; move it to APPDATA
rd $env:APPDATA\TinyTeX -r -fo -ErrorAction SilentlyContinue
rd $env:APPDATA\TinyTeX -r -fo -ErrorAction SilentlyContinue
move TinyTeX $env:APPDATA
Expand Down
Loading