1
0

home/develop/emacs: add yasnippet snippets and make snippet dirs configurable

This commit makes two significant changes to the Emacs configuration:

1. Refactors emacs.nix to use proper NixOS module structure:
   - Converts from simple configuration to a module with options/config
   - Adds `tb.emacs.extraSnippetDirs` option to allow per-machine snippet
     directories (defaults to ~/.emacs.d/snippets/)
   - Moves yasnippet configuration from custom.el to nix-generated elisp,
     enabling dynamic snippet directory configuration via Nix

2. Adds a comprehensive collection of yasnippet snippets for multiple modes:
   - C++ mode: 50 snippets for common patterns (class, namespace, operators,
     copy/move semantics, debug helpers, documentation, threading primitives)
   - CC mode (shared C/C++): for, switch, main, include guards, etc.
   - CMake mode: if/else, foreach, function, macro, project boilerplate
   - LaTeX mode: document structure, beamer frames, figures, lists
   - Perl mode: package boilerplate, shebang
   - Python/Shell/Nix/Protobuf/Java/CSS/Dockerfile modes: horizontal rules
     and common patterns
   - Text mode: modeline snippets for locale settings

The snippets use yasnippet's inheritance system via .yas-parents files,
so c++-mode inherits from cc-mode and text-mode, reducing duplication.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-08 22:38:18 -08:00
parent 3d098013a9
commit a0b0357466
111 changed files with 951 additions and 130 deletions

View File

@@ -1,5 +1,18 @@
{ pkgs, ... }:
{ config, pkgs, lib, ... }:
let
snippetsPath = ./emacs/snippets;
extraSnippetDirs = config.tb.emacs.extraSnippetDirs;
allSnippetDirs = [ "${snippetsPath}" ] ++ extraSnippetDirs;
snippetDirsLisp = lib.concatMapStringsSep " " (d: ''"${d}"'') allSnippetDirs;
in
{
options.tb.emacs.extraSnippetDirs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = ["~/.emacs.d/snippets/"];
description = "Additional snippet directories for yasnippet";
};
config = {
programs.emacs = {
enable = true;
@@ -115,7 +128,16 @@
swift-ts-mode # Swift programming with tree-sitter
];
extraConfig = builtins.readFile ./emacs/custom.el;
extraConfig = builtins.readFile ./emacs/custom.el + ''
;; Yasnippet configuration (generated by nix)
(use-package yasnippet
:init
(setq yas-snippet-dirs '(${snippetDirsLisp}))
:config
(yas-reload-all)
(yas-global-mode 1))
'';
};
# System packages required by various emacs packages
@@ -123,4 +145,5 @@
# Search and file utilities
ripgrep # Required for rg package
];
};
}

View File

