All right, then. Well, hello everyone.
I hope you're all enjoying the EmacsConf.
My name is Musa Al-hassy, and I hope you're
excited to learn about powering up special blocks.
Let's first off find out what these special blocks are,
and see what we can go from.
Yesterday, I saw a lot of cool talks
and people were chatting about
how should you present? Should you do it this way or that way?
I thought maybe I should try a different way.
But I'm talking about special blocks
and if I show you an Emacs, then I have to export
the HTML so you can see what it looks like
or export to a PDF so you can see what it looks like.
So I ended up writing in org-reveal,
and joyously, this just works.
You can just see things here.
I was worried that I'd have to take pictures
and then insert pings, so that was a delight.
Okay. Special blocks are these things like a center small quote.
That's what a special block is,
and with a bit of Lisp, we can make
special blocks and link types.
Right. Using a single interface.
The interface is going to be similar
to one many people are familiar with.
In particular, Org Babel's src interface
as well as using global header arguments for link types.
The idea is to write it once
and generate many different kinds.
You write in Org markup and you can have HTML,
you can have PDF, and joyously, org-reveal.
That was an unexpected delight.
Here are a few that you'll just see
in this presentation.
I won't show some of these link-only ones,
but we'll see a few of these other ones
just to make the presentation look nice
So the presentation is really going to
present these blocks and the mechanism
at the same time.
No HTML was written.
Look, Ma! No HTML, just pure Org Mode,
and you get all these beautiful boxes and things.
The motivation for this is...
you're online, you run into a blog,
and you see something you like,
and you're like, man,
you know, I wish I could produce that.
But you check, and the author wrote raw HTML.
You know, #+HTML: everywhere.
That's going to obscure your real content.
It's going to be surrounded by all this
styling information. That's unfortunate.
The author decides to use an Org macro.
All right, a bit better,
but then what if you decide,
hey I want to make a PDF? Not great.
And then the worst of all,
the author doesn't give you the source,
and then you have to view page source,
and learn cascading style sheets,
and sit in a corner and cry,
and decide to do other things with your life.
We want to give you Org users numerous styles
and an extensible mechanism to add more of these
aesthetically pleasing styles,
to have really nice things
look one way in the HTML
and look almost the same way in the PDF
and other back ends.
And if by having these newer ones,
people might be encouraged to try making new ones,
especially when the interface is not so difficult,
that's the aim.
So let's have a real story to motivate this even more.
Here's three friends. I hope I don't butcher their names,
but these friends are called
Amin, Sacha, and Corwin. They're organizing a conference,
EmacsConf 2020.
So Sacha decides to write an Org file
and she would like some feedback.
Okay. Just to make it clear, there's no...
just how easy this looks,
let's look at the source for this block.
Notice it's just the word "green," then a colon,
then Amin. No div style coloring,
just green:Amin.
A very pleasant Org markup.
So that's quite nice. Put some bold around it.
Not too difficult.
Hopefully, this will be useful to other people as well.
So what kind of feedback
would Sacha expect to get?
Maybe she would expect top-level remarks
visible in the export.
When she makes an HTML, she can see right there a big block.
Right. Maybe Amin will suggest to Sacha,
please replace this part
with this other part
or replace this word
with this other word.
This is not really possible
with raw HTML or with even LaTeX.
You'd have to have multiple arguments:
the first argument, and then
the replacement argument. It's a bit clunky.
But with our setup, you just write some text,
write #+replace_with
and then write more text, and you're good to go.
Normal Org markup.
Everyone speaks different languages.
Maybe they want to use one word,
or they're arguing about
whether we talk about frames or windows,
so maybe they want to have some translations.
So there are different kinds of feedback.
Let's take an example.
Look at what they are.
For example, Sacha might write
this Org Mode right here,
and then in her HTML exports, you might see this,
and her feedback might look really nicely
from anyone who says
let's do some Lisp instead of mathematics.
Let's just do some Lisp.
Corwin says, let's not be so silly.
Let's just say 9 a.m. and move on.
Amin likes to export to PDF,
and so he writes his top-level remarks using LaTeX.
That's how. To get this square
Amin: please change whatever,
he might write like this: #+latex:.
But then Sacha only exports to HTML, for example,
so she doesn't look at the PDF,
and she may not see his top-level feedback
with those nice brackets and and bold.
She might think everything's good.
That can be a bit disastrous.
So maybe Sacha will then
make some of her own feedback.
To produce it, she might write
HTML commands, #+html: to get that.
But then Amin will make a PDF,
and this won't stick out.
So he might think everything's okay,
even though it's not.
Then Corwin actually decides,
"Hey, let me read the exported result
and there's all those feedback from two people
who haven't read anything, because maybe they were in a rush,
and didn't see the top-level feedback.
So they agree. "Hey, let's have a uniform Org interface that exports
to both HTML and PDF.
Make both of us happy."
Okay. So they decide to use Org special blocks.
Right. To set this up,
they need to read a little bit of Lisp,
hooks, advice, macros to get all of this set up,
and then they'll use Org as the main interface.
It's a lot of work, but it's worth it, right? maybe?
But then Corwin's a bit terse.
Corwin maybe doesn't want to write using blocks.
He thinks they're overkill.
Sacha wants HTML, and Amin wants PDF, and Corwin wants org-reveal.
So now they have to reformat all their code.
And then they need to use org link types
to reduce the overkill,
so they can try to avoid duplication
by factoring things out into self-contained functions.
But now, to set up our links,
we'll have to learn a new interface, org setup link.
Learn a little bit about fonts, follow links, export handlers...
It's so much. That's so much. But then,
the friends, they learn a lot.
They learn about defun.
So these words are red.
You get a little explanation.
I think it's a bit too small for anyone to read.
This is Lisp documentation for defun.
advice-add. There's some Lisp documentation.
They learn about destructuring -let.
This is from the dash library.
Here's all that glorious,
glorious documentation with examples.
Sorry. I like that.
They might make an ad-hoc mechanism
to simulate arguments for special blocks,
so something maybe called extract-arguments,
and then, of course, to make new link types,
they have to learn about
org-link-set-parameters and its numerous bits and pieces.
Let's close all these ones down.
Of course they also need to be comfortable
with loops and maps and matching and string functions.
So it's a bit of a pain.
It's probably not worth it.
Maybe I'll just rush things quickly,
or do it ad-hoc...
We have things to do.
But maybe the squad wants to have a modular and unified interface
so everyone's comfortable with defun to define a function
and they say, "It would be nice if we could just define simultaneously
both a block and the link type."
That way, we have a single interface
Org mode, for these things.
It would be nice if it was modular.
If I defined a one kind of block and you defined another,
we could compose them,
then get a nice bigger block, like LEGO.
That would be nice. Building blocks.
This is what we have come up with, called defblock.
It also has a long documentation string containing examples and things.
So that way, it can try to be useful.
Let's look at a solution to these friends' trilemma.
So here's a way to define a block.
It doesn't look that difficult, but this is how they can define a block
for their top-level feedback.
Let's look at the three main parts together.
It's not that difficult, I hope.
Just six lines, and that's including a documentation string,
newlines and things.
So in line 1, we define the block just like you define a function.
We define a block.
The block name is going to be called "feedback."
It has an author, "who."
The author has no default value.
It has a color, and the color has a default value of red.
So just as when you define functions,
you start by define or defblock,
then the name, some mandatory argument, and some optional arguments.
Then the next stage is definition. Documentation.
The people who use this,
which are future you or future me,
might want to know what this is.
So let's get to document this.
For Corwin, who might want to use tooltips...
When Corwin writes feedback in Emacs, they'll see a nice little tooltip,
and the tooltip will have
this documentation string.
That'll be nice.
And then here's the third part.
The last three lines are not so difficult.
If the backend is HTML,
please use this template string.
Otherwise, use the other string.
For each of these string markers,
please put in the color, who wrote it, and then the contents
of the special block or the link type.
So that's pretty neat. Not so difficult.
I thought that was kind of cool,
then noticed it's anaphoric.
This defblock gives you two new names.
It gives you a name called contents,
and it gives you a name called backend.
So even if you're writing a defblock
and you intend it to be used only for links...
Like these colors, for example.
These colors were defined using defblock.
I used them as links right here.
You don't need to worry
where does the text come from in the link.
If I say "red:Bob," is it Bob?
Or if I put a description, is it the description?
So it's whatever is available will
become the value of contents.
If you're really interested
and you want to do some intricate stuff,
defblock also gives you something called raw-contents,
if you really want to touch
the raw contents with all of the Org markups still there.
Let's see how everyone can communicate amongst themselves
using this new interface.
So, Sacha speculates and she... How does
she speculate for her Org HTML?
She might just write. Hey look at that, no HTML, nice.
Amin wants to have some green,
and so he just says, hey here's some color green.
There you go. It looks almost the same.
Notice that the main argument is right here.
defblock took an author,
and here's the author again.
And now the optional argument
uses the org babel source interface
You just say :, then a key, and then the argument. Quite nice.
Corwin doesn't want to use blocks. It's a bit of an overkill.
He can just write a link.
So the main argument is now the label of the link,
and the description of the link is the contents of the feedback.
So that was quite nice.
So it looks like everyone uses the same interface on the left
and can have varying outputs.
I think it looks quite nice,
and I hope you do too.
There's a few more.
Maybe, as you saw in some previous ones,
we had text side beside side,
or we folded some regions away.
We put some things in pretty boxes.
We had some spoilers at the very beginning that we hid some text.
We demoed some texts. Here's some Org and here's what it looks like,
and most importantly, they compose.
There's a a macro called thread-block.
thread-block call, and it lets you thread the contents
through a number of blocks,
treating them as if they were functions.
So, really, you can think of a block
as a string-valued function.
That's pretty neat, I think.
Thank you for listening.
I hope you've enjoyed this little
happy fun time with the Emacs and friends.
I'll happily answer questions right now.
Someone says: "Why did you put optional arguments
in a separate list
rather than using cl-style argument lists?"
So that's a very good question,
and I will answer that
by showing you a more involved definition of feedback.
Let's look at a more involved one right here.
So, for example, this one is called rremark.
Please let me know if my text is not sufficiently big.
Here is why we have two arguments.
That takes two arguments instead of one
for its argument list.
You have def block,
then you have the name,
then you have the first argument list
and the second argument list.
The first argument list
takes the text right after the begin.
The text right after the begin is the main argument.
And then the remaining key-value pairs are in the second argument list.
Now the reason we have two is because
in order to streamline the interface to account for both special blocks
and Org link types, what we do is we say,
in the first argument list, you can give a name to the first argument,
give it a default value,
and anything else you provide will become part of the link information.
For example, this link,
we decided to make its face angry red.
You might want to give other features to links.
So we're trying to streamline the interface
for both special blocks and Org link types,
and we thought this way was quite nice.
That was the main reason.
Someone asks--
if you have follow-ups, please ask--
Someone asks, "Do you intend to try to
upstream this amazing work into Org?"
Well, I'm glad you like it.
I don't know how to upstream,
but I will look into it,
and any advice or guidance would be much appreciated.
Lisp is awesome. Just as defun is a macro,
defblock is a macro, and then
source blocks are awesome.
Now maybe we can have arguments in special blocks,
and motivate and encourage more people to learn Lisp.
So another person asks,
"What is used to produce colorful
boxes around the cursor?"
I'm not quite sure if you're asking...
Are you talking about my cursor right here,
or are you talking about in the slide?
So this cursor is some application called Streambrush,
that I had to purchase.
Unfortunately, I could not find a a suitable free one.
The blocks... I can demonstrate some Emacs Lisp.
I can open up my Emacs, if people like,
and we can try some things out.
Happy to do that.
You're welcome.
Someone asks a side question about org-reveal: "How do you get
bespoke or multiple-column layouts
without using HTML?"
Excellent question. That's what we do.
That's what this project is about.
So it's not org-reveal,
it's our fancy parallel block.
So we have this thing. You say, #+begin_parallel.
You say how many columns you would like.
Do you want a bar or not?
And then you write some text,
and then you get some text, and according with the bar or not.
That's how we achieve that in our slides.
I'm not quite sure where this was.
Somewhere here, I think.
Let me try to find this for you.
I can't seem to find where the parallel blocks were. Apologies.
Let's move on to the next question, I suppose.
I'm pretty sure they're here. Ah, there they are.
So these were just instances of using
the parallel block, and it makes things parallel.
So that's quite nice.
Another person asks,
"How does this relate to pandoc,
which is used for converting between markup formats?"
So all we're doing is we're saying,
hey, please write Org because Org is just fantastic,
and we love it, and it's the dream,
and if you would like to view things
in HTML, or in org-reveal, or in PDF,
that's up to the user.
Made it too small now. So here is an example.
Here's how parallel is implemented,
just as a quick example, not too long.
About half of the implementation is documentation,
so, hopefully, that speaks for for how useful this feature is.
We decide if there's a rule or not.
We look for the column break.
Here we're looking at the backend.
If the backend is LaTeX,
please use this incantation
with multicolumns, minipages, what have you.
If the backend is something else, please do this:
div, style and other gibberish that we don't really want to look at.
Pandoc works from Org,
so it might not work directly,
since our interface... The way we set it up is: when you try to export,
we hook in and we do a bunch of pre-processing,
so this defblock is a string-valued function.
Whenever we see these #+begin_parallel when you do an export,
I tell Emacs, hold up, look for those #+begin_parallels, please.
Oh, you found them? Grab that text.
You grabbed it. Great.
Now please apply this person's function
onto that text, and splice in the result.
So when you export, we're performing
arbitrary computations on your text.
Some people might not find that comforting,
to have arbitrary computations happening.
In this article, there's a few where
we change your text upon export.
We translate it, we do other things to it.
So someone says, "If you export to LaTeX, to PDF,
does that work well with Beamer as well
to create slides with columns?"
I made a bunch of these changes
earlier this morning,
and it just says LaTeX right here.
So if you want to go to beamer,
I think the back end for me,
beamer is called, well, beamer,
so instead of a pcase, what we would do is, we would say,
if it's a 'latex or it's a 'beamer, then use this.
Otherwise, it's not a LaTeX,
it will simply default to this one,
which could be dangerous for your needs.
I think it's a bad practice to put a underscore,
but I did it really quickly
because I just wanted to show you that it works fine in org-reveal
Contributions are more than welcome.
I happily would love any assistance.
We have a Lisp reference cheat sheet here
to learn a little bit about Lisp, if you're not comfortable,
or to ask some questions.
Lots of helpful people.
So there's another question that says,
"Does typing in a block mess up with syntax highlighting?
Usually, you use a single color inside an
example block, for example.
Ah, you found my crutch.
Emacs is all encompassing,
and I'm not quite sure how fonts work.
I learned enough to get by.
Here's how links work.
They're a bit complicated.
This is a bit scary.
I don't recommend anyone read it.
Actually, let me open up an email
and you can see what I see.
So here's an Emacs.
Let's make that a bit bigger.
Let's change this slightly.
Nope, that's worse. There you go.
Here's some words. Here's red hello.
But you're worried about preserving fontification.
Let's make an emacs-lisp block.
Let's say, (+ 1 2).
Ah, where's the fun? Hello. Bye.
Okay. Where's the coloring?
If we zoom in on this #+begin_src block,
you can see down here
we have our our coloring
when we zoom in.
If we zoom out, no coloring.
Zoom in, coloring. Zoom out, aah, no coloring.
Let's take off these bad boys, and oh, look, my coloring's back.
In a previous iteration of the system, I was able to maintain coloring.
In this new iteration, I am not.
I don't know how to do it.
I haven't had the time to implement it.
I spent a lot of time writing this 48-page documentation
with some fun examples to try to help people learn.
But I would appreciate any help or guidance
on how to maintain the fontification.
I really would like to keep those colors in.
[Amin]: Musa, we have time for maybe one more question,
one or two more questions,
and then we have to move on to the next talk.
You're more than welcome to
continue taking the questions via IRC or the pad.
[Musa]: Okay. Thank you.
The final question we'll take is,
"Should packages implement
interface to one specific format,
or attempt to be inclusive
to all the potential output targets?"
I think you should just make them as you go,
and add them as you need them.
We'll make Github requests for things.
We can share recipes in this document,
and then try to add other techniques,
and then we can use these blocks as a common interface
for exporting to PDF and other things.
Since someone asked,
here what a PDF looks like.
This is the same PDF rendered.
I made no effort to make it look good,
but it surprisingly does look good.
That was nice.
That was a terrible magenta, but that is life.
Anyhow, I hope you all enjoyed this talk.
I hope you will find defblock useful to you.
It is available on MELPA.
In a rush to make it available for EmacsConf 2020,
some MELPA guidelines may not have been adhered to.
Please do not hit me.
I hope everyone enjoys the rest of the EmacsConf 2020. Thank you!