[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Core package offering - engrave-faces.el
Re: Core package offering - engrave-faces.el
Fri, 16 Jul 2021 21:08:15 +0800
mu4e 1.4.15; emacs 28.0.50
Hi Clément, thanks for your email. I'll paste your reply that you kindly
linked and respond inline.
Clément Pit-Claudel <firstname.lastname@example.org> writes:
>> Unlike htmlize, Engrave Faces provides general functionality to
>> transform a buffer into another format with font-lock information.
>> This core functionality is currently made us of in
>> engrave-faces-latex.el, engrave-faces-ansi.el, and engrave-faces-html.el
>> to provide exporters for LaTeX, ASCII/ANSI, and HTML.
> Neat! But, I'm not sure I understand what the package actually does. Can you
> give a short example of the API and the results it produces?
Sure! So each of the engrave-faces-FORMAT.el files defines 1-2 user
facing interactive functions:
- engrave-faces-FORMAT-buffer, and maybe
These both return a new buffer which is an export of the current to
So for example if I have an elisp buffer which only contains
(funcall #'message "hi")
and call M-x engrave-faces-latex-buffer I will be taken to a new buffer
and M-x engrave-faces-latex-buffer will give
<span style="color: #4078f2;">(</span><span class="ef-c">funcall</span> <span
class="ef-hq">#'</span><span class="ef-hs">message</span> <span
class="ef-s">"hi"</span><span style="color: #4078f2;">)</span>
While the -standalone variants will generate a valid LaTeX/HTML document
with a preamble defining some of the commands/classes seen above.
Meanwhile, the most notable part of the core library itself
(engrave-faces.el) would be the macro `engrave-faces-define-backend'.
This could really do with a good docstring, but it takes
- a format name FORMAT
- the file extension for FORMAT
- a "face transforming" function
What this "face transforming" function needs to do is given a list of
faces applying to a certain content string, generate a new string that
applies that information to the content in FORMAT.
There's a rather nice helper function which I expect to be made use of
here, `engrave-faces-merge-attributes' which will take a face spec list
(as simple as "(default)" or complex as "((:weight bold :inherit
default) warning highlight (:extend t))") and a list of attributes, and
resolve all the attributes for that face spec while considering the
'saved' faces in `engrave-faces-preset-styles' -- returning a plist like:
(:foreground #FCCE7B :background #51afef :slant nil :weight bold :height nil
This can then be used to create a transformed version of the content
with face information in FORMAT like:
<span style="color: #FCCE7B; background-color: #51afef; weight:
With such a "face transforming" function `engrave-faces-define-backend'
will create the user-facing function `engrave-faces-FORMAT-buffer' which
will apply this transformation across the whole buffer.
I hope this gives you a better idea of what this package is doing :)
> If I understand correctly, the following may be relevant:
> https://github.com/cpitclaudel/esh (I mention it because it supports exporting
> overlays to HTML and LaTeX, too, and it uses a tricky algorithm to correctly
> handle overlapping fontification)
Interesting. I have not seen many of these before.
>> For comparison, htmlize.el is 1700 sloc and htmlfontify.el is 2200 sloc.
> My experience is that getting faces right is hard, so I'm not sure I'd assume
> these thousands of lines are just due to bloat ^^
Regarding the the thousands of lines being "bloat", I do not think that
this is the case, and I suspect that not (yet) handling overlays is has
made my job much easier with engrave-faces.el. However, from my usage I
have not found any clear failings with the current approach. To get a
sample of how things look see the attachments to my original email.
Should you be interested in seeing how a LaTeX export of some code
looks, I can refer you to https://tecosaur.github.io/emacs-config/config.pdf.
This is mostly elisp but has a sprinkling of other languages too.
Having looked at htmlize.el a bit I noticed that:
- It was hard to get a clear picture of what's going on easily
- The HTML generation and face-processing parts where deeply intertwined
With this package I'm aiming to create:
- A simpler, smaller (as much as possible), easier to understand core
- Separate the concerns of processing face information and creating a
representation in a certain format(s)
- Have the face processing be generalised such that creating exporters
in certain formats is a much easier task
I expect the current state of affairs has room for improvement, but I
feel it has also reached a state where it is plausibly useful :)
Please let me know if this has answered your questions, and if you have