@@ -386,14 +386,6 @@ frame if FRAME is nil, and to 1 if AMT is nil."
try-expand-list
try-expand-line)))
;; Yet another snippet extension for Emacs.
(use-package yasnippet
:init
(setq yas-snippet-dirs '("~/.emacs.d/snippets/"))
:config
(yas-reload-all)
(yas-global-mode 1))
;; Clean up whitespace
(use-package ethan-wspace
:ensure t

View File

@@ -0,0 +1,2 @@
cc-mode
text-mode

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: A
# key: A
# binding: direct-keybinding
# --
ASSERT_EQ($0)

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ac
# key: ac
# --
* @param[in] alloc Memory allocator to use.

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: alloc
# key: alloc
# --
const xplat::polymorphic_allocator<> alloc;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ator
# key: ator
# --
const xplat::polymorphic_allocator<> alloc;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: be
# key: be
# --
$1.begin(), $1.end()

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# contributor: York Zhao <gtdplatform@gmail.com>
# name: cerr
# key: cerr
# --
`(progn (save-excursion) (goto-char (point-min)) (unless (re-search-forward
"^using\\s-+namespace std;" nil 'no-errer) "std::"))
`cerr << $0 << '\n';

View File

@@ -0,0 +1,13 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: class
# key: class
# binding: direct-keybinding
# --
class ${1:Class}
{
public:
$1()
: { }
private:
};

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: cmd
# key: cmd
# --
static void ${1:cmd}(base::Cmd& cmd)
{
$0
}
CMD($1, "$1");

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: constructor
# key: ct
# --
${1:Class}::$1(${2:args}) ${3: : ${4:init}}
{
$0
}

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: copy
# key: copy
# binding: direct-keybinding
# --
* Copyright (C) `(format-time-string "%Y" (current-time))` Timo Bingmann <tb@panthema.net>

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: copymove
# key: copymove
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! default copy-constructor
${1:class}(const $1 &) = default;
//! default assignment operator
$1 & operator = (const $1 &) = default;
//! move-constructor: default
$1($1 &&) = default;
//! move-assignment operator: default
$1 & operator = ($1 &&) = default;

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# contributor: York Zhao <gtdplatform@gmail.com>
# name: cout
# key: cout
# --
`(progn (save-excursion) (goto-char (point-min)) (unless (re-search-forward
"^using\\s-+namespace std;" nil 'no-errer) "std::"))
`cout << $0 << '\n';

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: cv
# key: cv
# --
std::cout << "$1 " << $1 << std::endl;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: d
# key: d
# --
qDebug() <<

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: debug
# key: debug
# binding: direct-keybinding
# --
static constexpr bool debug = true;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: debugf
# key: debugf
# binding: direct-keybinding
# --
static constexpr bool debug = false;

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: doc
# key: doc
# --
/**
* @brief $1
*/

View File

@@ -0,0 +1,12 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: dog
# key: dog
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! \\name $1
//! \\{
$0
//! \\}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: el
# key: el
# --
<< std::endl

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet -*-
# name: functor
# key: functor
# --
class ${1:Functor}
{
public:
$1($2) { }
void operator () () const {
}
private:
};

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hi
# key: hi
# --
/*`(make-string (- 78 (current-column)) ?-)`*/

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: i
# key: i
# binding: direct-keybinding
# --
`(if (char-equal ?) (preceding-char)) "," "")` m_${1:var}($1)

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: lock
# key: lock
# binding: direct-keybinding
# --
std::unique_lock<std::mutex> lock$1(mutex$1_);

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: mutexlock
# key: mutexlock
# binding: direct-keybinding
# --
static std::mutex mutex$1;
std::unique_lock<std::mutex> lock$1(mutex$1);

View File

@@ -0,0 +1,17 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: mysource
# key: mysource
# binding: direct-keybinding
# --
/*******************************************************************************
* $1/<file>
*
* $2
******************************************************************************/
namespace $1 {
} // namespace $1
/******************************************************************************/

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: nl
# key: nl
# --
// NOLINTNEXTLINE($1)

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: noncopy
# key: noncopy
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! non-copyable: delete copy-constructor
${1:class}(const $1 &) = delete;
//! non-copyable: delete assignment operator
$1 & operator = (const $1 &) = delete;

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: noncopymove
# key: noncopymove
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! non-copyable: delete copy-constructor
${1:class}(const $1 &) = delete;
//! non-copyable: delete assignment operator
$1 & operator = (const $1 &) = delete;
//! move-constructor: default
$1($1 &&) noexcept = default;
//! move-assignment operator: default
$1 & operator = ($1 &&) noexcept = default;

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: namespace
# key: ns
# binding: direct-keybinding
# --
namespace $1 {
$0
} // namespace $1

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: al
# key: al
# --
allocator_type alloc

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator>>
# key: op>>
# --
istream& operator>>(istream& s, const ${1:type}& ${2:c})
{
$0
}

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator<
# key: op<
# --
friend bool operator < (const ${1:type}& a, const $1& b)
{
return $0;
}

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator<<
# key: op<<
# --
friend std::ostream& operator << (std::ostream& os, const ${1:type}& ${2:x})
{
return os << $0;
}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: os
# key: os
# --
os << " $1=" << x.$1;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet -*-
# name: oso
# key: oso
# --
if (${2:t}.${1:var})
os << " $1=" << $2.$1;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet -*-
# name: oss
# key: oss
# --
std::ostringstream oss;
oss << $0

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: pe
# key: pe
# --
v.$1 += p.$1;

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: perl
# key: perl
# --
/*[[[perl
$0
]]]*/
//[[[end]]]

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: q
# key: q
# --
db::Query q = cmd.db_.query << "SELECT $1"
<< into(...);
while (q.next())
{
}

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: stdrand
# key: stdrand
# binding: direct-keybinding
# --
std::default_random_engine ${1:name}(std::random_device { } ())

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: stdsleep
# key: stdsleep
# binding: direct-keybinding
# --
std::this_thread::sleep_for(std::chrono::seconds($1));

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: sv
# key: sv
# --
std::string_view

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: svlit
# key: svlit
# --
using namespace std::string_view_literals;

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: timestamp
# key: timestamp
# --
//! Time is measured using chrono::steady_clock
static double timestamp() {
return std::chrono::duration_cast<std::chrono::duration<double> >(
std::chrono::steady_clock::now().time_since_epoch()).count();
}

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: try
# key: try
# a bit too intrusive now still, not always I want to do this
# --
try {
$0
} catch (${1:std::exception& e}) {
}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: using_ator
# key: using
# --
using allocator_type = xplat::polymorphic_allocator<>;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ls
# key: ls
# --
common::allocate_local_shared

View File

@@ -0,0 +1,2 @@
cc-mode
text-mode

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hr
# key: hr
# --
################################################################################

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: c
# key: c
# binding: direct-keybinding
# --
/* $1 */

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: cc
# key: cc
# binding: direct-keybinding
# --
/** $1
*/

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: comment-spacerline
# key: ***
# binding: direct-keybinding
# --
/******************************************************************************/

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: for
# key: for
# binding: direct-keybinding
# --
for ($1) {
$0
}

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: fori
# key: fori
# --
for (${1:std::size_t} ${2:i} = ${3:0}; $2 ${4:!= size()}; ++$2) {
$0
}

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: guard
# key: guard
# --
#ifndef ${1:NAME}_HEADER
#define $1_HEADER
$0
#endif // $1_HEADER

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: in
# key: in
# binding: direct-keybinding
# --
#include <$0>

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: inc
# key: inc
# binding: direct-keybinding
# --
#include "$0"

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: main
# key: main
# --
int main(${1:int argc, char *argv[]})
{
$0
return 0;
}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: packed
# key: packed
# --
__attribute__((__packed__))$0

View File

@@ -0,0 +1,11 @@
# -*- mode: snippet -*-
# name: switch
# key: case
# --
switch (${1:ch}) {
case ${2:const}:
${3:a = b};
break;
${4:default:
${5:action}}
}

View File

@@ -0,0 +1 @@
text-mode

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: cmake_minimum_required
# key: min
# --
cmake_minimum_required(VERSION ${1:2.6})

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: foreach
# key: for
# --
foreach(${1:item} \${${2:array}})
$0
endforeach()

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: function
# key: fun
# --
function (${1:name})
$0
endfunction()

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: hr
# key: hr
# binding: direct-keybinding
# --
`(make-string (- 80 (current-column)) ?#)`

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: if
# key: if
# --
if(${1:cond})
$0
endif()

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: ifelse
# key: if
# --
if(${1:cond})
$2
else(${3:cond})
$0
endif()

View File

@@ -0,0 +1,5 @@
# type: command
# key: inc
# name: include
# --
include ($0)

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: macro
# key: macro
# --
macro(${1:name}${2: args})
endmacro()

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: message
# key: msg
# --
message(${1:STATUS }"$0")

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: option
# key: opt
# --
option (${1:OPT} "${2:docstring}" ${3:value})

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: project
# key: proj
# --
project ($0)

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: set
# key: set
# --
set(${1:var} ${2:value})

View File

@@ -0,0 +1 @@
text-mode

View File

@@ -0,0 +1,21 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: package
# key: package
# binding: direct-keybinding
# --
#!/usr/bin/perl -w
package ${1:package};
use strict;
use warnings;
use diagnostics;
use utf8;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw();
our @EXPORT_OK = qw();
1;

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: perl
# key: perl
# --
#!/usr/bin/env perl
use strict;
use warnings;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: doc
# key: doc
# binding: direct-keybinding
# --
/* $1 */

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hr
# key: hr
# --
################################################################################

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hr
# key: hr
# --
################################################################################

View File

@@ -0,0 +1,2 @@
cc-mode
text-mode

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hr
# key: hr
# --
/*`(make-string (- 78 (current-column)) ?*)`*/

View File

@@ -0,0 +1 @@
text-mode

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: begin
# key: begin
# binding: direct-keybinding
# --
\begin{${1:environment}}
$0
\end{$1}

View File

@@ -0,0 +1,12 @@
# -*- mode: snippet -*-
# name: cols
# key: cols
# --
\begin{columns}
\begin{column}{${1:.5}\linewidth}
column 1
\end{column}
\begin{column}{${2:.5}\linewidth}
column 2
\end{column}
\end{columns}

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: enumerate
# key: enumerate
# binding: direct-keybinding
# --
\begin{enumerate}
\item $0
\end{enumerate}

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: figure
# key: figure
# --
\begin{figure}[ht]
\centering
\includegraphics[${1:options}]{figures/${2:path.pdf}}
\caption{\label{fig:${3:label}} $0}
\end{figure}

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: frame
# key: frame
# binding: direct-keybinding
# --
% ------------------------------------------------------------------------------
\begin{frame}{${1:title}}
\end{frame}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ho
# key: ho
# --
% ---[ $1 ]-------------------------------------------------

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: hr
# key: hr
# binding: direct-keybinding
# --
% `(make-string (- 80 (current-column)) ?-)`

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: hrr
# key: hrr
# binding: direct-keybinding
# --
% ==============================================================================

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: hrx
# key: hrx
# --
% %
%% %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
% %

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hx
# key: hx
# --
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: itemize
# key: itemize
# binding: direct-keybinding
# --
\begin{itemize}
\item $0
\end{itemize}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: emacs modeline de_DE dictionary
# key: modeline
# --
% -*- mode: latex; mode: flyspell; ispell-local-dictionary: "de_DE"; coding: utf-8 -*-

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: noex
# key: noex
# --
\tikzset{external/export=false}

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: noexternal
# key: noexternal
# binding: direct-keybinding
# --
\tikzset{external/export=false}

View File

@@ -0,0 +1,73 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: template
# key: template
# binding: direct-keybinding
# --
% -*- mode: latex; mode: flyspell; ispell-local-dictionary: "en_US"; coding: utf-8 -*-
\documentclass[a4paper,12pt,twoside]{scrartcl}
\setlength\overfullrule{14pt} % this enables big black bars on overlong lines.
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[english]{babel}
\title{${1:title}}
\author{${2:Timo Bingmann}}
% small margin
\usepackage[tmargin=20mm,bmargin=20mm,lmargin=20mm,rmargin=20mm]{geometry}
% set default paragraph skip and indention
\setlength\parskip{\smallskipamount}
\setlength\parindent{0pt}
% math support
\usepackage{amsmath,amssymb,array,mathtools}
% smaller enumerations
\usepackage{enumitem}
\setlist[enumerate]{topsep=\smallskipamount,parsep=0pt}
\setlist[itemize]{topsep=\smallskipamount,parsep=0pt}
\setlist[enumerate,1]{topsep=\smallskipamount,parsep=0pt,label=(\roman*)}
% for graphics
\usepackage{graphicx}
% for nice graphics
\usepackage{tikz}
\usetikzlibrary{calc}
% Hyperref
\usepackage{xcolor,hyperref}
\hypersetup{
colorlinks=true,
pdfborder={0 0 0},
bookmarksopen=true,
bookmarksopenlevel=1,
bookmarksnumbered=true,
linkcolor=blue!60!black,
%linkcolor=black,
urlcolor=blue!60!black,
filecolor=green!60!black,
citecolor=blue!60!black,
pdfpagemode=UseNone,
unicode=true,
setpagesize=false,
bookmarksdepth=subsection,
pdftitle={$1},
pdfauthor={$2},
pdfsubject={},
}
\begin{document}
\maketitle
$0
\end{document}

Some files were not shown because too many files have changed in this diff Show More