Introducing codetabs.el
Warning!
Some features might not yet be added to the codetabs.el repo! This blog is experimenting with what could be done. If you are interested in how it works check _org/lisp/codetabs.el and js/codetabs.js
Description
Recently, I've been trying to change the way I write blog posts. Up until now I was using Jekyll+Markdown to write and publish. However, I decided I didn't want Markdown anymore and instead use Org Mode (I use Emacs BTW!). The reason is very simple: CUSTOMIZATION.
If you read some of my previous blog post, I have code snippets that are grouped under tabs. This is because I often want to write multi-language code or simply have a beautiful code snippet and the name of a file as the tab name. Previous articles were relying on jdvp-codetabs-commonmark but I was missing some features and I already bothered the maintainer enough that I didn't feel like asking anymore. These features were:
- Custom code highlighting (change color theme)
- Code emphasis (emphasize errors and warnings in code)
- Small animations (not important, but looks good)
So, I decided to implement this my way. During this process, I came up with codetabs.el and this article will demonstrate its features.
Behavior
Naming
With codetabs
we can either get tabs named after the org babel language like so:
func main() { }
int main() { return 0; }
or we can rename them with a simple #+name
:
func main() { }
int main() { return 0; }
For single src-blocks
, it is similar:
ls
Skipping
We can skip some blocks. For example, the BQN block is consecutive but uses the attr :skip
:
std::cout << "hello" << std::endl;
def test(): print(1)
<⟜'a'⊸/ "Big Questions Notation"
std::cout << "world" << std::endl;
def test(): print(2)
And it also works for single src-blocks
:
ls
Copying
We can also enable copy of code with the :copy
attribute (check the top right corner!):
func main() { }
State
The language preference is reflected across the whole article. For example, if you click on C++ because you prefer reading in this language, all the C++ codes will be selected. Try it:
func main() { }
int main() { return 0; }
SOME TEXT HERE….
func main() { }
int main() { return 0; }
Styling
CSS
With org-html-htmlize-output-type
set to css
you can customize your CSS to make any token the color you want (see the function name difference in light and dark theme):
func main() { }
This is just done like so:
.org-src-container pre .org-function-name { /* font-lock-function-name-face */ color: #0000ff; } .org-src-container pre.dark-mode .org-function-name { /* font-lock-function-name-face */ color: #0ff; }
Emphasis
By using the :emphasize
attr we can also define the styling for a given portion of code:
func main() { fmt.Printf("%d\n", ⟜"I pass a string"⊸) fmt.Printf(⊢"%d\n"⊣) }
Misc
I customized the code snippets theme based on: tokyo-night-vscode-theme
I added the following animations:
- Switching to/from dark mode
- Tab transitions