0

I have a package to create exam paper sujet.sty, in this package I have defined some commands like school which expand to the name of school.

\def\school{name-of-school}

I thought about using a method defined in this answer Modifying .sty files? , and I have created a file sujetset.sty which contain those commands, users of the package have to modify this file and enter their schools (and other permanent info).

In order to simplify the process of opening and edeting of package for users I thought about using Kpathsea like this (command line):

kpsewhich sujetset.sty

Which give:

c:/texlive/texmf-local/tex/latex/local/sujet/sujetset.sty 

Then we need to copy/past this in command line to open sujetset.sty for modification.

My aim is to reduce those two operations in one single command, Is this possible?, if any one has another simpler method please help.

Salim Bou
  • 17,021
  • 2
  • 31
  • 76
  • I wrote a simple function in bash to do that. You use texsrc sujetset.sty and it opens in the current $EDITOR. More or less like texdoc, but way simpler. Would you be interested? – Phelype Oleinik Nov 16 '18 at 15:47
  • Yes, can you post it as answer. – Salim Bou Nov 16 '18 at 15:50
  • 2
    @PhelypeOleinik With bash, the need is not so great anyway: one can do nano `kpsewhich sujetset.sty` or similar ... – Joseph Wright Nov 16 '18 at 15:50
  • 3
    Since the usual advice is not to change system-installed .sty files (for very good reasons), maybe it would be a good idea to come up with a different system for your package that involves only changing files that were not installed by the system and that you can guarantee a user has the permissions to write anyway. – moewe Nov 16 '18 at 15:53
  • 1
    It is easier to users if you define in sty file such commands: \def\@school{name-of-school} and \newcommand{\school}[1]{\gdef\@school{#1}}. Then, you use in your code the macro \@school. Now, user simply type in the main tex file the following: \school{here it is} to change the value of \@school, which is in use in your style file. In this case, user does not need to edit style file. – Sigur Nov 16 '18 at 21:46
  • This means that it is necessary for the user to add \school{name-of-school} every time he need to create new document with this package, I think it is better for the user if it can change it in sujetset file once . – Salim Bou Nov 17 '18 at 05:38
  • Please use \newcommand rather than \def so that users get meaningful errors in case of conflicts. There's no reason to use \def here. – cfr Nov 18 '18 at 01:06
  • @SalimBou Not really, you can support an optional configuration file, allowing the user to set defaults. – cfr Nov 18 '18 at 01:08
  • Please can you explain more @cfr . – Salim Bou Nov 18 '18 at 08:20
  • @SalimBou Like, say, graphix or biblatex or whatever. You look for a file with a particular name. If it exists, you input it. If not, you carry on. Or you provide a default configuration file which users can copy if they like and modify. Then you input it unconditionally and you'll get the user's if it exists or your defaults otherwise. There's no need to require users to provide such a file. Make it optional. – cfr Nov 18 '18 at 22:19

3 Answers3

1

Here's a solution using ba(s|tc)h.

To load a sujetset.sty file you can use texsrc sujetset or texsrc sujetset.sty. If you don't specify the extension (actually, if the file name you given was not found), the function tries cls, sty, and def, in this order. Upon not finding a file the function tries these fallback extensions, but this slows down the process due to extra calls to kpsewhich.

You can also pass a second argument, the function tries to use it as the editor, so texsrc article nano would open article.cls in nano.

Both versions are essentially the same code (modulo the batch version being a collage of code snippets from around the internet :-). The main difference is the choice of editor:

  • The bash version checks if $2 is given; if it is not, the default $EDITOR is used, otherwise it searches for the executable in $2 with which and issues an error if it doesn't exist. If no editor was given and $EDITOR is not set, another error is raised.

  • The batch version due to my lack of knowledge can't test if an executable exists, so it uses %EDITOR if defined, or uses %2if given, or uses notepad because. If anything is set wrong, chaos ensues :-)

Here's the bash version:

function texsrc {
    if [ $# -eq "0" ]; then
      echo 'Use texsrc <package name>'
      return 1
    fi
    tryfile=$(kpsewhich "$1")
    if [ -n "$tryfile" ]; then
      filetoload=$tryfile
    else
      for i in cls sty def; do
        tryfile=$(kpsewhich "$1.$i")
        if [ -n "$tryfile" ]; then
          filetoload=$tryfile
          break
        fi
      done
    fi
    if [ -z "$filetoload" ]; then
      echo "No file found."
      return 1
    fi
    if [ $# -eq "2" ]; then
      if [ -z $(which $2) ]; then
        echo I couldn''t find the editor $2
      else
        texed=$2
      fi
    else
      texed=$EDITOR
    fi
    if [ -n "$texed" ]; then
      eval $texed $filetoload
    else
      echo I Couldn''t find an appropriate editor to open the file: $filetoload
    fi
}

and a batch version:

@echo off
:texsrc
setlocal enabledelayedexpansion
if %1.==. goto ZeroArgs
call :SearchFile tryfile %1
if "%tryfile%"=="" (
  for %%g in (cls,sty,def) do (
    call :SearchFile tryfile "%1.%%g"
    if defined tryfile (
      set filetoload=!tryfile!
      goto FileFound
    )
  )
) else (
  set filetoload=%tryfile%
)
:FileFound
if "%filetoload%"=="" (
  echo "No file found."
  goto Return1
)
if defined EDITOR (set texed=%EDITOR%)
if not %2.==. (set texed=%2)
if not defined texed (set texed=notepad)
start "" %texed% %filetoload%
endlocal
exit /B 0

:SearchFile
  setlocal
  for /f "tokens=* usebackq" %%f in (`kpsewhich %2`) do (set _var=%%f)
  endlocal & set %1=%_var%
  exit /B 0
:ZeroArgs
  echo Use texsrc ^<package name^>
  goto Return1
:Return1
  endlocal
  exit /B 1

P.S.: Don't edit your TeX installation files directly :)

  • Not working function texsrc { 'function' is not recognized as an internal or external command, operable program or batch file. $# was unexpected at this time. – Salim Bou Nov 16 '18 at 17:02
  • @SalimBou Strange... Works for me. Are you sure you are using bash? What is the output of echo $0? – Phelype Oleinik Nov 16 '18 at 17:16
  • I have copied your code in a file texsrc.bat, then I run texsrc sujetset from command prompt . like this or I am wrong ? – Salim Bou Nov 16 '18 at 18:14
  • @SalimBou .bat? Are you using the Windows command prompt? – Phelype Oleinik Nov 16 '18 at 18:27
  • Yes, I have windows. – Salim Bou Nov 16 '18 at 18:41
  • Sorry, now I saw the c:/ in your question. This answer only works for bash, which is one of the Linux equivalents of Windows' command prompt. It won't work, unfortunately :/ And I don't have a Windows machine to try to translated the code for you, sorry. – Phelype Oleinik Nov 16 '18 at 18:44
  • 1
    @SalimBou I know you asked this quite some time ago, but I added a batch version now, in case you're interested :-) – Phelype Oleinik Sep 27 '19 at 01:05
1

If you are a Emacs user, you can add this code to your init file :

(defun LaTeX-find-sty-file ()
  "find sty file whose name is under the point" 
      (interactive)
      (let ((adr (shell-command-to-string (format "kpsewhich %s.sty" (thing-at-point 'symbol)))))
(if (string-empty-p adr)
(message "kpsewhich : no such package : %s.sty" (thing-at-point 'word))
      (find-file (substring adr 0 -1)))))

  (define-key LaTeX-mode-map (kbd "C-c y")       'LaTeX-find-sty-file)

next, assuming latex-mode, C-c y open the sty file whose name is under the point.

gigiair
  • 1,812
0

I found a solution here
How do I use a pipe to redirect the output of one command to the input of another?

In my case all we need in windows command prompt is:

for /F "tokens=*" %i in ('kpsewhich sujetset.sty') do %i

Which open the file sujetset.sty in the default ide. and with batch file

@echo off
c:
cd \
for /f "delims=" %%i in ('kpsewhich  sujetset.sty') do set exeLcn=%%i
start %exeLcn%
Salim Bou
  • 17,021
  • 2
  • 31
  • 76