GNU Emacs package for transforming files with Makefile recipes
Curry command line tools with Makefiles and select a Makefile to call
from dired
dispatching on selected files' extension.
I'm sure you've encountered your share of "How do I transform X to
Y?"-type questions on the web. I know I have. A lot of answers involve
using kitchen-sink tools like ffmpeg
or convert
. These tools are
great: they can transform almost anything into anything else. But
they come with a price of a gazillion switches that are hard to
remember (and to type in, for that matter).
This package solves this problem by moving the complex command to a Makefile with customizable literate parameters at the top. Additionally it catalogs all available Makefiles by the file extension that they work on. It also creates a Makefile template for you when a selected action doesn't exist.
-
You write the command only once. All the other times, you just customize the literate switches.
-
It's possible to not have to write the command at all if it's available in the repository.
-
Since the command is meant to be written just once, you can have a more complex and optimized command, compared to the one that you would normally enter in the terminal.
-
In case of multiple files,
make
allows to use multiple cores without the actual command knowing about it. This means that people with different processors can use the same Makefile to the most efficiency, callingmake -j8
ormake -j2
where appropriate. -
The Elisp layer of this package solves the problem of Makefiles and file names with spaces.
Clone this repository:
$ cd ~/git/
$ git clone https://github.com/abo-abo/make-it-so
Add to .emacs
:
(add-to-list 'load-path "~/git/make-it-so")
(require 'make-it-so)
(mis-config-default)
This method means that any Makefile that you create will be under version control.
If you install from MELPA, you only need this:
(mis-config-default)
However beware that your recipes will be in your package-user-dir
and will be wiped when you update the package. Which is fine if
you just want to give it a quick go or don't plan on creating your own
recipes. But if you do, move your recipes directory to a different place
and configure mis-recipes-directory
properly.
As a sample scenario, assume you want to trim (change running time) one or more *.ogv files.
So you navigate to their location with dired
and mark
them in case there's more than one.
Next, you call make-it-so
(bound to ,). It recognizes the "ogv"
extension and offers crop
, to-gif
and trim
actions. You can
navigate with C-n/C-p, select with RET and cancel with C-g.
After you've selected trim
, the selected files and the corresponding
Makefile will be moved to a staging directory within
your current directory. The staging directory will be named after the
action and the first selected file.
The Makefile will be opened for you to customize switches which start out as:
from = 00:00:01
to = 00:00:23
The actual command called will be:
ffmpeg -i $< -ss $(from) -t $(to) -c copy $@
but this complexity is distanced from you, and you can just select
from
and to
if you want.
Next you call mis-save-and-compile
(bound to f5 for make-mode
)
and test your result.
After this you can:
- Call
mis-abort
(bound to C-M-,): the staging directory will be deleted and all files restored to their places. Basically, this is just an undo with respect tomake-it-so
. - Call
mis-finalize
(bound to C-,): in addition tomis-abort
the generated files will be moved to the original directory. - Call
mis-replace
(bound to C-M-.): in addition tomis-finalize
the source files will be moved to trash.
Note that in all three cases any modifications to the Makefile
template will be lost, along with all files in the staging directory
except those that were copied when you first called make-it-so
and
those registered by the Makefile in "provide" file.
There's also mis-dispatch (bound to C-.) that allows to call the above three commands by name and remind you their shortcuts.
- cue-spit
- flac-to-mp3
- ogv-trim
- ogv-crop
- ogv-to-gif
- svg-to-png
- md-to-html
- mp4-to-mp3
- m4a-to-mp3
- chm-to-pdf
- pdf-to-txt
As a sample scenario, assume you want to convert *.svg to *.png.
-
An internet search lead to Stack Overflow and this command:
inkscape -z -e test.png -w 1024 -h 1024 test.svg
-
Navigate to the file(s) in
dired
and callmake-it-so
with ,. No default actions are available, so just type "to-png" and hit RET. The "to-" prefix signifies that this is a conversion, adapting the Makefile to this form:# This is a template for the Makefile. # Parameters should go in the upper half as: # width = 200 # and be referenced in the command as $(width) # ______________________________________________________________________________ DIRSVG = $(shell dir *.svg) DIRPNG = $(DIRSVG:.svg=.png) all: clean Makefile $(DIRPNG) %.png: %.svg echo "add command here" echo $@ >> provide clean: rm -f *.png provide # Insert the install command here. # e.g. sudo apt-get install ffmpeg install-tools: echo "No tools required" .PHONY: all install-tools clean
If the action name doesn't have a "to-" prefix, the transformation is assumed to be e.g. "svg" -> "out.svg". You can change this of course by editing the Makefile.
-
In case the command name and package name don't coincide, or the command needs additional packages in order to work you might want to change
echo "No tools required"
tosudo apt-get install inkscape
. This should serve as a reminder of what you should install when you're on a new system in order for the Makefile to work. And you can callmake install-tools
to install them of course. -
Replace
echo "add command here"
withinkscape -z -e $@ -w $(width) -h $(height) $^
. The parameterswidth
andheight
will go to the top of the Makefile, where they can be customized.$@
refers to the output file,test.png
in this case.$^
refers to the input file,test.svg
in this case. -
That's it. You can see the final Makefile here. Test if the command works with f5 from the Makefile. If you're happy with it, call
mis-finalize
with C-, fromdired
. The Makefile will be saved for all future calls tomake-it-so
.
- Remember to use
dired-jump
command to jump from any file (or even the compilation buffer) to the associated directory. - Remember
dired-mark-files-regexp
(bound to Shift 85) that will mark all files of specific type in directory. This is much faster than m when you want to convert a bunch of files. - Until you're sure that the command and the Makefile work properly make backups. In fact, make backups period.
As you can see, the list of Makefile recipes is quite scarce at the moment. So new Makefile contributions are most welcome.