diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b5c292..3e118dcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][CTAN] ### Fixed - Multiple Scribus render frames were all using the same file name, which would result in the same score appearing in all render frames. This change makes the score files use an available Scribus variable to force multiple file names. +- When kpsewhich cannot write to a particular location, it generates an error which is directed to stderr but not to our glog file. This created an undocumented error when trying to write to a gtex file to a bad location. We now capture stderr output produced when compiling scores and redirect it to our glog file so that the error is properly recorded. Fixes [#1541](https://github.com/gregorio-project/gregorio/issues/1541). + +### Changed +- Defined an output directory for gtex and glog files. Default is `tmp-gre`. This can be changed using `\gresetoutputdir{...}`. Fixes [#1393](https://github.com/gregorio-project/gregorio/issues/1393), [#1542](https://github.com/gregorio-project/gregorio/issues/1542), and [#1571](https://github.com/gregorio-project/gregorio/issues/1571). ## [6.0.0] - 2021-03-13 ### Fixed diff --git a/doc/Command_Index_User.tex b/doc/Command_Index_User.tex index c05cf7d9..79dce446 100644 --- a/doc/Command_Index_User.tex +++ b/doc/Command_Index_User.tex @@ -157,7 +157,8 @@ \subsubsection{Including scores} \gresetgregpath{{../Scores/}} \end{latexcode} -Note that these directories are not searched recursively. If you want to include subdirectories, then each subdirectory must be included individually. +\macroname{\textbackslash gresetoutputdir}{\{\#1\}}{gregoriotex-main.tex} +Sets the name of the output directory where gtex and glog files will be written. By default this is tmp-gre of the current directory. Use this command to relocate these files to some other directory. \macroname{\textbackslash gresetcompilegabc}{\{\#1\}}{gregoriotex-main.tex} diff --git a/tex/gregoriotex-main.tex b/tex/gregoriotex-main.tex index 7fd0168b..3a8dfc29 100644 --- a/tex/gregoriotex-main.tex +++ b/tex/gregoriotex-main.tex @@ -156,6 +156,13 @@ \closeout\gre@gaux % }% +%%%%%%%%%%%%%%%%%%% +%% output directory selection +%%%%%%%%%%%%%%%%%%% + +\def\gresetoutputdir#1{% + \directlua{gregoriotex.set_base_output_dir([[#1]])}% +}% %%%%%%%%%%%%%%% %% basic start diff --git a/tex/gregoriotex.lua b/tex/gregoriotex.lua index eb2628f2..4d194147 100644 --- a/tex/gregoriotex.lua +++ b/tex/gregoriotex.lua @@ -89,6 +89,11 @@ local test_snippet_filename = nil local snippet_filename = nil local snippet_logname = nil +local base_output_dir = 'tmp-gre' +local function set_base_output_dir(new_dirname) + base_output_dir = new_dirname +end + local space_below_staff = 5 local space_above_staff = 13 @@ -761,6 +766,71 @@ local function at_score_end() saved_counts = {} end +-- Inserted copy of https://github.com/ToxicFrog/luautil/blob/master/lfs.lua +local windows = package.config:sub(1,1) == "\\" + +-- We make the simplifying assumption in these functions that path separators +-- are always forward slashes. This is true on *nix and *should* be true on +-- windows, but you can never tell what a user will put into a config file +-- somewhere. This function enforces this. +function lfs.normalize(path) + if windows then + return (path:gsub("\\", "/")) + else + return path + end +end + +local _attributes = lfs.attributes +function lfs.attributes(path, ...) + path = lfs.normalize(path) + if windows then + -- Windows stat() is kind of awful. If the path has a trailing slash, it + -- will always fail. Except on drive root directories, which *require* a + -- trailing slash. Thankfully, appending a "." will always work if the + -- target is a directory; and if it's not, failing on paths with trailing + -- slashes is consistent with other OSes. + path = path:gsub("/$", "/.") + end + + return _attributes(path, ...) +end + +function lfs.exists(path) + return lfs.attributes(path, "mode") ~= nil +end + +function lfs.dirname(oldpath) + local path = lfs.normalize(oldpath):gsub("[^/]+/*$", "") + if path == "" then + return oldpath + end + return path +end + +-- Recursive directory creation a la mkdir -p. Unlike lfs.mkdir, this will +-- create missing intermediate directories, and will not fail if the +-- destination directory already exists. +-- It assumes that the directory separator is '/' and that the path is valid +-- for the OS it's running on, e.g. no trailing slashes on windows -- it's up +-- to the caller to ensure this! +function lfs.rmkdir(path) + path = lfs.normalize(path) + if lfs.exists(path) then + return true + end + if lfs.dirname(path) == path then + -- We're being asked to create the root directory! + return nil,"rmkdir: unable to create root directory" + end + local r,err = lfs.rmkdir(lfs.dirname(path)) + if not r then + return nil,err.." (creating "..path..")" + end + return lfs.mkdir(path) +end +-- end https://github.com/ToxicFrog/luautil/blob/master/lfs.lua + local function clean_old_gtex_files(file_withdir) local filename = "" local dirpath = "" @@ -775,9 +845,11 @@ local function clean_old_gtex_files(file_withdir) dirpath = string.match(file_withdir, "(.*)"..sep) if dirpath then -- dirpath is nil if current directory filename = "^"..file_withdir:match(".*/".."(.*)").."%-%d+_%d+_%d+[-%a%d]*%.gtex$" - for a in lfs.dir(dirpath) do - if a:match(filename) then - os.remove(dirpath..sep..a) + if lfs.exists(dirpath) then + for a in lfs.dir(dirpath) do + if a:match(filename) then + os.remove(dirpath..sep..a) + end end end else @@ -798,8 +870,8 @@ local function compile_gabc(gabc_file, gtex_file, glog_file, allow_deprecated) extra_args = extra_args..' -D' end - local cmd = string.format('%s %s -W -o %s -l %s "%s"', gregorio_exe(), - extra_args, gtex_file, glog_file, gabc_file) + local cmd = string.format('%s %s -W -o %s -l %s "%s" 2> %s', gregorio_exe(), + extra_args, gtex_file, glog_file, gabc_file, glog_file) res = os.execute(cmd) if res == nil then err("\nSomething went wrong when executing\n '%s'.\n" @@ -920,6 +992,29 @@ local function include_score(input_file, force_gabccompile, allow_deprecated) else gabc:close() end + local sep = "" + local onwindows = os.type == "windows" or + string.find(os.getenv("PATH"),";",1,true) + if onwindows then + sep = "\\" + else + sep = "/" + end + local output_dir = base_output_dir..sep..file_dir + info(output_dir) + if not lfs.exists(output_dir) then + if not lfs.exists(base_output_dir) then + lfs.mkdir(base_output_dir) + end + local err,message = lfs.rmkdir(output_dir) + if not err then + info(message) + end + end + gtex_filename = string.format("%s%s-%s.gtex", output_dir, cleaned_filename, + internalversion:gsub("%.", "_")) + glog_file = string.format("%s%s-%s.glog", output_dir, cleaned_filename, + internalversion:gsub("%.", "_")) compile_gabc(gabc_file, gtex_filename, glog_file, allow_deprecated) tex.print(string.format([[\input %s\relax]], gtex_filename)) return @@ -1557,6 +1652,7 @@ gregoriotex.save_dim = save_dim gregoriotex.save_count = save_count gregoriotex.change_next_score_line_dim = change_next_score_line_dim gregoriotex.change_next_score_line_count = change_next_score_line_count +gregoriotex.set_base_output_dir = set_base_output_dir dofile(kpse.find_file('gregoriotex-nabc.lua', 'lua')) dofile(kpse.find_file('gregoriotex-signs.lua', 'lua'))